chiark / gitweb /
turn negative options into positive options
[elogind.git] / src / systemctl.c
index 66d6ef038b77ffdcd1efdec979053c2da9caa9d8..1ad0c48a89f8eef669ab8867960295d2b2373955 100644 (file)
@@ -583,13 +583,10 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me
 
 static int enable_wait_for_jobs(DBusConnection *bus) {
         DBusError error;
-        DBusMessage *m = NULL, *reply = NULL;
-        int r;
 
         assert(bus);
 
         dbus_error_init(&error);
-
         dbus_bus_add_match(bus,
                            "type='signal',"
                            "sender='org.freedesktop.systemd1',"
@@ -600,40 +597,12 @@ static int enable_wait_for_jobs(DBusConnection *bus) {
 
         if (dbus_error_is_set(&error)) {
                 log_error("Failed to add match: %s", error.message);
-                r = -EIO;
-                goto finish;
-        }
-
-        if (!(m = dbus_message_new_method_call(
-                              "org.freedesktop.systemd1",
-                              "/org/freedesktop/systemd1",
-                              "org.freedesktop.systemd1.Manager",
-                              "Subscribe"))) {
-                log_error("Could not allocate message.");
-                r = -ENOMEM;
-                goto finish;
-        }
-
-        if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
-                log_error("Failed to issue method call: %s", error.message);
-                r = -EIO;
-                goto finish;
+                dbus_error_free(&error);
+                return -EIO;
         }
 
-        r = 0;
-
-finish:
         /* This is slightly dirty, since we don't undo the match registrations. */
-
-        if (m)
-                dbus_message_unref(m);
-
-        if (reply)
-                dbus_message_unref(reply);
-
-        dbus_error_free(&error);
-
-        return r;
+        return 0;
 }
 
 static int wait_for_jobs(DBusConnection *bus, Set *s) {
@@ -1024,11 +993,15 @@ static int print_property(const char *name, DBusMessageIter *iter) {
                 /* Yes, heuristics! But we can change this check
                  * should it turn out to not be sufficient */
 
-                if (strstr(name, "Timestamp") || strstr(name, "Elapse")) {
+                if (strstr(name, "Timestamp")) {
                         char timestamp[FORMAT_TIMESTAMP_MAX], *t;
 
                         if ((t = format_timestamp(timestamp, sizeof(timestamp), u)) || arg_all)
                                 printf("%s=%s\n", name, strempty(t));
+                } else if (strstr(name, "USec")) {
+                        char timespan[FORMAT_TIMESPAN_MAX];
+
+                        printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u));
                 } else
                         printf("%s=%llu\n", name, (unsigned long long) u);
 
@@ -1111,7 +1084,29 @@ static int print_property(const char *name, DBusMessageIter *iter) {
                         }
 
                         return 0;
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_BYTE) {
+                        DBusMessageIter sub;
+
+                        dbus_message_iter_recurse(iter, &sub);
 
+                        if (arg_all ||
+                            dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                printf("%s=", name);
+
+                                while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+                                        uint8_t u;
+
+                                        assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE);
+                                        dbus_message_iter_get_basic(&sub, &u);
+                                        printf("%02x", u);
+
+                                        dbus_message_iter_next(&sub);
+                                }
+
+                                puts("");
+                        }
+
+                        return 0;
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) {
                         DBusMessageIter sub, sub2;
 
@@ -1143,8 +1138,72 @@ static int print_property(const char *name, DBusMessageIter *iter) {
 
                                 if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 &&
                                     bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 &&
-                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0)
-                                        printf("%s=%llu\n", base, (unsigned long long) value);
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0) {
+                                        char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
+
+                                        printf("%s={ value=%s ; next_elapse=%s }\n",
+                                               base,
+                                               format_timespan(timespan1, sizeof(timespan1), value),
+                                               format_timespan(timespan2, sizeof(timespan2), next_elapse));
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) {
+
+                        DBusMessageIter sub, sub2, sub3;
+
+                        dbus_message_iter_recurse(iter, &sub);
+
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *path;
+                                uint64_t start_time, exit_time;
+                                uint32_t pid;
+                                int32_t code, status;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0)
+                                        continue;
+
+                                if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY ||
+                                    dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING)
+                                        continue;
+
+                                printf("%s={ path=%s ; argv[]=", name, path);
+
+                                dbus_message_iter_recurse(&sub2, &sub3);
+
+                                while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) {
+                                        const char *s;
+
+                                        assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING);
+                                        dbus_message_iter_get_basic(&sub3, &s);
+                                        printf("%s ", s);
+                                        dbus_message_iter_next(&sub3);
+                                }
+
+                                if (dbus_message_iter_next(&sub2) &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_time, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_time, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) >= 0) {
+
+                                        char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
+
+                                        printf("; start=%s ; stop=%s ; pid=%u ; code=%s ; status=%i/%s",
+                                               strna(format_timestamp(timestamp1, sizeof(timestamp1), start_time)),
+                                               strna(format_timestamp(timestamp2, sizeof(timestamp2), exit_time)),
+                                               (unsigned) pid,
+                                               sigchld_code_to_string(code),
+                                               status,
+                                               strna(code == CLD_EXITED ? NULL : strsignal(status)));
+                                }
+
+                                printf(" }\n");
 
                                 dbus_message_iter_next(&sub);
                         }
@@ -2023,7 +2082,7 @@ static int systemctl_help(void) {
                "Send control commands to the systemd manager.\n\n"
                "  -h --help          Show this help\n"
                "  -t --type=TYPE     List only units of a particular type\n"
-               "  -p --property=NAME Show only property by this name\n"
+               "  -p --property=NAME Show only properties by this name\n"
                "  -a --all           Show all units/properties, including dead/empty ones\n"
                "     --replace       When installing a new job, replace existing conflicting ones\n"
                "     --system        Connect to system bus\n"
@@ -2039,7 +2098,7 @@ static int systemctl_help(void) {
                "  reload [NAME...]                Reload one or more units\n"
                "  isolate [NAME]                  Start one unit and stop all others\n"
                "  check [NAME...]                 Check whether any of the passed units are active\n"
-               "  show [NAME...|JOB...]           Show information about one or more units\n"
+               "  show [NAME...|JOB...]           Show information about one or more units/jobs/manager\n"
                "  load [NAME...]                  Load one or more units\n"
                "  list-jobs                       List jobs\n"
                "  cancel [JOB...]                 Cancel one or more jobs\n"