/* 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);
uint32_t u;
dbus_message_iter_get_basic(iter, &u);
- if (strstr(name, "UMask"))
+ if (strstr(name, "UMask") || strstr(name, "Mode"))
printf("%s=%04o\n", name, u);
else
printf("%s=%u\n", name, (unsigned) u);
}
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;
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);
}
"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"
" 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"