#include "logs-show.h"
#include "path-util.h"
#include "socket-util.h"
+#include "fileio.h"
static const char *arg_type = NULL;
static const char *arg_load_state = NULL;
ACTION_CANCEL_SHUTDOWN,
_ACTION_MAX
} arg_action = ACTION_SYSTEMCTL;
-static enum dot {
- DOT_ALL,
- DOT_ORDER,
- DOT_REQUIRE
-} arg_dot = DOT_ALL;
static enum transport {
TRANSPORT_NORMAL,
TRANSPORT_SSH,
id_len = max_id_len;
for (u = unit_infos; u < unit_infos + c; u++) {
- char *e;
+ char _cleanup_free_ *e = NULL;
const char *on_loaded, *off_loaded;
const char *on_active, *off_active;
printf("%.*s\n", desc_len, u->description);
else
printf("%s\n", u->description);
-
- free(e);
}
if (!arg_no_legend) {
printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE");
for (u = units; u < units + c; u++) {
- char *e;
+ char _cleanup_free_ *e = NULL;
const char *on, *off;
const char *id;
printf("%-*s %s%-*s%s\n",
id_cols, e ? e : id,
on, state_cols, unit_file_state_to_string(u->state), off);
-
- free(e);
}
if (!arg_no_legend)
}
static int list_dependencies_one(DBusConnection *bus, const char *name, int level, char **units, unsigned int branches) {
- char **deps = NULL;
+ char _cleanup_strv_free_ **deps = NULL, **u;
char **c;
- char **u = NULL;
int r = 0;
u = strv_append(units, name);
- if(!u)
+ if (!u)
return log_oom();
r = list_dependencies_get_dependencies(bus, name, &deps);
if (r < 0)
- goto finish;
+ return r;
qsort(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
STRV_FOREACH(c, deps) {
if (strv_contains(u, *c)) {
r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
- if(r < 0)
- goto finish;
+ if (r < 0)
+ return r;
continue;
}
r = list_dependencies_print(*c, level, branches, c[1] == NULL);
- if(r < 0)
- goto finish;
+ if (r < 0)
+ return r;
if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
r = list_dependencies_one(bus, *c, level + 1, u, (branches << 1) | (c[1] == NULL ? 0 : 1));
if(r < 0)
- goto finish;
+ return r;
}
}
- r = 0;
-finish:
- strv_free(deps);
- strv_free(u);
- return r;
+ return 0;
}
static int list_dependencies(DBusConnection *bus, char **args) {
return list_dependencies_one(bus, u, 0, NULL, 0);
}
-static int dot_one_property(const char *name, const char *prop, DBusMessageIter *iter) {
-
- static const char * const colors[] = {
- "Requires", "[color=\"black\"]",
- "RequiresOverridable", "[color=\"black\"]",
- "Requisite", "[color=\"darkblue\"]",
- "RequisiteOverridable", "[color=\"darkblue\"]",
- "Wants", "[color=\"grey66\"]",
- "Conflicts", "[color=\"red\"]",
- "ConflictedBy", "[color=\"red\"]",
- "After", "[color=\"green\"]"
- };
-
- const char *c = NULL;
- unsigned i;
-
- assert(name);
- assert(prop);
- assert(iter);
-
- for (i = 0; i < ELEMENTSOF(colors); i += 2)
- if (streq(colors[i], prop)) {
- c = colors[i+1];
- break;
- }
-
- if (!c)
- return 0;
-
- if (arg_dot != DOT_ALL)
- if ((arg_dot == DOT_ORDER) != streq(prop, "After"))
- return 0;
-
- switch (dbus_message_iter_get_arg_type(iter)) {
-
- case DBUS_TYPE_ARRAY:
-
- if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) {
- DBusMessageIter sub;
-
- dbus_message_iter_recurse(iter, &sub);
-
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- const char *s;
-
- assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
- dbus_message_iter_get_basic(&sub, &s);
- printf("\t\"%s\"->\"%s\" %s;\n", name, s, c);
-
- dbus_message_iter_next(&sub);
- }
-
- return 0;
- }
- }
-
- return 0;
-}
-
-static int dot_one(DBusConnection *bus, const struct unit_info *u) {
- _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- const char *interface = "org.freedesktop.systemd1.Unit";
- int r;
- DBusMessageIter iter, sub, sub2, sub3;
-
- assert(bus);
- assert(u);
-
- r = bus_method_call_with_reply(
- bus,
- "org.freedesktop.systemd1",
- u->unit_path,
- "org.freedesktop.DBus.Properties",
- "GetAll",
- &reply,
- NULL,
- DBUS_TYPE_STRING, &interface,
- DBUS_TYPE_INVALID);
- if (r < 0)
- return r;
-
- if (!dbus_message_iter_init(reply, &iter) ||
- dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- dbus_message_iter_recurse(&iter, &sub);
-
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- const char *prop;
-
- assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY);
- dbus_message_iter_recurse(&sub, &sub2);
-
- if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &prop, true) < 0 ||
- dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- dbus_message_iter_recurse(&sub2, &sub3);
- r = dot_one_property(u->id, prop, &sub3);
- if (r < 0)
- return r;
-
- dbus_message_iter_next(&sub);
- }
-
- return 0;
-}
-
-static int dot(DBusConnection *bus, char **args) {
- _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- DBusMessageIter iter, sub;
- int r;
-
- r = bus_method_call_with_reply(
- bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "ListUnits",
- &reply,
- NULL,
- DBUS_TYPE_INVALID);
- if (r < 0)
- return r;
-
- if (!dbus_message_iter_init(reply, &iter) ||
- dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- printf("digraph systemd {\n");
-
- dbus_message_iter_recurse(&iter, &sub);
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- struct unit_info u;
-
- r = bus_parse_unit_info(&sub, &u);
- if (r < 0)
- return -EIO;
-
- r = dot_one(bus, &u);
- if (r < 0)
- return r;
-
- /* printf("\t\"%s\";\n", u.id); */
- dbus_message_iter_next(&sub);
- }
-
- printf("}\n");
-
- log_info(" Color legend: black = Requires\n"
- " dark blue = Requisite\n"
- " dark grey = Wants\n"
- " red = Conflicts\n"
- " green = After\n");
-
- if (on_tty())
- log_notice("-- You probably want to process this output with graphviz' dot tool.\n"
- "-- Try a shell pipeline like 'systemctl dot | dot -Tsvg > systemd.svg'!\n");
-
- return 0;
-}
-
static int list_jobs(DBusConnection *bus, char **args) {
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
DBusMessageIter iter, sub, sub2;
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
const char *name, *type, *state, *job_path, *unit_path;
uint32_t id;
- char *e;
+ char _cleanup_free_ *e = NULL;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
log_error("Failed to parse reply.");
e = arg_full ? NULL : ellipsize(name, 25, 33);
printf("%4u %-25s %-15s %-7s\n", id, e ? e : name, type, state);
- free(e);
k++;
} WaitData;
static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *message, void *data) {
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
WaitData *d = data;
+ dbus_error_init(&error);
+
assert(connection);
assert(message);
assert(d);
- dbus_error_init(&error);
-
log_debug("Got D-Bus request: %s.%s() on %s",
dbus_message_get_interface(message),
dbus_message_get_member(message),
if (!isempty(unit))
d->name = strdup(unit);
- goto finish;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
#ifndef LEGACY
dbus_error_free(&error);
if (*result)
d->result = strdup(result);
- goto finish;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
#endif
log_error("Failed to parse message: %s", bus_error_message(&error));
}
-finish:
- dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
int r, ret = 0;
const char *method, *mode, *one_name;
- Set *s = NULL;
- DBusError error;
+ Set _cleanup_set_free_free_ *s = NULL;
+ DBusError _cleanup_dbus_error_free_ error;
char **name;
dbus_error_init(&error);
ret = enable_wait_for_jobs(bus);
if (ret < 0) {
log_error("Could not watch jobs: %s", strerror(-ret));
- goto finish;
+ return ret;
}
s = set_new(string_hash_func, string_compare_func);
- if (!s) {
- ret = log_oom();
- goto finish;
- }
+ if (!s)
+ return log_oom();
}
if (one_name) {
if (!arg_no_block) {
r = wait_for_jobs(bus, s);
- if (r < 0) {
- ret = r;
- goto finish;
- }
+ if (r < 0)
+ return r;
/* When stopping units, warn if they can still be triggered by
* another active unit (socket, path, timer) */
}
}
-finish:
- set_free_free(s);
- dbus_error_free(&error);
-
return ret;
}
if (startswith(*p, "man:")) {
size_t k;
char *e = NULL;
- char *page = NULL, *section = NULL;
+ char _cleanup_free_ *page = NULL, *section = NULL;
const char *args[4] = { "man", NULL, NULL, NULL };
pid_t pid;
if (e) {
page = strndup((*p) + 4, e - *p - 4);
- if (!page) {
- log_oom();
- return;
- }
-
section = strndup(e + 1, *p + k - e - 2);
- if (!section) {
- free(page);
+ if (!page || !section) {
log_oom();
return;
}
pid = fork();
if (pid < 0) {
log_error("Failed to fork: %m");
- free(page);
- free(section);
continue;
}
_exit(EXIT_FAILURE);
}
- free(page);
- free(section);
-
wait_for_terminate(pid, NULL);
} else
log_info("Can't show: %s", *p);
zero(info);
if (exec_status_info_deserialize(&sub, &info) >= 0) {
char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
- char *t;
+ char _cleanup_free_ *t;
t = strv_join(info.argv, " ");
info.status,
info.code == CLD_EXITED ? "" : "/",
strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
-
- free(t);
}
free(info.path);
static int show_one_by_pid(const char *verb, DBusConnection *bus, uint32_t pid, bool *new_line) {
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
const char *path = NULL;
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
int r;
dbus_error_init(&error);
DBUS_TYPE_UINT32, &pid,
DBUS_TYPE_INVALID);
if (r < 0)
- goto finish;
+ return r;
if (!dbus_message_get_args(reply, &error,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID)) {
log_error("Failed to parse reply: %s", bus_error_message(&error));
- r = -EIO;
- goto finish;
+ return -EIO;
}
r = show_one(verb, bus, path, false, new_line);
-
-finish:
- dbus_error_free(&error);
-
return r;
}
UnitFileChange *changes = NULL;
unsigned n_changes = 0, i;
int carries_install_info = -1;
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage _cleanup_dbus_message_unref_ *m = NULL, *reply = NULL;
int r;
- DBusError error;
- char **mangled_names = NULL;
+ DBusError _cleanup_dbus_error_free_ error;
+ char _cleanup_strv_free_ **mangled_names = NULL;
+
+ dbus_error_init(&error);
r = enable_sysv_units(args);
if (r < 0)
if (!args[1])
return 0;
- dbus_error_init(&error);
-
if (!bus || avoid_bus()) {
if (streq(verb, "enable")) {
r = unit_file_enable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
" D-Bus, udev, scripted systemctl call, ...).\n");
finish:
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
unit_file_changes_free(changes, n_changes);
- dbus_error_free(&error);
-
- strv_free(mangled_names);
-
return r;
}
static int unit_is_enabled(DBusConnection *bus, char **args) {
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
int r;
- DBusMessage *reply = NULL;
+ DBusMessage _cleanup_dbus_message_unref_ *reply = NULL;
bool enabled;
char **name;
UnitFileState state;
state = unit_file_get_state(arg_scope, arg_root, *name);
- if (state < 0) {
- r = state;
- goto finish;
- }
+ if (state < 0)
+ return state;
if (state == UNIT_FILE_ENABLED ||
state == UNIT_FILE_ENABLED_RUNTIME ||
DBUS_TYPE_STRING, name,
DBUS_TYPE_INVALID);
if (r)
- goto finish;
+ return r;
if (!dbus_message_get_args(reply, &error,
DBUS_TYPE_STRING, &s,
DBUS_TYPE_INVALID)) {
log_error("Failed to parse reply: %s", bus_error_message(&error));
- r = -EIO;
- goto finish;
+ return -EIO;
}
dbus_message_unref(reply);
}
}
- r = enabled ? 0 : 1;
-
-finish:
- if (reply)
- dbus_message_unref(reply);
-
- dbus_error_free(&error);
- return r;
+ return enabled ? 0 : 1;
}
static int systemctl_help(void) {
" --no-pager Do not pipe output into a pager\n"
" --no-ask-password\n"
" Do not ask for system passwords\n"
- " --order When generating graph for dot, show only order\n"
- " --require When generating graph for dot, show only requirement\n"
" --system Connect to system manager\n"
" --user Connect to user service manager\n"
" --global Enable/disable unit files globally\n"
" cancel [JOB...] Cancel all, one, or more jobs\n\n"
"Status Commands:\n"
" dump Dump server status\n"
- " dot Dump dependency graph for dot(1)\n\n"
"Snapshot Commands:\n"
" snapshot [NAME] Create a snapshot\n"
" delete [NAME...] Remove one or more snapshots\n\n"
ARG_NO_LEGEND,
ARG_NO_PAGER,
ARG_NO_WALL,
- ARG_ORDER,
- ARG_REQUIRE,
ARG_ROOT,
ARG_FULL,
ARG_NO_RELOAD,
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
{ "quiet", no_argument, NULL, 'q' },
- { "order", no_argument, NULL, ARG_ORDER },
- { "require", no_argument, NULL, ARG_REQUIRE },
{ "root", required_argument, NULL, ARG_ROOT },
{ "force", no_argument, NULL, ARG_FORCE },
{ "no-reload", no_argument, NULL, ARG_NO_RELOAD },
arg_no_wall = true;
break;
- case ARG_ORDER:
- arg_dot = DOT_ORDER;
- break;
-
- case ARG_REQUIRE:
- arg_dot = DOT_REQUIRE;
- break;
-
case ARG_ROOT:
arg_root = optarg;
break;
}
static int talk_upstart(void) {
- DBusMessage *m = NULL, *reply = NULL;
- DBusError error;
+ DBusMessage _cleanup_dbus_message_unref_ *m = NULL, *reply = NULL;
+ DBusError _cleanup_dbus_error_free_ error;
int previous, rl, r;
char
env1_buf[] = "RUNLEVEL=X",
r = 1;
finish:
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
if (bus) {
dbus_connection_flush(bus);
dbus_connection_close(bus);
dbus_connection_unref(bus);
}
- dbus_error_free(&error);
-
return r;
}
{ "status", MORE, 2, show },
{ "help", MORE, 2, show },
{ "dump", EQUAL, 1, dump },
- { "dot", EQUAL, 1, dot },
{ "snapshot", LESS, 2, snapshot },
{ "delete", MORE, 2, delete_snapshot },
{ "daemon-reload", EQUAL, 1, daemon_reload },
}
static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
- int fd;
+ int _cleanup_close_ fd;
struct msghdr msghdr;
struct iovec iovec[2];
union sockaddr_union sockaddr;
}
msghdr.msg_iov = iovec;
- if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
- close_nointr_nofail(fd);
+ if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
return -errno;
- }
- close_nointr_nofail(fd);
return 0;
}
}
if (arg_when > 0) {
- char *m;
+ char _cleanup_free_ *m;
m = strv_join(arg_wall, " ");
r = send_shutdownd(arg_when,
arg_dry,
!arg_no_wall,
m);
- free(m);
if (r < 0)
log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
int main(int argc, char*argv[]) {
int r, retval = EXIT_FAILURE;
DBusConnection *bus = NULL;
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
dbus_error_init(&error);
dbus_connection_unref(bus);
}
- dbus_error_free(&error);
-
dbus_shutdown();
strv_free(arg_property);