10 #include <glib-object.h>
12 #include <glib-unix.h>
13 #include <glib/gstdio.h>
17 static gchar *session_id;
19 static GMainLoop *loop;
21 static GString *open_fds;
23 static GKeyFile *config;
25 static xcb_connection_t *connection;
28 sigint_cb (gpointer user_data)
30 status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGINT);
31 g_main_loop_quit (loop);
36 sigterm_cb (gpointer user_data)
38 status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGTERM);
39 g_main_loop_quit (loop);
44 request_cb (const gchar *request)
50 g_main_loop_quit (loop);
54 r = g_strdup_printf ("%s LOGOUT", session_id);
55 if (strcmp (request, r) == 0)
59 r = g_strdup_printf ("%s CRASH", session_id);
60 if (strcmp (request, r) == 0)
61 kill (getpid (), SIGSEGV);
64 r = g_strdup_printf ("%s LOCK-SEAT", session_id);
65 if (strcmp (request, r) == 0)
67 status_notify ("%s LOCK-SEAT", session_id);
68 g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
69 "org.freedesktop.DisplayManager",
70 getenv ("XDG_SEAT_PATH"),
71 "org.freedesktop.DisplayManager.Seat",
74 G_VARIANT_TYPE ("()"),
75 G_DBUS_CALL_FLAGS_NONE,
82 r = g_strdup_printf ("%s LOCK-SESSION", session_id);
83 if (strcmp (request, r) == 0)
85 status_notify ("%s LOCK-SESSION", session_id);
86 g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
87 "org.freedesktop.DisplayManager",
88 getenv ("XDG_SESSION_PATH"),
89 "org.freedesktop.DisplayManager.Session",
92 G_VARIANT_TYPE ("()"),
93 G_DBUS_CALL_FLAGS_NONE,
100 r = g_strdup_printf ("%s LIST-GROUPS", session_id);
101 if (strcmp (request, r) == 0)
107 n_groups = getgroups (0, NULL);
110 g_printerr ("Failed to get groups: %s", strerror (errno));
113 groups = malloc (sizeof (gid_t) * n_groups);
114 n_groups = getgroups (n_groups, groups);
115 group_list = g_string_new ("");
116 for (i = 0; i < n_groups; i++)
121 g_string_append (group_list, ",");
122 group = getgrgid (groups[i]);
124 g_string_append (group_list, group->gr_name);
126 g_string_append_printf (group_list, "%d", groups[i]);
128 status_notify ("%s LIST-GROUPS GROUPS=%s", session_id, group_list->str);
129 g_string_free (group_list, TRUE);
133 r = g_strdup_printf ("%s READ-ENV NAME=", session_id);
134 if (g_str_has_prefix (request, r))
136 const gchar *name = request + strlen (r);
137 const gchar *value = g_getenv (name);
138 status_notify ("%s READ-ENV NAME=%s VALUE=%s", session_id, name, value ? value : "");
142 r = g_strdup_printf ("%s WRITE-STDOUT TEXT=", session_id);
143 if (g_str_has_prefix (request, r))
144 g_print ("%s", request + strlen (r));
147 r = g_strdup_printf ("%s WRITE-STDERR TEXT=", session_id);
148 if (g_str_has_prefix (request, r))
149 g_printerr ("%s", request + strlen (r));
152 r = g_strdup_printf ("%s READ FILE=", session_id);
153 if (g_str_has_prefix (request, r))
155 const gchar *name = request + strlen (r);
156 gchar *contents = NULL;
157 GError *error = NULL;
159 if (g_file_get_contents (name, &contents, NULL, &error))
160 status_notify ("%s READ FILE=%s TEXT=%s", session_id, name, contents);
162 status_notify ("%s READ FILE=%s ERROR=%s", session_id, name, error->message);
164 g_clear_error (&error);
168 r = g_strdup_printf ("%s LIST-UNKNOWN-FILE-DESCRIPTORS", session_id);
169 if (strcmp (request, r) == 0)
170 status_notify ("%s LIST-UNKNOWN-FILE-DESCRIPTORS FDS=%s", session_id, open_fds->str);
173 r = g_strdup_printf ("%s CHECK-X-AUTHORITY", session_id);
174 if (strcmp (request, r) == 0)
178 GString *mode_string;
180 xauthority = g_strdup (g_getenv ("XAUTHORITY"));
182 xauthority = g_build_filename (g_get_home_dir (), ".Xauthority", NULL);
184 g_stat (xauthority, &file_info);
187 mode_string = g_string_new ("");
188 g_string_append_c (mode_string, file_info.st_mode & S_IRUSR ? 'r' : '-');
189 g_string_append_c (mode_string, file_info.st_mode & S_IWUSR ? 'w' : '-');
190 g_string_append_c (mode_string, file_info.st_mode & S_IXUSR ? 'x' : '-');
191 g_string_append_c (mode_string, file_info.st_mode & S_IRGRP ? 'r' : '-');
192 g_string_append_c (mode_string, file_info.st_mode & S_IWGRP ? 'w' : '-');
193 g_string_append_c (mode_string, file_info.st_mode & S_IXGRP ? 'x' : '-');
194 g_string_append_c (mode_string, file_info.st_mode & S_IROTH ? 'r' : '-');
195 g_string_append_c (mode_string, file_info.st_mode & S_IWOTH ? 'w' : '-');
196 g_string_append_c (mode_string, file_info.st_mode & S_IXOTH ? 'x' : '-');
197 status_notify ("%s CHECK-X-AUTHORITY MODE=%s", session_id, mode_string->str);
198 g_string_free (mode_string, TRUE);
202 r = g_strdup_printf ("%s WRITE-SHARED-DATA DATA=", session_id);
203 if (g_str_has_prefix (request, r))
205 const gchar *data = request + strlen (r);
208 dir = getenv ("XDG_GREETER_DATA_DIR");
214 path = g_build_filename (dir, "data", NULL);
215 if (!(f = fopen (path, "w")) || fprintf (f, "%s", data) < 0)
216 status_notify ("%s WRITE-SHARED-DATA ERROR=%s", session_id, strerror (errno));
218 status_notify ("%s WRITE-SHARED-DATA RESULT=TRUE", session_id);
225 status_notify ("%s WRITE-SHARED-DATA ERROR=NO_XDG_GREETER_DATA_DIR", session_id);
229 r = g_strdup_printf ("%s READ-SHARED-DATA", session_id);
230 if (strcmp (request, r) == 0)
234 dir = getenv ("XDG_GREETER_DATA_DIR");
238 gchar *contents = NULL;
239 GError *error = NULL;
241 path = g_build_filename (dir, "data", NULL);
242 if (g_file_get_contents (path, &contents, NULL, &error))
243 status_notify ("%s READ-SHARED-DATA DATA=%s", session_id, contents);
245 status_notify ("%s WRITE-SHARED-DATA ERROR=%s", session_id, error->message);
248 g_clear_error (&error);
251 status_notify ("%s WRITE-SHARED-DATA ERROR=NO_XDG_GREETER_DATA_DIR", session_id);
257 main (int argc, char **argv)
259 gchar *display, *xdg_seat, *xdg_vtnr, *xdg_current_desktop, *xdg_greeter_data_dir, *xdg_session_cookie, *xdg_session_class, *desktop_session, *mir_socket, *mir_vt, *mir_id;
260 GString *status_text;
263 display = getenv ("DISPLAY");
264 xdg_seat = getenv ("XDG_SEAT");
265 xdg_vtnr = getenv ("XDG_VTNR");
266 xdg_current_desktop = getenv ("XDG_CURRENT_DESKTOP");
267 xdg_greeter_data_dir = getenv ("XDG_GREETER_DATA_DIR");
268 xdg_session_cookie = getenv ("XDG_SESSION_COOKIE");
269 xdg_session_class = getenv ("XDG_SESSION_CLASS");
270 desktop_session = getenv ("DESKTOP_SESSION");
271 mir_socket = getenv ("MIR_SOCKET");
272 mir_vt = getenv ("MIR_SERVER_VT");
273 mir_id = getenv ("MIR_SERVER_NAME");
276 if (display[0] == ':')
277 session_id = g_strdup_printf ("SESSION-X-%s", display + 1);
279 session_id = g_strdup_printf ("SESSION-X-%s", display);
282 session_id = g_strdup_printf ("SESSION-MIR-%s", mir_id);
283 else if (mir_socket || mir_vt)
284 session_id = g_strdup ("SESSION-MIR");
286 session_id = g_strdup ("SESSION-UNKNOWN");
288 open_fds = g_string_new ("");
289 open_max = sysconf (_SC_OPEN_MAX);
290 for (fd = STDERR_FILENO + 1; fd < open_max; fd++)
292 if (fcntl (fd, F_GETFD) >= 0)
293 g_string_append_printf (open_fds, "%d,", fd);
295 if (g_str_has_suffix (open_fds->str, ","))
296 open_fds->str[strlen (open_fds->str) - 1] = '\0';
298 #if !defined(GLIB_VERSION_2_36)
302 loop = g_main_loop_new (NULL, FALSE);
304 g_unix_signal_add (SIGINT, sigint_cb, NULL);
305 g_unix_signal_add (SIGTERM, sigterm_cb, NULL);
307 status_connect (request_cb);
309 status_text = g_string_new ("");
310 g_string_printf (status_text, "%s START", session_id);
312 g_string_append_printf (status_text, " XDG_SEAT=%s", xdg_seat);
314 g_string_append_printf (status_text, " XDG_VTNR=%s", xdg_vtnr);
315 if (xdg_current_desktop)
316 g_string_append_printf (status_text, " XDG_CURRENT_DESKTOP=%s", xdg_current_desktop);
317 if (xdg_greeter_data_dir)
318 g_string_append_printf (status_text, " XDG_GREETER_DATA_DIR=%s", xdg_greeter_data_dir);
319 if (xdg_session_cookie)
320 g_string_append_printf (status_text, " XDG_SESSION_COOKIE=%s", xdg_session_cookie);
321 if (xdg_session_class)
322 g_string_append_printf (status_text, " XDG_SESSION_CLASS=%s", xdg_session_class);
324 g_string_append_printf (status_text, " DESKTOP_SESSION=%s", desktop_session);
326 g_string_append_printf (status_text, " MIR_SERVER_VT=%s", mir_vt);
328 g_string_append_printf (status_text, " NAME=%s", argv[1]);
329 g_string_append_printf (status_text, " USER=%s", getenv ("USER"));
330 status_notify (status_text->str);
331 g_string_free (status_text, TRUE);
333 config = g_key_file_new ();
334 g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL);
338 connection = xcb_connect (NULL, NULL);
339 if (xcb_connection_has_error (connection))
341 status_notify ("%s CONNECT-XSERVER-ERROR", session_id);
344 status_notify ("%s CONNECT-XSERVER", session_id);
347 g_main_loop_run (loop);