X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=f7b2fb40190e61bc0ee73c3f36723e2d463a1450;hb=e93c33d4aa;hp=23399c16c63cc38383e4402dec3820baabad185c;hpb=4dc5b821ae737914499119e29811fc3346e3d97c;p=elogind.git diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 23399c16c..f7b2fb401 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3604,16 +3604,13 @@ static int show_one( return r; } -static int show_one_by_pid( - const char *verb, +static int get_unit_dbus_path_by_pid( sd_bus *bus, uint32_t pid, - bool *new_line, - bool *ellipsized) { + char **unit) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - const char *path = NULL; int r; r = sd_bus_call_method( @@ -3630,11 +3627,11 @@ static int show_one_by_pid( return r; } - r = sd_bus_message_read(reply, "o", &path); + r = sd_bus_message_read(reply, "o", unit); if (r < 0) return bus_log_parse_error(r); - return show_one(verb, bus, path, false, new_line, ellipsized); + return 0; } static int show_all( @@ -3678,6 +3675,107 @@ static int show_all( return 0; } +static int cat(sd_bus *bus, char **args) { + int r = 0; + char **name; + + _cleanup_free_ char *unit = NULL, *n = NULL; + + assert(bus); + assert(args); + + pager_open_if_enabled(); + + STRV_FOREACH(name, args+1) { + _cleanup_free_ char *fragment_path = NULL; + _cleanup_strv_free_ char **dropin_paths = NULL; + sd_bus_error error; + FILE *stdout; + char **path; + + n = unit_name_mangle(*name); + if (!n) + return log_oom(); + + unit = unit_dbus_path_from_name(n); + if (!unit) + return log_oom(); + + if (need_daemon_reload(bus, n) > 0) + log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.", + n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user"); + + r = sd_bus_get_property_string( + bus, + "org.freedesktop.systemd1", + unit, + "org.freedesktop.systemd1.Unit", + "FragmentPath", + &error, + &fragment_path); + if (r < 0) { + log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r)); + continue; + } + + if (isempty(fragment_path)) { + free(fragment_path); + fragment_path = NULL; + + if (sd_bus_get_property_string( + bus, + "org.freedesktop.systemd1", + unit, + "org.freedesktop.systemd1.Unit", + "SourcePath", + &error, + &fragment_path) < 0) { + log_warning("Failed to get SourcePath: %s", bus_error_message(&error, r)); + continue; + } + } + + r = sd_bus_get_property_strv( + bus, + "org.freedesktop.systemd1", + unit, + "org.freedesktop.systemd1.Unit", + "DropInPaths", + &error, + &dropin_paths); + if (r < 0) { + log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r)); + continue; + } + + stdout = fdopen(STDOUT_FILENO, "a"); + + if (!isempty(fragment_path)) { + fprintf(stdout, "# %s\n", fragment_path); + fflush(stdout); + r = sendfile_full(STDOUT_FILENO, fragment_path); + if (r < 0) { + log_warning("Failed to cat %s: %s", fragment_path, strerror(-r)); + continue; + } + } + + STRV_FOREACH(path, dropin_paths) { + fprintf(stdout, "%s# %s\n", + isempty(fragment_path) && path == dropin_paths ? "" : "\n", + *path); + fflush(stdout); + r = sendfile_full(STDOUT_FILENO, *path); + if (r < 0) { + log_warning("Failed to cat %s: %s", *path, strerror(-r)); + continue; + } + } + } + + return r; +} + static int show(sd_bus *bus, char **args) { int r, ret = 0; bool show_properties, show_status, new_line = false; @@ -3702,41 +3800,34 @@ static int show(sd_bus *bus, char **args) { ret = show_all(args[0], bus, false, &new_line, &ellipsized); else STRV_FOREACH(name, args+1) { + _cleanup_free_ char *unit = NULL; uint32_t id; if (safe_atou32(*name, &id) < 0) { - _cleanup_free_ char *p = NULL, *n = NULL; + _cleanup_free_ char *n = NULL; /* Interpret as unit name */ n = unit_name_mangle(*name); if (!n) return log_oom(); - p = unit_dbus_path_from_name(n); - if (!p) + unit = unit_dbus_path_from_name(n); + if (!unit) return log_oom(); - r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized); - if (r != 0) - ret = r; - } else if (show_properties) { - _cleanup_free_ char *p = NULL; - /* Interpret as job id */ - if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) + if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0) return log_oom(); - r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized); - if (r != 0) - ret = r; - } else { /* Interpret as PID */ - r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized); - if (r != 0) + r = get_unit_dbus_path_by_pid(bus, id, &unit); + if (r < 0) ret = r; } + + show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized); } if (ellipsized && !arg_quiet) @@ -4549,7 +4640,7 @@ static int enable_unit(sd_bus *bus, char **args) { return bus_log_parse_error(r); } - r = deserialize_and_dump_unit_file_changes(m); + r = deserialize_and_dump_unit_file_changes(reply); if (r < 0) return r; @@ -4717,6 +4808,7 @@ static int systemctl_help(void) { " status [NAME...|PID...] Show runtime status of one or more units\n" " show [NAME...|JOB...] Show properties of one or more\n" " units/jobs or the manager\n" + " cat [NAME...] Show files and drop-ins of one or more units\n" " set-property [NAME] [ASSIGNMENT...]\n" " Sets one or more properties of a unit\n" " help [NAME...|PID...] Show manual for one or more units\n" @@ -5700,6 +5792,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "check", MORE, 2, check_unit_active }, { "is-failed", MORE, 2, check_unit_failed }, { "show", MORE, 1, show }, + { "cat", MORE, 2, cat }, { "status", MORE, 1, show }, { "help", MORE, 2, show }, { "snapshot", LESS, 2, snapshot },