]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - tests/src/test-session.c
Refactor shared data tests so they don't require root.
[sojka/lightdm.git] / tests / src / test-session.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <sys/types.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <grp.h>
8 #include <xcb/xcb.h>
9 #include <glib.h>
10 #include <glib-object.h>
11 #include <gio/gio.h>
12 #include <glib-unix.h>
13 #include <glib/gstdio.h>
14
15 #include "status.h"
16
17 static gchar *session_id;
18
19 static GMainLoop *loop;
20
21 static GString *open_fds;
22
23 static GKeyFile *config;
24
25 static xcb_connection_t *connection;
26
27 static gboolean
28 sigint_cb (gpointer user_data)
29 {
30     status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGINT);
31     g_main_loop_quit (loop);
32     return TRUE;
33 }
34
35 static gboolean
36 sigterm_cb (gpointer user_data)
37 {
38     status_notify ("%s TERMINATE SIGNAL=%d", session_id, SIGTERM);
39     g_main_loop_quit (loop);
40     return TRUE;
41 }
42
43 static void
44 request_cb (const gchar *request)
45 {
46     gchar *r;
47
48     if (!request)
49     {
50         g_main_loop_quit (loop);
51         return;
52     }
53   
54     r = g_strdup_printf ("%s LOGOUT", session_id);
55     if (strcmp (request, r) == 0)
56         exit (EXIT_SUCCESS);
57     g_free (r);
58   
59     r = g_strdup_printf ("%s CRASH", session_id);
60     if (strcmp (request, r) == 0)
61         kill (getpid (), SIGSEGV);
62     g_free (r);
63
64     r = g_strdup_printf ("%s LOCK-SEAT", session_id);
65     if (strcmp (request, r) == 0)
66     {
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",
72                                      "Lock",
73                                      g_variant_new ("()"),
74                                      G_VARIANT_TYPE ("()"),
75                                      G_DBUS_CALL_FLAGS_NONE,
76                                      1000,
77                                      NULL,
78                                      NULL);
79     }
80     g_free (r);
81
82     r = g_strdup_printf ("%s LOCK-SESSION", session_id);
83     if (strcmp (request, r) == 0)
84     {
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",
90                                      "Lock",
91                                      g_variant_new ("()"),
92                                      G_VARIANT_TYPE ("()"),
93                                      G_DBUS_CALL_FLAGS_NONE,
94                                      1000,
95                                      NULL,
96                                      NULL);
97     }
98     g_free (r);
99
100     r = g_strdup_printf ("%s LIST-GROUPS", session_id);
101     if (strcmp (request, r) == 0)
102     {
103         int n_groups, i;
104         gid_t *groups;
105         GString *group_list;
106
107         n_groups = getgroups (0, NULL);
108         if (n_groups < 0)
109         {
110             g_printerr ("Failed to get groups: %s", strerror (errno));
111             n_groups = 0;
112         }
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++)
117         {
118             struct group *group;
119
120             if (i != 0)
121                 g_string_append (group_list, ",");
122             group = getgrgid (groups[i]);
123             if (group)
124                 g_string_append (group_list, group->gr_name);
125             else
126                 g_string_append_printf (group_list, "%d", groups[i]);
127         }
128         status_notify ("%s LIST-GROUPS GROUPS=%s", session_id, group_list->str);
129         g_string_free (group_list, TRUE);
130         free (groups);
131     }
132
133     r = g_strdup_printf ("%s READ-ENV NAME=", session_id);
134     if (g_str_has_prefix (request, r))
135     {
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 : "");
139     }
140     g_free (r);
141
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));
145     g_free (r);
146
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));
150     g_free (r);
151
152     r = g_strdup_printf ("%s READ FILE=", session_id);
153     if (g_str_has_prefix (request, r))
154     {
155         const gchar *name = request + strlen (r);
156         gchar *contents = NULL;
157         GError *error = NULL;
158
159         if (g_file_get_contents (name, &contents, NULL, &error))
160             status_notify ("%s READ FILE=%s TEXT=%s", session_id, name, contents);
161         else
162             status_notify ("%s READ FILE=%s ERROR=%s", session_id, name, error->message);
163         g_free (contents);
164         g_clear_error (&error);
165     }
166     g_free (r);
167
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);
171     g_free (r);
172
173     r = g_strdup_printf ("%s CHECK-X-AUTHORITY", session_id);
174     if (strcmp (request, r) == 0)
175     {
176         gchar *xauthority;
177         GStatBuf file_info;
178         GString *mode_string;
179
180         xauthority = g_strdup (g_getenv ("XAUTHORITY"));
181         if (!xauthority)
182             xauthority = g_build_filename (g_get_home_dir (), ".Xauthority", NULL);
183
184         g_stat (xauthority, &file_info);
185         g_free (xauthority);
186
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);
199     }
200     g_free (r);
201
202     r = g_strdup_printf ("%s WRITE-SHARED-DATA DATA=", session_id);
203     if (g_str_has_prefix (request, r))
204     {
205         const gchar *data = request + strlen (r);
206         gchar *dir;
207       
208         dir = getenv ("XDG_GREETER_DATA_DIR");
209         if (dir)
210         {
211             gchar *path;
212             FILE *f;
213
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));
217             else
218                 status_notify ("%s WRITE-SHARED-DATA RESULT=TRUE", session_id);
219
220             if (f)
221                 fclose (f);
222             g_free (path);
223         }
224         else
225             status_notify ("%s WRITE-SHARED-DATA ERROR=NO_XDG_GREETER_DATA_DIR", session_id);
226     }
227     g_free (r);
228
229     r = g_strdup_printf ("%s READ-SHARED-DATA", session_id);
230     if (strcmp (request, r) == 0)
231     {
232         gchar *dir;
233
234         dir = getenv ("XDG_GREETER_DATA_DIR");
235         if (dir)
236         {
237             gchar *path;
238             gchar *contents = NULL;
239             GError *error = NULL;
240
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);
244             else
245                 status_notify ("%s WRITE-SHARED-DATA ERROR=%s", session_id, error->message);
246             g_free (path);
247             g_free (contents);
248             g_clear_error (&error);
249         }
250         else
251             status_notify ("%s WRITE-SHARED-DATA ERROR=NO_XDG_GREETER_DATA_DIR", session_id);
252     }
253     g_free (r);
254 }
255
256 int
257 main (int argc, char **argv)
258 {
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;
261     int fd, open_max;
262
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");
274     if (display)
275     {
276         if (display[0] == ':')
277             session_id = g_strdup_printf ("SESSION-X-%s", display + 1);
278         else
279             session_id = g_strdup_printf ("SESSION-X-%s", display);
280     }
281     else if (mir_id)
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");
285     else
286         session_id = g_strdup ("SESSION-UNKNOWN");
287
288     open_fds = g_string_new ("");
289     open_max = sysconf (_SC_OPEN_MAX);
290     for (fd = STDERR_FILENO + 1; fd < open_max; fd++)
291     {
292         if (fcntl (fd, F_GETFD) >= 0)
293             g_string_append_printf (open_fds, "%d,", fd);
294     }
295     if (g_str_has_suffix (open_fds->str, ","))
296         open_fds->str[strlen (open_fds->str) - 1] = '\0';
297
298 #if !defined(GLIB_VERSION_2_36)
299     g_type_init ();
300 #endif
301
302     loop = g_main_loop_new (NULL, FALSE);
303
304     g_unix_signal_add (SIGINT, sigint_cb, NULL);
305     g_unix_signal_add (SIGTERM, sigterm_cb, NULL);
306
307     status_connect (request_cb);
308
309     status_text = g_string_new ("");
310     g_string_printf (status_text, "%s START", session_id);
311     if (xdg_seat)
312         g_string_append_printf (status_text, " XDG_SEAT=%s", xdg_seat);
313     if (xdg_vtnr)
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);
323     if (desktop_session)
324         g_string_append_printf (status_text, " DESKTOP_SESSION=%s", desktop_session);
325     if (mir_vt > 0)
326         g_string_append_printf (status_text, " MIR_SERVER_VT=%s", mir_vt);
327     if (argc > 1)
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);
332
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);
335
336     if (display)
337     {
338         connection = xcb_connect (NULL, NULL);
339         if (xcb_connection_has_error (connection))
340         {
341             status_notify ("%s CONNECT-XSERVER-ERROR", session_id);
342             return EXIT_FAILURE;
343         }
344         status_notify ("%s CONNECT-XSERVER", session_id);
345     }
346
347     g_main_loop_run (loop);
348
349     return EXIT_SUCCESS;
350 }