diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/ck-manager.c | 204 | ||||
| -rw-r--r-- | src/ck-seat.c | 86 | ||||
| -rw-r--r-- | src/ck-seat.h | 4 | ||||
| -rw-r--r-- | src/ck-session.c | 38 | ||||
| -rw-r--r-- | src/ck-session.h | 3 | 
6 files changed, 330 insertions, 7 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index ec4e04f..d72ec35 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,6 +17,7 @@ INCLUDES =							\  	-DLIBEXECDIR=\""$(libexecdir)"\"			\  	-DDATADIR=\""$(datadir)"\"				\  	-DSYSCONFDIR=\""$(sysconfdir)"\" 			\ +	-DLOCALSTATEDIR=\""$(localstatedir)"\" 			\  	-DCONSOLE_KIT_PID_FILE=\""$(CONSOLE_KIT_PID_FILE)"\"	\  	$(WARN_CFLAGS)						\  	$(DEBUG_CFLAGS)						\ @@ -169,3 +170,4 @@ MAINTAINERCLEANFILES =			\  install-data-local:  	-mkdir -p $(DESTDIR)$(sysconfdir)/ConsoleKit/run-session.d  	-mkdir -p $(DESTDIR)$(libdir)/ConsoleKit/run-session.d +	-mkdir -p $(DESTDIR)$(localstatedir)/run/ConsoleKit diff --git a/src/ck-manager.c b/src/ck-manager.c index c957896..74d488c 100644 --- a/src/ck-manager.c +++ b/src/ck-manager.c @@ -28,9 +28,11 @@  #include <signal.h>  #include <sys/stat.h>  #include <sys/types.h> +#include <errno.h>  #include <glib.h>  #include <glib/gi18n.h> +#include <glib/gstdio.h>  #include <glib-object.h>  #define DBUS_API_SUBJECT_TO_CHANGE  #include <dbus/dbus-glib.h> @@ -105,6 +107,115 @@ static gpointer manager_object = NULL;  G_DEFINE_TYPE (CkManager, ck_manager, G_TYPE_OBJECT)  static void +dump_state_seat_iter (char     *id, +                      CkSeat   *seat, +                      GKeyFile *key_file) +{ +        ck_seat_dump (seat, key_file); +} + +static void +dump_state_session_iter (char      *id, +                         CkSession *session, +                         GKeyFile  *key_file) +{ +        ck_session_dump (session, key_file); +} + +static gboolean +do_dump (CkManager *manager, +         int        fd) +{ +        char     *str; +        gsize     str_len; +        GKeyFile *key_file; +        GError   *error; +        gboolean  ret; + +        str = NULL; +        error = NULL; +        ret = FALSE; + +        key_file = g_key_file_new (); + +        g_hash_table_foreach (manager->priv->seats, (GHFunc) dump_state_seat_iter, key_file); +        g_hash_table_foreach (manager->priv->sessions, (GHFunc) dump_state_session_iter, key_file); + +        str = g_key_file_to_data (key_file, &str_len, &error); +        g_key_file_free (key_file); +        if (str != NULL) { +                ssize_t written; + +                written = 0; +                while (written < str_len) { +                        ssize_t ret; +                        ret = write (fd, str + written, str_len - written); +                        if (ret < 0) { +                                if (errno == EAGAIN || errno == EINTR) { +                                        continue; +                                } else { +                                        g_warning ("Error writing state file: %s", strerror (errno)); +                                        goto out; +                                } +                        } +                        written += ret; +                } +        } else { +                g_warning ("Couldn't construct state file: %s", error->message); +                g_error_free (error); +        } + +        ret = TRUE; + +out: +        g_free (str); +        return ret; +} + +static void +ck_manager_dump (CkManager *manager) +{ +        const char *filename = LOCALSTATEDIR "/run/ConsoleKit/database"; +        const char *filename_tmp = LOCALSTATEDIR "/run/ConsoleKit/database~"; +        if (manager != NULL) { +                int fd; + +                fd = g_open (filename_tmp, O_CREAT | O_WRONLY, 0600); +                if (fd == -1) { +                        g_warning ("Cannot create file %s: %s", filename_tmp, g_strerror (errno)); +                        goto error; +                } + +                if (! do_dump (manager, fd)) { +                        g_warning ("Cannot write to file %s", filename_tmp); +                        close (fd); +                        goto error; +                } +        again: +                if (close (fd) != 0) { +                        if (errno == EINTR) +                                goto again; +                        else { +                                g_warning ("Cannot close fd for %s: %s", filename_tmp, g_strerror (errno)); +                                goto error; +                        } +                } + +                if (g_rename (filename_tmp, filename) != 0) { +                        g_warning ("Cannot rename %s to %s: %s", filename_tmp, filename, g_strerror (errno)); +                        goto error; +                } +        } + +        return; +error: +        /* For security reasons; unlink the existing file since it contains outdated information */ +        if (g_unlink (filename) != 0) { +                g_warning ("Cannot unlink %s: %s", filename, g_strerror (errno)); +        } +} + +static void  remove_pending_job (CkJob *job)  {          if (job != NULL) { @@ -277,6 +388,68 @@ generate_seat_id (CkManager *manager)          return id;  } +static void +on_seat_active_session_changed (CkSeat     *seat, +                                const char *ssid, +                                CkManager  *manager) +{ +        ck_manager_dump (manager); +} + +static void +on_seat_session_added (CkSeat     *seat, +                       const char *ssid, +                       CkManager  *manager) +{ +        ck_manager_dump (manager); +} + +static void +on_seat_session_removed (CkSeat     *seat, +                         const char *ssid, +                         CkManager  *manager) +{ +        ck_manager_dump (manager); +} + +static void +on_seat_device_added (CkSeat      *seat, +                      GValueArray *device, +                      CkManager   *manager) +{ +        ck_manager_dump (manager); +} + +static void +on_seat_device_removed (CkSeat      *seat, +                        GValueArray *device, +                        CkManager   *manager) +{ +        ck_manager_dump (manager); +} + +static void +connect_seat_signals (CkManager *manager, +                      CkSeat    *seat) +{ +        g_signal_connect (seat, "active-session-changed", G_CALLBACK (on_seat_active_session_changed), manager); +        g_signal_connect (seat, "session-added", G_CALLBACK (on_seat_session_added), manager); +        g_signal_connect (seat, "session-removed", G_CALLBACK (on_seat_session_removed), manager); +        g_signal_connect (seat, "device-added", G_CALLBACK (on_seat_device_added), manager); +        g_signal_connect (seat, "device-removed", G_CALLBACK (on_seat_device_removed), manager); +} + +static void +disconnect_seat_signals (CkManager *manager, +                         CkSeat    *seat) +{ +        g_signal_handlers_disconnect_by_func (seat, on_seat_active_session_changed, manager); +        g_signal_handlers_disconnect_by_func (seat, on_seat_session_added, manager); +        g_signal_handlers_disconnect_by_func (seat, on_seat_session_removed, manager); +        g_signal_handlers_disconnect_by_func (seat, on_seat_device_added, manager); +        g_signal_handlers_disconnect_by_func (seat, on_seat_device_removed, manager); +} +  static CkSeat *  add_new_seat (CkManager *manager,                CkSeatKind kind) @@ -293,10 +466,14 @@ add_new_seat (CkManager *manager,                  goto out;          } +        connect_seat_signals (manager, seat); +          g_hash_table_insert (manager->priv->seats, sid, seat);          g_debug ("Added seat: %s kind:%d", sid, kind); +        ck_manager_dump (manager); +          g_signal_emit (manager, signals [SEAT_ADDED], 0, sid);   out: @@ -329,10 +506,14 @@ remove_seat (CkManager *manager,           * unref until the signal is emitted */          g_hash_table_steal (manager->priv->seats, sid); +        disconnect_seat_signals (manager, orig_seat); +          if (sid != NULL) {                  g_hash_table_remove (manager->priv->seats, sid);          } +        ck_manager_dump (manager); +          g_debug ("Emitting seat-removed: %s", sid);          g_signal_emit (manager, signals [SEAT_REMOVED], 0, sid); @@ -1204,6 +1385,11 @@ remove_session_for_cookie (CkManager  *manager,          LeaderInfo *leader_info;          char       *sid;          gboolean    res; +        gboolean    ret; + +        ret = FALSE; +        orig_ssid = NULL; +        orig_session = NULL;          g_debug ("Removing session for cookie: %s", cookie); @@ -1214,7 +1400,7 @@ remove_session_for_cookie (CkManager  *manager,                               CK_MANAGER_ERROR,                               CK_MANAGER_ERROR_GENERAL,                               "Unable to find session for cookie"); -                return FALSE; +                goto out;          }          /* Need to get the original key/value */ @@ -1227,7 +1413,7 @@ remove_session_for_cookie (CkManager  *manager,                               CK_MANAGER_ERROR,                               CK_MANAGER_ERROR_GENERAL,                               "Unable to find session for cookie"); -                return FALSE; +                goto out;          }          /* Remove the session from the list but don't call @@ -1255,14 +1441,18 @@ remove_session_for_cookie (CkManager  *manager,          }          g_free (sid); +        ck_manager_dump (manager); + +        manager_update_system_idle_hint (manager); + +        ret = TRUE; + out:          if (orig_session != NULL) {                  g_object_unref (orig_session);          }          g_free (orig_ssid); -        manager_update_system_idle_hint (manager); - -        return TRUE; +        return ret;  }  static gboolean @@ -1595,10 +1785,14 @@ add_seat_for_file (CkManager  *manager,                  return;          } +        connect_seat_signals (manager, seat); +          g_hash_table_insert (manager->priv->seats, sid, seat);          g_debug ("Added seat: %s", sid); +        ck_manager_dump (manager); +          g_signal_emit (manager, signals [SEAT_ADDED], 0, sid);  } diff --git a/src/ck-seat.c b/src/ck-seat.c index 66bf728..526640e 100644 --- a/src/ck-seat.c +++ b/src/ck-seat.c @@ -656,7 +656,6 @@ ck_seat_add_device (CkSeat         *seat,          g_ptr_array_add (seat->priv->devices, g_boxed_copy (CK_TYPE_DEVICE, device));          g_debug ("Emitting device added signal"); -          g_signal_emit (seat, signals [DEVICE_ADDED], 0, device);          return TRUE; @@ -672,7 +671,6 @@ ck_seat_remove_device (CkSeat         *seat,          /* FIXME: check if already present */          if (0) {                  g_debug ("Emitting device removed signal"); -                  g_signal_emit (seat, signals [DEVICE_REMOVED], 0, device);          } @@ -1122,3 +1120,87 @@ ck_seat_new_from_file (const char *sid,          return seat;  } + +static void +dump_seat_session_iter (char      *id, +                        CkSession *session, +                        GString   *str) +{ +        char   *session_id; +        GError *error; + +        error = NULL; +        if (! ck_session_get_id (session, &session_id, &error)) { +                g_warning ("Cannot get session id from seat: %s", error->message); +                g_error_free (error); +        } else { +                if (str->len > 0) { +                        g_string_append_c (str, ' '); +                } +                g_string_append (str, session_id); +                g_free (session_id); +        } +} + +void +ck_seat_dump (CkSeat   *seat, +              GKeyFile *key_file) +{ +        char    *group_name; +        GString *str; +        char    *s; +        int      n; + +        group_name = g_strdup_printf ("Seat %s", seat->priv->id); + +        g_key_file_set_integer (key_file, group_name, "kind", seat->priv->kind); + +        str = g_string_new (NULL); +        g_hash_table_foreach (seat->priv->sessions, (GHFunc) dump_seat_session_iter, str); +        s = g_string_free (str, FALSE); +        g_key_file_set_string (key_file, group_name, "sessions", s); +        g_free (s); + +        str = g_string_new (NULL); +        if (seat->priv->devices != NULL) { +                for (n = 0; n < seat->priv->devices->len; n++) { +                        int          m; +                        GValueArray *va; + +                        va = seat->priv->devices->pdata[n]; + +                        if (str->len > 0) +                                g_string_append_c (str, ' '); +                        for (m = 0; m < va->n_values; m++) { +                                if (m > 0) +                                        g_string_append_c (str, ':'); +                                g_string_append (str, g_value_get_string ((const GValue *) &((va->values)[m]))); +                        } + +                        g_debug ("foo %d", va->n_values); +                } +        } +        s = g_string_free (str, FALSE); +        g_key_file_set_string (key_file, group_name, "devices", s); +        g_free (s); + + +        if (seat->priv->active_session != NULL) { +                char   *session_id; +                GError *error; + +                error = NULL; +                if (! ck_session_get_id (seat->priv->active_session, &session_id, &error)) { +                        g_warning ("Cannot get session id for active session on seat %s: %s", +                                   seat->priv->id, +                                   error->message); +                        g_error_free (error); +                } else { +                        g_key_file_set_string (key_file, group_name, "active_session", session_id); +                        g_free (session_id); +                } +        } + +        g_free (group_name); +} + diff --git a/src/ck-seat.h b/src/ck-seat.h index 63ab3d5..5977781 100644 --- a/src/ck-seat.h +++ b/src/ck-seat.h @@ -90,6 +90,10 @@ CkSeat            * ck_seat_new_from_file       (const char            *sid,  CkSeat            * ck_seat_new_with_devices    (const char            *sid,                                                   CkSeatKind             kind,                                                   GPtrArray             *devices); + +void                ck_seat_dump                (CkSeat                *seat, +                                                 GKeyFile              *key_file); +  gboolean            ck_seat_get_kind            (CkSeat                *seat,                                                   CkSeatKind            *kind,                                                   GError               **error); diff --git a/src/ck-session.c b/src/ck-session.c index 6f16720..a700786 100644 --- a/src/ck-session.c +++ b/src/ck-session.c @@ -1245,3 +1245,41 @@ ck_session_run_programs (CkSession  *session,                  g_free (extra_env[n]);          }  } + +void +ck_session_dump (CkSession *session, +                 GKeyFile  *key_file) +{ +        char *s; +        char *group_name; + +        group_name = g_strdup_printf ("Session %s", session->priv->id); +        g_key_file_set_integer (key_file, group_name, "uid", session->priv->uid); +        g_key_file_set_string (key_file, group_name, "seat", session->priv->seat_id); +        g_key_file_set_string (key_file, group_name, "cookie", session->priv->cookie); +        if (session->priv->session_type != NULL) { +                g_key_file_set_string (key_file, group_name, "type", session->priv->session_type); +        } +        if (session->priv->display_device != NULL && strlen (session->priv->display_device) > 0) { +                g_key_file_set_string (key_file, group_name, "display_device", session->priv->display_device); +        } +        if (session->priv->x11_display_device != NULL && strlen (session->priv->x11_display_device) > 0) { +                g_key_file_set_string (key_file, group_name, "x11_display_device", session->priv->x11_display_device); +        } +        if (session->priv->x11_display != NULL && strlen (session->priv->x11_display) > 0) { +                g_key_file_set_string (key_file, group_name, "x11_display", session->priv->x11_display); +        } +        if (session->priv->remote_host_name != NULL && strlen (session->priv->remote_host_name) > 0) { +                g_key_file_set_string (key_file, group_name, "remote_host_name", session->priv->remote_host_name); +        } +        g_key_file_set_string (key_file, group_name, "remote_host_name", session->priv->remote_host_name); +        g_key_file_set_boolean (key_file, group_name, "is_active", session->priv->active); +        g_key_file_set_boolean (key_file, group_name, "is_local", session->priv->is_local); + +        s = g_time_val_to_iso8601 (&(session->priv->creation_time)); +        g_key_file_set_string (key_file, group_name, "creation_time", s); +        g_free (s); + +        g_free (group_name); +} + diff --git a/src/ck-session.h b/src/ck-session.h index fea3a71..8c5c00e 100644 --- a/src/ck-session.h +++ b/src/ck-session.h @@ -74,6 +74,9 @@ CkSession         * ck_session_new_with_parameters    (const char            *ss                                                         const char            *cookie,                                                         const GPtrArray       *parameters); +void                ck_session_dump                   (CkSession             *session, +                                                       GKeyFile              *key_file); +  gboolean            ck_session_set_active             (CkSession             *session,                                                         gboolean               active,                                                         GError               **error);  | 
