chiark / gitweb /
logind: avoid creating stale session state files
[elogind.git] / src / login / logind-dbus.c
index 1dcdf04b2925462169d126a9d3a4ec7f87b75221..230dd2b4b5e9ac2f329a0de281cb30f1d439a214 100644 (file)
@@ -319,7 +319,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         int r;
         uint32_t vtnr = 0;
         _cleanup_close_ int fifo_fd = -1;
-        DBusMessage *reply = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         Session *session = NULL;
         User *user = NULL;
         Seat *seat = NULL;
@@ -353,21 +353,28 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
                 return -EINVAL;
 
         dbus_message_iter_get_basic(&iter, &type);
-        t = session_type_from_string(type);
+        if (isempty(type))
+                t = _SESSION_TYPE_INVALID;
+        else {
+                t = session_type_from_string(type);
+                if (t < 0)
+                        return -EINVAL;
+        }
 
-        if (t < 0 ||
-            !dbus_message_iter_next(&iter) ||
+        if (!dbus_message_iter_next(&iter) ||
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
                 return -EINVAL;
 
         dbus_message_iter_get_basic(&iter, &class);
         if (isempty(class))
-                c = SESSION_USER;
-        else
+                c = _SESSION_CLASS_INVALID;
+        else {
                 c = session_class_from_string(class);
+                if (c < 0)
+                        return -EINVAL;
+        }
 
-        if (c < 0 ||
-            !dbus_message_iter_next(&iter) ||
+        if (!dbus_message_iter_next(&iter) ||
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
                 return -EINVAL;
 
@@ -441,6 +448,22 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
                 return -EINVAL;
 
+        if (t == _SESSION_TYPE_INVALID) {
+                if (!isempty(display))
+                        t = SESSION_X11;
+                else if (!isempty(tty))
+                        t = SESSION_TTY;
+                else
+                        t = SESSION_UNSPECIFIED;
+        }
+
+        if (c == _SESSION_CLASS_INVALID) {
+                if (!isempty(display) || !isempty(tty))
+                        c = SESSION_USER;
+                else
+                        c = SESSION_BACKGROUND;
+        }
+
         dbus_message_iter_get_basic(&iter, &remote);
 
         if (!dbus_message_iter_next(&iter) ||
@@ -536,6 +559,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
                 }
 
                 *_reply = reply;
+                reply = NULL;
 
                 return 0;
         }
@@ -681,6 +705,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         }
 
         *_reply = reply;
+        reply = NULL;
 
         return 0;
 
@@ -691,9 +716,6 @@ fail:
         if (user)
                 user_add_to_gc_queue(user);
 
-        if (reply)
-                dbus_message_unref(reply);
-
         return r;
 }
 
@@ -712,7 +734,7 @@ static int bus_manager_inhibit(
         InhibitMode mm;
         unsigned long ul;
         int r, fifo_fd = -1;
-        DBusMessage *reply = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
 
         assert(m);
         assert(connection);
@@ -833,6 +855,7 @@ static int bus_manager_inhibit(
 
         close_nointr_nofail(fifo_fd);
         *_reply = reply;
+        reply = NULL;
 
         inhibitor_start(i);
 
@@ -845,9 +868,6 @@ fail:
         if (fifo_fd >= 0)
                 close_nointr_nofail(fifo_fd);
 
-        if (reply)
-                dbus_message_unref(reply);
-
         return r;
 }
 
@@ -889,7 +909,7 @@ static int trigger_device(Manager *m, struct udev_device *d) {
                         goto finish;
                 }
 
-                write_one_line_file(t, "change");
+                write_string_file(t, "change");
                 free(t);
         }
 
@@ -904,7 +924,7 @@ finish:
 
 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
         struct udev_device *d;
-        char *rule = NULL, *file = NULL;
+        char _cleanup_free_ *rule = NULL, *file = NULL;
         const char *id_for_seat;
         int r;
 
@@ -939,16 +959,13 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs) {
 
         mkdir_p_label("/etc/udev/rules.d", 0755);
         label_init("/etc");
-        r = write_one_line_file_atomic_label(file, rule);
+        r = write_string_file_atomic_label(file, rule);
         if (r < 0)
                 goto finish;
 
         r = trigger_device(m, d);
 
 finish:
-        free(rule);
-        free(file);
-
         if (d)
                 udev_device_unref(d);
 
@@ -956,7 +973,7 @@ finish:
 }
 
 static int flush_devices(Manager *m) {
-        DIR *d;
+        DIR _cleanup_closedir_ *d;
 
         assert(m);
 
@@ -981,8 +998,6 @@ static int flush_devices(Manager *m) {
                         if (unlinkat(dirfd(d), de->d_name, 0) < 0)
                                 log_warning("Failed to unlink %s: %m", de->d_name);
                 }
-
-                closedir(d);
         }
 
         return trigger_device(m, NULL);
@@ -1001,7 +1016,6 @@ static int have_multiple_sessions(
          * count, and non-login sessions do not count either. */
         HASHMAP_FOREACH(session, m->sessions, i)
                 if (session->class == SESSION_USER &&
-                    (session->type == SESSION_TTY || session->type == SESSION_X11) &&
                     session->user->uid != uid)
                         return true;
 
@@ -1126,7 +1140,7 @@ static int bus_manager_can_shutdown_or_sleep(
 
         bool multiple_sessions, challenge, blocked, b;
         const char *result;
-        DBusMessage *reply = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         int r;
         unsigned long ul;
 
@@ -1225,12 +1239,11 @@ finish:
                         reply,
                         DBUS_TYPE_STRING, &result,
                         DBUS_TYPE_INVALID);
-        if (!b) {
-                dbus_message_unref(reply);
+        if (!b)
                 return -ENOMEM;
-        }
 
         *_reply = reply;
+        reply = NULL;
         return 0;
 }
 
@@ -1430,7 +1443,7 @@ static DBusHandlerResult manager_message_handler(
         Manager *m = userdata;
 
         DBusError error;
-        DBusMessage *reply = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         int r;
 
         assert(connection);
@@ -2338,16 +2351,11 @@ static DBusHandlerResult manager_message_handler(
         if (reply) {
                 if (!bus_maybe_send_reply(connection, message, reply))
                                 goto oom;
-
-                dbus_message_unref(reply);
         }
 
         return DBUS_HANDLER_RESULT_HANDLED;
 
 oom:
-        if (reply)
-                dbus_message_unref(reply);
-
         dbus_error_free(&error);
 
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -2413,25 +2421,20 @@ DBusHandlerResult bus_message_filter(
 }
 
 int manager_send_changed(Manager *manager, const char *properties) {
-        DBusMessage *m;
-        int r = -ENOMEM;
+        _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
 
         assert(manager);
 
-        m = bus_properties_changed_new("/org/freedesktop/login1", "org.freedesktop.login1.Manager", properties);
+        m = bus_properties_changed_new("/org/freedesktop/login1",
+                                       "org.freedesktop.login1.Manager",
+                                       properties);
         if (!m)
-                goto finish;
+                return -ENOMEM;
 
         if (!dbus_connection_send(manager->bus, m, NULL))
-                goto finish;
-
-        r = 0;
-
-finish:
-        if (m)
-                dbus_message_unref(m);
+                return -ENOMEM;
 
-        return r;
+        return 0;
 }
 
 int manager_dispatch_delayed(Manager *manager) {