X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=c20a82b8b45ad0c2938f1613341993418f711719;hb=58684be9a781be9797142bce442bbac6fb6a7738;hp=2022f13233c55f34b8873d60b1ecaff9ef55e2d9;hpb=4f8f66cb4236783cd3cbee97fefc9aaa8469ac08;p=elogind.git diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 2022f1323..c20a82b8b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3678,6 +3678,7 @@ static int get_unit_dbus_path_by_pid( _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + char *u; int r; r = sd_bus_call_method( @@ -3694,10 +3695,15 @@ static int get_unit_dbus_path_by_pid( return r; } - r = sd_bus_message_read(reply, "o", unit); + r = sd_bus_message_read(reply, "o", &u); if (r < 0) return bus_log_parse_error(r); + u = strdup(u); + if (!u) + return log_oom(); + + *unit = u; return 0; } @@ -3743,10 +3749,10 @@ static int show_all( } static int cat(sd_bus *bus, char **args) { + _cleanup_free_ char *unit = NULL, *n = NULL; int r = 0; char **name; - - _cleanup_free_ char *unit = NULL, *n = NULL; + bool first = true; assert(bus); assert(args); @@ -3754,9 +3760,9 @@ static int cat(sd_bus *bus, char **args) { pager_open_if_enabled(); STRV_FOREACH(name, args+1) { - _cleanup_free_ char *fragment_path = NULL; + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_strv_free_ char **dropin_paths = NULL; - sd_bus_error error; + _cleanup_free_ char *fragment_path = NULL; char **path; n = unit_name_mangle(*name); @@ -3797,9 +3803,18 @@ static int cat(sd_bus *bus, char **args) { continue; } + if (first) + first = false; + else + puts(""); + if (!isempty(fragment_path)) { - fprintf(stdout, "# %s\n", fragment_path); + printf("%s# %s%s\n", + ansi_highlight_blue(), + fragment_path, + ansi_highlight_off()); fflush(stdout); + r = sendfile_full(STDOUT_FILENO, fragment_path); if (r < 0) { log_warning("Failed to cat %s: %s", fragment_path, strerror(-r)); @@ -3808,10 +3823,13 @@ static int cat(sd_bus *bus, char **args) { } STRV_FOREACH(path, dropin_paths) { - fprintf(stdout, "%s# %s\n", - isempty(fragment_path) && path == dropin_paths ? "" : "\n", - *path); + printf("%s%s# %s%s\n", + isempty(fragment_path) && path == dropin_paths ? "" : "\n", + ansi_highlight_blue(), + *path, + ansi_highlight_off()); fflush(stdout); + r = sendfile_full(STDOUT_FILENO, *path); if (r < 0) { log_warning("Failed to cat %s: %s", *path, strerror(-r)); @@ -3820,7 +3838,7 @@ static int cat(sd_bus *bus, char **args) { } } - return r; + return r < 0 ? r : 0; } static int show(sd_bus *bus, char **args) { @@ -3870,8 +3888,10 @@ static int show(sd_bus *bus, char **args) { } else { /* Interpret as PID */ r = get_unit_dbus_path_by_pid(bus, id, &unit); - if (r < 0) + if (r < 0) { ret = r; + continue; + } } show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized); @@ -4766,7 +4786,7 @@ static int unit_is_enabled(sd_bus *bus, char **args) { "GetUnitFileState", &error, &reply, - "s", name); + "s", *name); if (r < 0) { log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r)); return r; @@ -4834,7 +4854,8 @@ static int systemctl_help(void) { " --root=PATH Enable unit files in the specified root directory\n" " -n --lines=INTEGER Number of journal entries to show\n" " -o --output=STRING Change journal output mode (short, short-monotonic,\n" - " verbose, export, json, json-pretty, json-sse, cat)\n\n" + " verbose, export, json, json-pretty, json-sse, cat)\n" + " --plain Print unit dependencies as a list instead of a tree\n\n" "Unit Commands:\n" " list-units [PATTERN...] List loaded units\n" " list-sockets [PATTERN...] List loaded sockets ordered by address\n" @@ -5813,9 +5834,13 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { } argc_cmp; const int argc; int (* const dispatch)(sd_bus *bus, char **args); + const enum { + NOBUS = 1, + FORCE, + } bus; } verbs[] = { { "list-units", MORE, 0, list_units }, - { "list-unit-files", MORE, 1, list_unit_files }, + { "list-unit-files", MORE, 1, list_unit_files, NOBUS }, { "list-sockets", MORE, 1, list_sockets }, { "list-timers", MORE, 1, list_timers }, { "list-jobs", MORE, 1, list_jobs }, @@ -5848,9 +5873,9 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "show-environment", EQUAL, 1, show_environment }, { "set-environment", MORE, 2, set_environment }, { "unset-environment", MORE, 2, set_environment }, - { "halt", EQUAL, 1, start_special }, - { "poweroff", EQUAL, 1, start_special }, - { "reboot", EQUAL, 1, start_special }, + { "halt", EQUAL, 1, start_special, FORCE }, + { "poweroff", EQUAL, 1, start_special, FORCE }, + { "reboot", EQUAL, 1, start_special, FORCE }, { "kexec", EQUAL, 1, start_special }, { "suspend", EQUAL, 1, start_special }, { "hibernate", EQUAL, 1, start_special }, @@ -5860,53 +5885,50 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "emergency", EQUAL, 1, start_special }, { "exit", EQUAL, 1, start_special }, { "reset-failed", MORE, 1, reset_failed }, - { "enable", MORE, 2, enable_unit }, - { "disable", MORE, 2, enable_unit }, - { "is-enabled", MORE, 2, unit_is_enabled }, - { "reenable", MORE, 2, enable_unit }, - { "preset", MORE, 2, enable_unit }, - { "mask", MORE, 2, enable_unit }, - { "unmask", MORE, 2, enable_unit }, - { "link", MORE, 2, enable_unit }, + { "enable", MORE, 2, enable_unit, NOBUS }, + { "disable", MORE, 2, enable_unit, NOBUS }, + { "is-enabled", MORE, 2, unit_is_enabled, NOBUS }, + { "reenable", MORE, 2, enable_unit, NOBUS }, + { "preset", MORE, 2, enable_unit, NOBUS }, + { "mask", MORE, 2, enable_unit, NOBUS }, + { "unmask", MORE, 2, enable_unit, NOBUS }, + { "link", MORE, 2, enable_unit, NOBUS }, { "switch-root", MORE, 2, switch_root }, { "list-dependencies", LESS, 2, list_dependencies }, - { "set-default", EQUAL, 2, set_default }, - { "get-default", EQUAL, 1, get_default }, + { "set-default", EQUAL, 2, set_default, NOBUS }, + { "get-default", EQUAL, 1, get_default, NOBUS }, { "set-property", MORE, 3, set_property }, - }; + {} + }, *verb = verbs; int left; - unsigned i; assert(argc >= 0); assert(argv); left = argc - optind; - if (left <= 0) - /* Special rule: no arguments means "list-units" */ - i = 0; - else { + /* Special rule: no arguments (left == 0) means "list-units" */ + if (left > 0) { if (streq(argv[optind], "help") && !argv[optind+1]) { log_error("This command expects one or more " "unit names. Did you mean --help?"); return -EINVAL; } - for (i = 0; i < ELEMENTSOF(verbs); i++) - if (streq(argv[optind], verbs[i].verb)) - break; + for (; verb->verb; verb++) + if (streq(argv[optind], verb->verb)) + goto found; - if (i >= ELEMENTSOF(verbs)) { - log_error("Unknown operation '%s'.", argv[optind]); - return -EINVAL; - } + log_error("Unknown operation '%s'.", argv[optind]); + return -EINVAL; } +found: - switch (verbs[i].argc_cmp) { + switch (verb->argc_cmp) { case EQUAL: - if (left != verbs[i].argc) { + if (left != verb->argc) { log_error("Invalid number of arguments."); return -EINVAL; } @@ -5914,7 +5936,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { break; case MORE: - if (left < verbs[i].argc) { + if (left < verb->argc) { log_error("Too few arguments."); return -EINVAL; } @@ -5922,7 +5944,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { break; case LESS: - if (left > verbs[i].argc) { + if (left > verb->argc) { log_error("Too many arguments."); return -EINVAL; } @@ -5935,39 +5957,25 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { /* Require a bus connection for all operations but * enable/disable */ - if (!streq(verbs[i].verb, "enable") && - !streq(verbs[i].verb, "disable") && - !streq(verbs[i].verb, "is-enabled") && - !streq(verbs[i].verb, "list-unit-files") && - !streq(verbs[i].verb, "reenable") && - !streq(verbs[i].verb, "preset") && - !streq(verbs[i].verb, "mask") && - !streq(verbs[i].verb, "unmask") && - !streq(verbs[i].verb, "link") && - !streq(verbs[i].verb, "set-default") && - !streq(verbs[i].verb, "get-default")) { + if (verb->bus == NOBUS) { + if (!bus && !avoid_bus()) { + log_error("Failed to get D-Bus connection: %s", strerror(-bus_error)); + return -EIO; + } + } else { if (running_in_chroot() > 0) { log_info("Running in chroot, ignoring request."); return 0; } - if (((!streq(verbs[i].verb, "reboot") && - !streq(verbs[i].verb, "halt") && - !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) { - log_error("Failed to get D-Bus connection: %s", strerror (-bus_error)); - return -EIO; - } - - } else { - - if (!bus && !avoid_bus()) { - log_error("Failed to get D-Bus connection: %s", strerror (-bus_error)); + if ((verb->bus != FORCE || arg_force <= 0) && !bus) { + log_error("Failed to get D-Bus connection: %s", strerror(-bus_error)); return -EIO; } } - return verbs[i].dispatch(bus, argv + optind); + return verb->dispatch(bus, argv + optind); } static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {