chiark / gitweb /
test-catalog,core/load-dropin: remove unused variables
[elogind.git] / src / login / logind.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <pwd.h>
24 #include <libudev.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/epoll.h>
29 #include <sys/ioctl.h>
30 #include <linux/vt.h>
31 #include <sys/timerfd.h>
32
33 #include <systemd/sd-daemon.h>
34
35 #include "logind.h"
36 #include "dbus-common.h"
37 #include "dbus-loop.h"
38 #include "strv.h"
39 #include "conf-parser.h"
40 #include "mkdir.h"
41
42 Manager *manager_new(void) {
43         Manager *m;
44
45         m = new0(Manager, 1);
46         if (!m)
47                 return NULL;
48
49         m->console_active_fd = -1;
50         m->bus_fd = -1;
51         m->udev_seat_fd = -1;
52         m->udev_vcsa_fd = -1;
53         m->udev_button_fd = -1;
54         m->epoll_fd = -1;
55         m->reserve_vt_fd = -1;
56
57         m->n_autovts = 6;
58         m->reserve_vt = 6;
59         m->inhibit_delay_max = 5 * USEC_PER_SEC;
60         m->handle_power_key = HANDLE_POWEROFF;
61         m->handle_suspend_key = HANDLE_SUSPEND;
62         m->handle_hibernate_key = HANDLE_HIBERNATE;
63         m->handle_lid_switch = HANDLE_SUSPEND;
64         m->lid_switch_ignore_inhibited = true;
65
66         m->idle_action_fd = -1;
67         m->idle_action_usec = 30 * USEC_PER_MINUTE;
68         m->idle_action = HANDLE_IGNORE;
69         m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
70
71         m->devices = hashmap_new(string_hash_func, string_compare_func);
72         m->seats = hashmap_new(string_hash_func, string_compare_func);
73         m->sessions = hashmap_new(string_hash_func, string_compare_func);
74         m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
75         m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
76         m->buttons = hashmap_new(string_hash_func, string_compare_func);
77
78         m->user_cgroups = hashmap_new(string_hash_func, string_compare_func);
79         m->session_cgroups = hashmap_new(string_hash_func, string_compare_func);
80
81         m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
82         m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
83         m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
84
85         if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
86             !m->user_cgroups || !m->session_cgroups ||
87             !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
88                 manager_free(m);
89                 return NULL;
90         }
91
92         m->reset_controllers = strv_new("cpu", NULL);
93         m->kill_exclude_users = strv_new("root", NULL);
94         if (!m->reset_controllers || !m->kill_exclude_users) {
95                 manager_free(m);
96                 return NULL;
97         }
98
99         m->udev = udev_new();
100         if (!m->udev) {
101                 manager_free(m);
102                 return NULL;
103         }
104
105         if (cg_get_user_path(&m->cgroup_path) < 0) {
106                 manager_free(m);
107                 return NULL;
108         }
109
110         return m;
111 }
112
113 void manager_free(Manager *m) {
114         Session *session;
115         User *u;
116         Device *d;
117         Seat *s;
118         Inhibitor *i;
119         Button *b;
120
121         assert(m);
122
123         while ((session = hashmap_first(m->sessions)))
124                 session_free(session);
125
126         while ((u = hashmap_first(m->users)))
127                 user_free(u);
128
129         while ((d = hashmap_first(m->devices)))
130                 device_free(d);
131
132         while ((s = hashmap_first(m->seats)))
133                 seat_free(s);
134
135         while ((i = hashmap_first(m->inhibitors)))
136                 inhibitor_free(i);
137
138         while ((b = hashmap_first(m->buttons)))
139                 button_free(b);
140
141         hashmap_free(m->devices);
142         hashmap_free(m->seats);
143         hashmap_free(m->sessions);
144         hashmap_free(m->users);
145         hashmap_free(m->inhibitors);
146         hashmap_free(m->buttons);
147
148         hashmap_free(m->user_cgroups);
149         hashmap_free(m->session_cgroups);
150
151         hashmap_free(m->session_fds);
152         hashmap_free(m->inhibitor_fds);
153         hashmap_free(m->button_fds);
154
155         if (m->console_active_fd >= 0)
156                 close_nointr_nofail(m->console_active_fd);
157
158         if (m->udev_seat_monitor)
159                 udev_monitor_unref(m->udev_seat_monitor);
160         if (m->udev_vcsa_monitor)
161                 udev_monitor_unref(m->udev_vcsa_monitor);
162         if (m->udev_button_monitor)
163                 udev_monitor_unref(m->udev_button_monitor);
164
165         if (m->udev)
166                 udev_unref(m->udev);
167
168         if (m->bus) {
169                 dbus_connection_flush(m->bus);
170                 dbus_connection_close(m->bus);
171                 dbus_connection_unref(m->bus);
172         }
173
174         if (m->bus_fd >= 0)
175                 close_nointr_nofail(m->bus_fd);
176
177         if (m->epoll_fd >= 0)
178                 close_nointr_nofail(m->epoll_fd);
179
180         if (m->reserve_vt_fd >= 0)
181                 close_nointr_nofail(m->reserve_vt_fd);
182
183         if (m->idle_action_fd >= 0)
184                 close_nointr_nofail(m->idle_action_fd);
185
186         strv_free(m->controllers);
187         strv_free(m->reset_controllers);
188         strv_free(m->kill_only_users);
189         strv_free(m->kill_exclude_users);
190
191         free(m->action_job);
192
193         free(m->cgroup_path);
194         free(m);
195 }
196
197 int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
198         Device *d;
199
200         assert(m);
201         assert(sysfs);
202
203         d = hashmap_get(m->devices, sysfs);
204         if (d) {
205                 if (_device)
206                         *_device = d;
207
208                 return 0;
209         }
210
211         d = device_new(m, sysfs);
212         if (!d)
213                 return -ENOMEM;
214
215         if (_device)
216                 *_device = d;
217
218         return 0;
219 }
220
221 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
222         Seat *s;
223
224         assert(m);
225         assert(id);
226
227         s = hashmap_get(m->seats, id);
228         if (s) {
229                 if (_seat)
230                         *_seat = s;
231
232                 return 0;
233         }
234
235         s = seat_new(m, id);
236         if (!s)
237                 return -ENOMEM;
238
239         if (_seat)
240                 *_seat = s;
241
242         return 0;
243 }
244
245 int manager_add_session(Manager *m, User *u, const char *id, Session **_session) {
246         Session *s;
247
248         assert(m);
249         assert(id);
250
251         s = hashmap_get(m->sessions, id);
252         if (s) {
253                 if (_session)
254                         *_session = s;
255
256                 return 0;
257         }
258
259         s = session_new(m, u, id);
260         if (!s)
261                 return -ENOMEM;
262
263         if (_session)
264                 *_session = s;
265
266         return 0;
267 }
268
269 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
270         User *u;
271
272         assert(m);
273         assert(name);
274
275         u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
276         if (u) {
277                 if (_user)
278                         *_user = u;
279
280                 return 0;
281         }
282
283         u = user_new(m, uid, gid, name);
284         if (!u)
285                 return -ENOMEM;
286
287         if (_user)
288                 *_user = u;
289
290         return 0;
291 }
292
293 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
294         uid_t uid;
295         gid_t gid;
296         int r;
297
298         assert(m);
299         assert(name);
300
301         r = get_user_creds(&name, &uid, &gid, NULL, NULL);
302         if (r < 0)
303                 return r;
304
305         return manager_add_user(m, uid, gid, name, _user);
306 }
307
308 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
309         struct passwd *p;
310
311         assert(m);
312
313         errno = 0;
314         p = getpwuid(uid);
315         if (!p)
316                 return errno ? -errno : -ENOENT;
317
318         return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
319 }
320
321 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
322         Inhibitor *i;
323
324         assert(m);
325         assert(id);
326
327         i = hashmap_get(m->inhibitors, id);
328         if (i) {
329                 if (_inhibitor)
330                         *_inhibitor = i;
331
332                 return 0;
333         }
334
335         i = inhibitor_new(m, id);
336         if (!i)
337                 return -ENOMEM;
338
339         if (_inhibitor)
340                 *_inhibitor = i;
341
342         return 0;
343 }
344
345 int manager_add_button(Manager *m, const char *name, Button **_button) {
346         Button *b;
347
348         assert(m);
349         assert(name);
350
351         b = hashmap_get(m->buttons, name);
352         if (b) {
353                 if (_button)
354                         *_button = b;
355
356                 return 0;
357         }
358
359         b = button_new(m, name);
360         if (!b)
361                 return -ENOMEM;
362
363         if (_button)
364                 *_button = b;
365
366         return 0;
367 }
368
369 int manager_process_seat_device(Manager *m, struct udev_device *d) {
370         Device *device;
371         int r;
372
373         assert(m);
374
375         if (streq_ptr(udev_device_get_action(d), "remove")) {
376
377                 device = hashmap_get(m->devices, udev_device_get_syspath(d));
378                 if (!device)
379                         return 0;
380
381                 seat_add_to_gc_queue(device->seat);
382                 device_free(device);
383
384         } else {
385                 const char *sn;
386                 Seat *seat;
387
388                 sn = udev_device_get_property_value(d, "ID_SEAT");
389                 if (isempty(sn))
390                         sn = "seat0";
391
392                 if (!seat_name_is_valid(sn)) {
393                         log_warning("Device with invalid seat name %s found, ignoring.", sn);
394                         return 0;
395                 }
396
397                 r = manager_add_device(m, udev_device_get_syspath(d), &device);
398                 if (r < 0)
399                         return r;
400
401                 r = manager_add_seat(m, sn, &seat);
402                 if (r < 0) {
403                         if (!device->seat)
404                                 device_free(device);
405
406                         return r;
407                 }
408
409                 device_attach(device, seat);
410                 seat_start(seat);
411         }
412
413         return 0;
414 }
415
416 int manager_process_button_device(Manager *m, struct udev_device *d) {
417         Button *b;
418
419         int r;
420
421         assert(m);
422
423         if (streq_ptr(udev_device_get_action(d), "remove")) {
424
425                 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
426                 if (!b)
427                         return 0;
428
429                 button_free(b);
430
431         } else {
432                 const char *sn;
433
434                 r = manager_add_button(m, udev_device_get_sysname(d), &b);
435                 if (r < 0)
436                         return r;
437
438                 sn = udev_device_get_property_value(d, "ID_SEAT");
439                 if (isempty(sn))
440                         sn = "seat0";
441
442                 button_set_seat(b, sn);
443                 button_open(b);
444         }
445
446         return 0;
447 }
448
449 int manager_enumerate_devices(Manager *m) {
450         struct udev_list_entry *item = NULL, *first = NULL;
451         struct udev_enumerate *e;
452         int r;
453
454         assert(m);
455
456         /* Loads devices from udev and creates seats for them as
457          * necessary */
458
459         e = udev_enumerate_new(m->udev);
460         if (!e) {
461                 r = -ENOMEM;
462                 goto finish;
463         }
464
465         r = udev_enumerate_add_match_tag(e, "master-of-seat");
466         if (r < 0)
467                 goto finish;
468
469         r = udev_enumerate_scan_devices(e);
470         if (r < 0)
471                 goto finish;
472
473         first = udev_enumerate_get_list_entry(e);
474         udev_list_entry_foreach(item, first) {
475                 struct udev_device *d;
476                 int k;
477
478                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
479                 if (!d) {
480                         r = -ENOMEM;
481                         goto finish;
482                 }
483
484                 k = manager_process_seat_device(m, d);
485                 udev_device_unref(d);
486
487                 if (k < 0)
488                         r = k;
489         }
490
491 finish:
492         if (e)
493                 udev_enumerate_unref(e);
494
495         return r;
496 }
497
498 int manager_enumerate_buttons(Manager *m) {
499         struct udev_list_entry *item = NULL, *first = NULL;
500         struct udev_enumerate *e;
501         int r;
502
503         assert(m);
504
505         /* Loads buttons from udev */
506
507         if (m->handle_power_key == HANDLE_IGNORE &&
508             m->handle_suspend_key == HANDLE_IGNORE &&
509             m->handle_hibernate_key == HANDLE_IGNORE &&
510             m->handle_lid_switch == HANDLE_IGNORE)
511                 return 0;
512
513         e = udev_enumerate_new(m->udev);
514         if (!e) {
515                 r = -ENOMEM;
516                 goto finish;
517         }
518
519         r = udev_enumerate_add_match_subsystem(e, "input");
520         if (r < 0)
521                 goto finish;
522
523         r = udev_enumerate_add_match_tag(e, "power-switch");
524         if (r < 0)
525                 goto finish;
526
527         r = udev_enumerate_scan_devices(e);
528         if (r < 0)
529                 goto finish;
530
531         first = udev_enumerate_get_list_entry(e);
532         udev_list_entry_foreach(item, first) {
533                 struct udev_device *d;
534                 int k;
535
536                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
537                 if (!d) {
538                         r = -ENOMEM;
539                         goto finish;
540                 }
541
542                 k = manager_process_button_device(m, d);
543                 udev_device_unref(d);
544
545                 if (k < 0)
546                         r = k;
547         }
548
549 finish:
550         if (e)
551                 udev_enumerate_unref(e);
552
553         return r;
554 }
555
556 int manager_enumerate_seats(Manager *m) {
557         DIR *d;
558         struct dirent *de;
559         int r = 0;
560
561         assert(m);
562
563         /* This loads data about seats stored on disk, but does not
564          * actually create any seats. Removes data of seats that no
565          * longer exist. */
566
567         d = opendir("/run/systemd/seats");
568         if (!d) {
569                 if (errno == ENOENT)
570                         return 0;
571
572                 log_error("Failed to open /run/systemd/seats: %m");
573                 return -errno;
574         }
575
576         while ((de = readdir(d))) {
577                 Seat *s;
578                 int k;
579
580                 if (!dirent_is_file(de))
581                         continue;
582
583                 s = hashmap_get(m->seats, de->d_name);
584                 if (!s) {
585                         unlinkat(dirfd(d), de->d_name, 0);
586                         continue;
587                 }
588
589                 k = seat_load(s);
590                 if (k < 0)
591                         r = k;
592         }
593
594         closedir(d);
595
596         return r;
597 }
598
599 static int manager_enumerate_users_from_cgroup(Manager *m) {
600         int r = 0, k;
601         char *name;
602         DIR *d;
603
604         r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
605         if (r < 0) {
606                 if (r == -ENOENT)
607                         return 0;
608
609                 log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r));
610                 return r;
611         }
612
613         while ((k = cg_read_subgroup(d, &name)) > 0) {
614                 User *user;
615
616                 k = manager_add_user_by_name(m, name, &user);
617                 if (k < 0) {
618                         free(name);
619                         r = k;
620                         continue;
621                 }
622
623                 user_add_to_gc_queue(user);
624
625                 if (!user->cgroup_path)
626                         if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) {
627                                 r = -ENOMEM;
628                                 free(name);
629                                 break;
630                         }
631
632                 free(name);
633         }
634
635         if (r >= 0 && k < 0)
636                 r = k;
637
638         closedir(d);
639
640         return r;
641 }
642
643 static int manager_enumerate_linger_users(Manager *m) {
644         DIR *d;
645         struct dirent *de;
646         int r = 0;
647
648         d = opendir("/var/lib/systemd/linger");
649         if (!d) {
650                 if (errno == ENOENT)
651                         return 0;
652
653                 log_error("Failed to open /var/lib/systemd/linger/: %m");
654                 return -errno;
655         }
656
657         while ((de = readdir(d))) {
658                 int k;
659
660                 if (!dirent_is_file(de))
661                         continue;
662
663                 k = manager_add_user_by_name(m, de->d_name, NULL);
664                 if (k < 0) {
665                         log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
666                         r = k;
667                 }
668         }
669
670         closedir(d);
671
672         return r;
673 }
674
675 int manager_enumerate_users(Manager *m) {
676         DIR *d;
677         struct dirent *de;
678         int r, k;
679
680         assert(m);
681
682         /* First, enumerate user cgroups */
683         r = manager_enumerate_users_from_cgroup(m);
684
685         /* Second, add lingering users on top */
686         k = manager_enumerate_linger_users(m);
687         if (k < 0)
688                 r = k;
689
690         /* Third, read in user data stored on disk */
691         d = opendir("/run/systemd/users");
692         if (!d) {
693                 if (errno == ENOENT)
694                         return 0;
695
696                 log_error("Failed to open /run/systemd/users: %m");
697                 return -errno;
698         }
699
700         while ((de = readdir(d))) {
701                 uid_t uid;
702                 User *u;
703
704                 if (!dirent_is_file(de))
705                         continue;
706
707                 k = parse_uid(de->d_name, &uid);
708                 if (k < 0) {
709                         log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
710                         continue;
711                 }
712
713                 u = hashmap_get(m->users, ULONG_TO_PTR(uid));
714                 if (!u) {
715                         unlinkat(dirfd(d), de->d_name, 0);
716                         continue;
717                 }
718
719                 k = user_load(u);
720                 if (k < 0)
721                         r = k;
722         }
723
724         closedir(d);
725
726         return r;
727 }
728
729 static int manager_enumerate_sessions_from_cgroup(Manager *m) {
730         User *u;
731         Iterator i;
732         int r = 0;
733
734         HASHMAP_FOREACH(u, m->users, i) {
735                 DIR *d;
736                 char *name;
737                 int k;
738
739                 if (!u->cgroup_path)
740                         continue;
741
742                 k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d);
743                 if (k < 0) {
744                         if (k == -ENOENT)
745                                 continue;
746
747                         log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k));
748                         r = k;
749                         continue;
750                 }
751
752                 while ((k = cg_read_subgroup(d, &name)) > 0) {
753                         Session *session;
754
755                         if (streq(name, "shared"))
756                                 continue;
757
758                         k = manager_add_session(m, u, name, &session);
759                         if (k < 0) {
760                                 free(name);
761                                 break;
762                         }
763
764                         session_add_to_gc_queue(session);
765
766                         if (!session->cgroup_path)
767                                 if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) {
768                                         k = -ENOMEM;
769                                         free(name);
770                                         break;
771                                 }
772
773                         free(name);
774                 }
775
776                 closedir(d);
777
778                 if (k < 0)
779                         r = k;
780         }
781
782         return r;
783 }
784
785 int manager_enumerate_sessions(Manager *m) {
786         DIR *d;
787         struct dirent *de;
788         int r = 0;
789
790         assert(m);
791
792         /* First enumerate session cgroups */
793         r = manager_enumerate_sessions_from_cgroup(m);
794
795         /* Second, read in session data stored on disk */
796         d = opendir("/run/systemd/sessions");
797         if (!d) {
798                 if (errno == ENOENT)
799                         return 0;
800
801                 log_error("Failed to open /run/systemd/sessions: %m");
802                 return -errno;
803         }
804
805         while ((de = readdir(d))) {
806                 struct Session *s;
807                 int k;
808
809                 if (!dirent_is_file(de))
810                         continue;
811
812                 s = hashmap_get(m->sessions, de->d_name);
813                 if (!s) {
814                         unlinkat(dirfd(d), de->d_name, 0);
815                         continue;
816                 }
817
818                 k = session_load(s);
819                 if (k < 0)
820                         r = k;
821         }
822
823         closedir(d);
824
825         return r;
826 }
827
828 int manager_enumerate_inhibitors(Manager *m) {
829         DIR *d;
830         struct dirent *de;
831         int r = 0;
832
833         assert(m);
834
835         d = opendir("/run/systemd/inhibit");
836         if (!d) {
837                 if (errno == ENOENT)
838                         return 0;
839
840                 log_error("Failed to open /run/systemd/inhibit: %m");
841                 return -errno;
842         }
843
844         while ((de = readdir(d))) {
845                 int k;
846                 Inhibitor *i;
847
848                 if (!dirent_is_file(de))
849                         continue;
850
851                 k = manager_add_inhibitor(m, de->d_name, &i);
852                 if (k < 0) {
853                         log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
854                         r = k;
855                         continue;
856                 }
857
858                 k = inhibitor_load(i);
859                 if (k < 0)
860                         r = k;
861         }
862
863         closedir(d);
864
865         return r;
866 }
867
868 int manager_dispatch_seat_udev(Manager *m) {
869         struct udev_device *d;
870         int r;
871
872         assert(m);
873
874         d = udev_monitor_receive_device(m->udev_seat_monitor);
875         if (!d)
876                 return -ENOMEM;
877
878         r = manager_process_seat_device(m, d);
879         udev_device_unref(d);
880
881         return r;
882 }
883
884 int manager_dispatch_vcsa_udev(Manager *m) {
885         struct udev_device *d;
886         int r = 0;
887         const char *name;
888
889         assert(m);
890
891         d = udev_monitor_receive_device(m->udev_vcsa_monitor);
892         if (!d)
893                 return -ENOMEM;
894
895         name = udev_device_get_sysname(d);
896
897         /* Whenever a VCSA device is removed try to reallocate our
898          * VTs, to make sure our auto VTs never go away. */
899
900         if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
901                 r = seat_preallocate_vts(m->vtconsole);
902
903         udev_device_unref(d);
904
905         return r;
906 }
907
908 int manager_dispatch_button_udev(Manager *m) {
909         struct udev_device *d;
910         int r;
911
912         assert(m);
913
914         d = udev_monitor_receive_device(m->udev_button_monitor);
915         if (!d)
916                 return -ENOMEM;
917
918         r = manager_process_button_device(m, d);
919         udev_device_unref(d);
920
921         return r;
922 }
923
924 int manager_dispatch_console(Manager *m) {
925         assert(m);
926
927         if (m->vtconsole)
928                 seat_read_active_vt(m->vtconsole);
929
930         return 0;
931 }
932
933 static int vt_is_busy(int vtnr) {
934         struct vt_stat vt_stat;
935         int r = 0, fd;
936
937         assert(vtnr >= 1);
938
939         /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
940          * we'd open the latter we'd open the foreground tty which
941          * hence would be unconditionally busy. By opening /dev/tty1
942          * we avoid this. Since tty1 is special and needs to be an
943          * explicitly loaded getty or DM this is safe. */
944
945         fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
946         if (fd < 0)
947                 return -errno;
948
949         if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
950                 r = -errno;
951         else
952                 r = !!(vt_stat.v_state & (1 << vtnr));
953
954         close_nointr_nofail(fd);
955
956         return r;
957 }
958
959 int manager_spawn_autovt(Manager *m, int vtnr) {
960         int r;
961         char *name = NULL;
962         const char *mode = "fail";
963
964         assert(m);
965         assert(vtnr >= 1);
966
967         if ((unsigned) vtnr > m->n_autovts &&
968             (unsigned) vtnr != m->reserve_vt)
969                 return 0;
970
971         if ((unsigned) vtnr != m->reserve_vt) {
972                 /* If this is the reserved TTY, we'll start the getty
973                  * on it in any case, but otherwise only if it is not
974                  * busy. */
975
976                 r = vt_is_busy(vtnr);
977                 if (r < 0)
978                         return r;
979                 else if (r > 0)
980                         return -EBUSY;
981         }
982
983         if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
984                 log_error("Could not allocate service name.");
985                 r = -ENOMEM;
986                 goto finish;
987         }
988
989         r = bus_method_call_with_reply (
990                         m->bus,
991                         "org.freedesktop.systemd1",
992                         "/org/freedesktop/systemd1",
993                         "org.freedesktop.systemd1.Manager",
994                         "StartUnit",
995                         NULL,
996                         NULL,
997                         DBUS_TYPE_STRING, &name,
998                         DBUS_TYPE_STRING, &mode,
999                         DBUS_TYPE_INVALID);
1000
1001 finish:
1002         free(name);
1003
1004         return r;
1005 }
1006
1007 static int manager_reserve_vt(Manager *m) {
1008         _cleanup_free_ char *p = NULL;
1009
1010         assert(m);
1011
1012         if (m->reserve_vt <= 0)
1013                 return 0;
1014
1015         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
1016                 return log_oom();
1017
1018         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
1019         if (m->reserve_vt_fd < 0) {
1020
1021                 /* Don't complain on VT-less systems */
1022                 if (errno != ENOENT)
1023                         log_warning("Failed to pin reserved VT: %m");
1024                 return -errno;
1025         }
1026
1027         return 0;
1028 }
1029
1030 int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
1031         Session *s;
1032         char *p;
1033
1034         assert(m);
1035         assert(cgroup);
1036         assert(session);
1037
1038         s = hashmap_get(m->session_cgroups, cgroup);
1039         if (s) {
1040                 *session = s;
1041                 return 1;
1042         }
1043
1044         p = strdup(cgroup);
1045         if (!p)
1046                 return log_oom();
1047
1048         for (;;) {
1049                 char *e;
1050
1051                 e = strrchr(p, '/');
1052                 if (!e || e == p) {
1053                         free(p);
1054                         *session = NULL;
1055                         return 0;
1056                 }
1057
1058                 *e = 0;
1059
1060                 s = hashmap_get(m->session_cgroups, p);
1061                 if (s) {
1062                         free(p);
1063                         *session = s;
1064                         return 1;
1065                 }
1066         }
1067 }
1068
1069 int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
1070         User *u;
1071         char *p;
1072
1073         assert(m);
1074         assert(cgroup);
1075         assert(user);
1076
1077         u = hashmap_get(m->user_cgroups, cgroup);
1078         if (u) {
1079                 *user = u;
1080                 return 1;
1081         }
1082
1083         p = strdup(cgroup);
1084         if (!p)
1085                 return log_oom();
1086
1087         for (;;) {
1088                 char *e;
1089
1090                 e = strrchr(p, '/');
1091                 if (!e || e == p) {
1092                         free(p);
1093                         *user = NULL;
1094                         return 0;
1095                 }
1096
1097                 *e = 0;
1098
1099                 u = hashmap_get(m->user_cgroups, p);
1100                 if (u) {
1101                         free(p);
1102                         *user = u;
1103                         return 1;
1104                 }
1105         }
1106 }
1107
1108 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
1109         char *p;
1110         int r;
1111
1112         assert(m);
1113         assert(pid >= 1);
1114         assert(session);
1115
1116         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
1117         if (r < 0)
1118                 return r;
1119
1120         r = manager_get_session_by_cgroup(m, p, session);
1121         free(p);
1122
1123         return r;
1124 }
1125
1126 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
1127         Session *s;
1128         User *u;
1129         int r;
1130
1131         r = manager_get_session_by_cgroup(m, cgroup, &s);
1132         if (r > 0)
1133                 session_add_to_gc_queue(s);
1134
1135         r = manager_get_user_by_cgroup(m, cgroup, &u);
1136         if (r > 0)
1137                 user_add_to_gc_queue(u);
1138 }
1139
1140 static void manager_dispatch_other(Manager *m, int fd) {
1141         Session *s;
1142         Inhibitor *i;
1143         Button *b;
1144
1145         assert_se(m);
1146         assert_se(fd >= 0);
1147
1148         s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1149         if (s) {
1150                 assert(s->fifo_fd == fd);
1151                 session_remove_fifo(s);
1152                 session_stop(s);
1153                 return;
1154         }
1155
1156         i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1157         if (i) {
1158                 assert(i->fifo_fd == fd);
1159                 inhibitor_stop(i);
1160                 inhibitor_free(i);
1161                 return;
1162         }
1163
1164         b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1165         if (b) {
1166                 assert(b->fd == fd);
1167                 button_process(b);
1168                 return;
1169         }
1170
1171         assert_not_reached("Got event for unknown fd");
1172 }
1173
1174 static int manager_connect_bus(Manager *m) {
1175         DBusError error;
1176         int r;
1177         struct epoll_event ev;
1178
1179         assert(m);
1180         assert(!m->bus);
1181         assert(m->bus_fd < 0);
1182
1183         dbus_error_init(&error);
1184
1185         m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1186         if (!m->bus) {
1187                 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1188                 r = -ECONNREFUSED;
1189                 goto fail;
1190         }
1191
1192         if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1193             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1194             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1195             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1196             !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1197                 r = log_oom();
1198                 goto fail;
1199         }
1200
1201         dbus_bus_add_match(m->bus,
1202                            "type='signal',"
1203                            "interface='org.freedesktop.systemd1.Agent',"
1204                            "member='Released',"
1205                            "path='/org/freedesktop/systemd1/agent'",
1206                            &error);
1207
1208         if (dbus_error_is_set(&error)) {
1209                 log_error("Failed to register match: %s", bus_error_message(&error));
1210                 r = -EIO;
1211                 goto fail;
1212         }
1213
1214         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1215         if (dbus_error_is_set(&error)) {
1216                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1217                 r = -EIO;
1218                 goto fail;
1219         }
1220
1221         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1222                 log_error("Failed to acquire name.");
1223                 r = -EEXIST;
1224                 goto fail;
1225         }
1226
1227         m->bus_fd = bus_loop_open(m->bus);
1228         if (m->bus_fd < 0) {
1229                 r = m->bus_fd;
1230                 goto fail;
1231         }
1232
1233         zero(ev);
1234         ev.events = EPOLLIN;
1235         ev.data.u32 = FD_BUS;
1236
1237         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1238                 goto fail;
1239
1240         return 0;
1241
1242 fail:
1243         dbus_error_free(&error);
1244
1245         return r;
1246 }
1247
1248 static int manager_connect_console(Manager *m) {
1249         struct epoll_event ev;
1250
1251         assert(m);
1252         assert(m->console_active_fd < 0);
1253
1254         /* On certain architectures (S390 and Xen, and containers),
1255            /dev/tty0 does not exist, so don't fail if we can't open
1256            it. */
1257         if (access("/dev/tty0", F_OK) < 0) {
1258                 m->console_active_fd = -1;
1259                 return 0;
1260         }
1261
1262         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1263         if (m->console_active_fd < 0) {
1264
1265                 /* On some systems the device node /dev/tty0 may exist
1266                  * even though /sys/class/tty/tty0 does not. */
1267                 if (errno == ENOENT)
1268                         return 0;
1269
1270                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1271                 return -errno;
1272         }
1273
1274         zero(ev);
1275         ev.events = 0;
1276         ev.data.u32 = FD_CONSOLE;
1277
1278         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1279                 return -errno;
1280
1281         return 0;
1282 }
1283
1284 static int manager_connect_udev(Manager *m) {
1285         struct epoll_event ev;
1286         int r;
1287
1288         assert(m);
1289         assert(!m->udev_seat_monitor);
1290         assert(!m->udev_vcsa_monitor);
1291         assert(!m->udev_button_monitor);
1292
1293         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1294         if (!m->udev_seat_monitor)
1295                 return -ENOMEM;
1296
1297         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1298         if (r < 0)
1299                 return r;
1300
1301         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1302         if (r < 0)
1303                 return r;
1304
1305         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1306
1307         zero(ev);
1308         ev.events = EPOLLIN;
1309         ev.data.u32 = FD_SEAT_UDEV;
1310         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1311                 return -errno;
1312
1313         /* Don't watch keys if nobody cares */
1314         if (m->handle_power_key != HANDLE_IGNORE ||
1315             m->handle_suspend_key != HANDLE_IGNORE ||
1316             m->handle_hibernate_key != HANDLE_IGNORE ||
1317             m->handle_lid_switch != HANDLE_IGNORE) {
1318
1319                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1320                 if (!m->udev_button_monitor)
1321                         return -ENOMEM;
1322
1323                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1324                 if (r < 0)
1325                         return r;
1326
1327                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1328                 if (r < 0)
1329                         return r;
1330
1331                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1332                 if (r < 0)
1333                         return r;
1334
1335                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1336
1337                 zero(ev);
1338                 ev.events = EPOLLIN;
1339                 ev.data.u32 = FD_BUTTON_UDEV;
1340                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1341                         return -errno;
1342         }
1343
1344         /* Don't bother watching VCSA devices, if nobody cares */
1345         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1346
1347                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1348                 if (!m->udev_vcsa_monitor)
1349                         return -ENOMEM;
1350
1351                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1352                 if (r < 0)
1353                         return r;
1354
1355                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1356                 if (r < 0)
1357                         return r;
1358
1359                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1360
1361                 zero(ev);
1362                 ev.events = EPOLLIN;
1363                 ev.data.u32 = FD_VCSA_UDEV;
1364                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1365                         return -errno;
1366         }
1367
1368         return 0;
1369 }
1370
1371 void manager_gc(Manager *m, bool drop_not_started) {
1372         Seat *seat;
1373         Session *session;
1374         User *user;
1375
1376         assert(m);
1377
1378         while ((seat = m->seat_gc_queue)) {
1379                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1380                 seat->in_gc_queue = false;
1381
1382                 if (seat_check_gc(seat, drop_not_started) == 0) {
1383                         seat_stop(seat);
1384                         seat_free(seat);
1385                 }
1386         }
1387
1388         while ((session = m->session_gc_queue)) {
1389                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1390                 session->in_gc_queue = false;
1391
1392                 if (session_check_gc(session, drop_not_started) == 0) {
1393                         session_stop(session);
1394                         session_free(session);
1395                 }
1396         }
1397
1398         while ((user = m->user_gc_queue)) {
1399                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1400                 user->in_gc_queue = false;
1401
1402                 if (user_check_gc(user, drop_not_started) == 0) {
1403                         user_stop(user);
1404                         user_free(user);
1405                 }
1406         }
1407 }
1408
1409 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1410         Session *s;
1411         bool idle_hint;
1412         dual_timestamp ts = { 0, 0 };
1413         Iterator i;
1414
1415         assert(m);
1416
1417         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1418
1419         HASHMAP_FOREACH(s, m->sessions, i) {
1420                 dual_timestamp k;
1421                 int ih;
1422
1423                 ih = session_get_idle_hint(s, &k);
1424                 if (ih < 0)
1425                         return ih;
1426
1427                 if (!ih) {
1428                         if (!idle_hint) {
1429                                 if (k.monotonic < ts.monotonic)
1430                                         ts = k;
1431                         } else {
1432                                 idle_hint = false;
1433                                 ts = k;
1434                         }
1435                 } else if (idle_hint) {
1436
1437                         if (k.monotonic > ts.monotonic)
1438                                 ts = k;
1439                 }
1440         }
1441
1442         if (t)
1443                 *t = ts;
1444
1445         return idle_hint;
1446 }
1447
1448 int manager_dispatch_idle_action(Manager *m) {
1449         struct dual_timestamp since;
1450         struct itimerspec its;
1451         int r;
1452         usec_t n;
1453
1454         assert(m);
1455
1456         if (m->idle_action == HANDLE_IGNORE ||
1457             m->idle_action_usec <= 0) {
1458                 r = 0;
1459                 goto finish;
1460         }
1461
1462         zero(its);
1463         n = now(CLOCK_MONOTONIC);
1464
1465         r = manager_get_idle_hint(m, &since);
1466         if (r <= 0)
1467                 /* Not idle. Let's check if after a timeout it might be idle then. */
1468                 timespec_store(&its.it_value, n + m->idle_action_usec);
1469         else {
1470                 /* Idle! Let's see if it's time to do something, or if
1471                  * we shall sleep for longer. */
1472
1473                 if (n >= since.monotonic + m->idle_action_usec &&
1474                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1475                         log_info("System idle. Taking action.");
1476
1477                         manager_handle_action(m, 0, m->idle_action, false, false);
1478                         m->idle_action_not_before_usec = n;
1479                 }
1480
1481                 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1482         }
1483
1484         if (m->idle_action_fd < 0) {
1485                 struct epoll_event ev;
1486
1487                 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1488                 if (m->idle_action_fd < 0) {
1489                         log_error("Failed to create idle action timer: %m");
1490                         r = -errno;
1491                         goto finish;
1492                 }
1493
1494                 zero(ev);
1495                 ev.events = EPOLLIN;
1496                 ev.data.u32 = FD_IDLE_ACTION;
1497
1498                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1499                         log_error("Failed to add idle action timer to epoll: %m");
1500                         r = -errno;
1501                         goto finish;
1502                 }
1503         }
1504
1505         if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1506                 log_error("Failed to reset timerfd: %m");
1507                 r = -errno;
1508                 goto finish;
1509         }
1510
1511         return 0;
1512
1513 finish:
1514         if (m->idle_action_fd >= 0) {
1515                 close_nointr_nofail(m->idle_action_fd);
1516                 m->idle_action_fd = -1;
1517         }
1518
1519         return r;
1520 }
1521 int manager_startup(Manager *m) {
1522         int r;
1523         Seat *seat;
1524         Session *session;
1525         User *user;
1526         Inhibitor *inhibitor;
1527         Iterator i;
1528
1529         assert(m);
1530         assert(m->epoll_fd <= 0);
1531
1532         cg_shorten_controllers(m->reset_controllers);
1533         cg_shorten_controllers(m->controllers);
1534
1535         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1536         if (m->epoll_fd < 0)
1537                 return -errno;
1538
1539         /* Connect to console */
1540         r = manager_connect_console(m);
1541         if (r < 0)
1542                 return r;
1543
1544         /* Connect to udev */
1545         r = manager_connect_udev(m);
1546         if (r < 0)
1547                 return r;
1548
1549         /* Connect to the bus */
1550         r = manager_connect_bus(m);
1551         if (r < 0)
1552                 return r;
1553
1554         /* Instantiate magic seat 0 */
1555         r = manager_add_seat(m, "seat0", &m->vtconsole);
1556         if (r < 0)
1557                 return r;
1558
1559         /* Deserialize state */
1560         manager_enumerate_devices(m);
1561         manager_enumerate_seats(m);
1562         manager_enumerate_users(m);
1563         manager_enumerate_sessions(m);
1564         manager_enumerate_inhibitors(m);
1565         manager_enumerate_buttons(m);
1566
1567         /* Remove stale objects before we start them */
1568         manager_gc(m, false);
1569
1570         /* Reserve the special reserved VT */
1571         manager_reserve_vt(m);
1572
1573         /* And start everything */
1574         HASHMAP_FOREACH(seat, m->seats, i)
1575                 seat_start(seat);
1576
1577         HASHMAP_FOREACH(user, m->users, i)
1578                 user_start(user);
1579
1580         HASHMAP_FOREACH(session, m->sessions, i)
1581                 session_start(session);
1582
1583         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1584                 inhibitor_start(inhibitor);
1585
1586         manager_dispatch_idle_action(m);
1587
1588         return 0;
1589 }
1590
1591 static int manager_recheck_buttons(Manager *m) {
1592         Iterator i;
1593         Button *b;
1594         int r = 0;
1595
1596         assert(m);
1597
1598         HASHMAP_FOREACH(b, m->buttons, i) {
1599                 int q;
1600
1601                 q = button_recheck(b);
1602                 if (q > 0)
1603                         return 1;
1604                 if (q < 0)
1605                         r = q;
1606         }
1607
1608         return r;
1609 }
1610
1611 int manager_run(Manager *m) {
1612         assert(m);
1613
1614         for (;;) {
1615                 struct epoll_event event;
1616                 int n;
1617                 int msec = -1;
1618
1619                 manager_gc(m, true);
1620
1621                 if (manager_dispatch_delayed(m) > 0)
1622                         continue;
1623
1624                 if (manager_recheck_buttons(m) > 0)
1625                         continue;
1626
1627                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1628                         continue;
1629
1630                 manager_gc(m, true);
1631
1632                 if (m->action_what != 0) {
1633                         usec_t x, y;
1634
1635                         x = now(CLOCK_MONOTONIC);
1636                         y = m->action_timestamp + m->inhibit_delay_max;
1637
1638                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1639                 }
1640
1641                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1642                 if (n < 0) {
1643                         if (errno == EINTR || errno == EAGAIN)
1644                                 continue;
1645
1646                         log_error("epoll() failed: %m");
1647                         return -errno;
1648                 }
1649
1650                 if (n == 0)
1651                         continue;
1652
1653                 switch (event.data.u32) {
1654
1655                 case FD_SEAT_UDEV:
1656                         manager_dispatch_seat_udev(m);
1657                         break;
1658
1659                 case FD_VCSA_UDEV:
1660                         manager_dispatch_vcsa_udev(m);
1661                         break;
1662
1663                 case FD_BUTTON_UDEV:
1664                         manager_dispatch_button_udev(m);
1665                         break;
1666
1667                 case FD_CONSOLE:
1668                         manager_dispatch_console(m);
1669                         break;
1670
1671                 case FD_IDLE_ACTION:
1672                         manager_dispatch_idle_action(m);
1673                         break;
1674
1675                 case FD_BUS:
1676                         bus_loop_dispatch(m->bus_fd);
1677                         break;
1678
1679                 default:
1680                         if (event.data.u32 >= FD_OTHER_BASE)
1681                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1682                 }
1683         }
1684
1685         return 0;
1686 }
1687
1688 static int manager_parse_config_file(Manager *m) {
1689         FILE *f;
1690         const char *fn;
1691         int r;
1692
1693         assert(m);
1694
1695         fn = "/etc/systemd/logind.conf";
1696         f = fopen(fn, "re");
1697         if (!f) {
1698                 if (errno == ENOENT)
1699                         return 0;
1700
1701                 log_warning("Failed to open configuration file %s: %m", fn);
1702                 return -errno;
1703         }
1704
1705         r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
1706         if (r < 0)
1707                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1708
1709         fclose(f);
1710
1711         return r;
1712 }
1713
1714 int main(int argc, char *argv[]) {
1715         Manager *m = NULL;
1716         int r;
1717
1718         log_set_target(LOG_TARGET_AUTO);
1719         log_set_facility(LOG_AUTH);
1720         log_parse_environment();
1721         log_open();
1722
1723         umask(0022);
1724
1725         if (argc != 1) {
1726                 log_error("This program takes no arguments.");
1727                 r = -EINVAL;
1728                 goto finish;
1729         }
1730
1731         /* Always create the directories people can create inotify
1732          * watches in. Note that some applications might check for the
1733          * existance of /run/systemd/seats/ to determine whether
1734          * logind is available, so please always make sure this check
1735          * stays in. */
1736         mkdir_label("/run/systemd/seats", 0755);
1737         mkdir_label("/run/systemd/users", 0755);
1738         mkdir_label("/run/systemd/sessions", 0755);
1739
1740         m = manager_new();
1741         if (!m) {
1742                 r = log_oom();
1743                 goto finish;
1744         }
1745
1746         manager_parse_config_file(m);
1747
1748         r = manager_startup(m);
1749         if (r < 0) {
1750                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1751                 goto finish;
1752         }
1753
1754         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1755
1756         sd_notify(false,
1757                   "READY=1\n"
1758                   "STATUS=Processing requests...");
1759
1760         r = manager_run(m);
1761
1762         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1763
1764 finish:
1765         sd_notify(false,
1766                   "STATUS=Shutting down...");
1767
1768         if (m)
1769                 manager_free(m);
1770
1771         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1772 }