chiark / gitweb /
systemctl: conform to LSB with the "status" return code
[elogind.git] / src / systemctl / systemctl.c
index 0ba3568a1e9309a6a5615116173898522158bede..24543ee06db3d6e0dcd1112d14a582e0a28b6917 100644 (file)
@@ -129,7 +129,8 @@ static enum transport {
         TRANSPORT_SSH,
         TRANSPORT_POLKIT
 } arg_transport = TRANSPORT_NORMAL;
-static const char *arg_host = NULL;
+static char *arg_host = NULL;
+static char *arg_user = NULL;
 static unsigned arg_lines = 10;
 static OutputMode arg_output = OUTPUT_SHORT;
 static bool arg_plain = false;
@@ -2657,6 +2658,7 @@ typedef struct UnitStatusInfo {
         pid_t main_pid;
         pid_t control_pid;
         const char *status_text;
+        const char *pid_file;
         bool running:1;
 
         usec_t start_timestamp;
@@ -3056,6 +3058,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
                                 i->default_control_group = s;
                         else if (streq(name, "StatusText"))
                                 i->status_text = s;
+                        else if (streq(name, "PIDFile"))
+                                i->pid_file = s;
                         else if (streq(name, "SysFSPath"))
                                 i->sysfs_path = s;
                         else if (streq(name, "Where"))
@@ -3546,9 +3550,19 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
 
         if (!streq_ptr(info.active_state, "active") &&
             !streq_ptr(info.active_state, "reloading") &&
-            streq(verb, "status"))
+            streq(verb, "status")) {
                 /* According to LSB: "program not running" */
-                r = 3;
+                /* 0: program is running or service is OK
+                 * 1: program is dead and /var/run pid file exists
+                 * 2: program is dead and /var/lock lock file exists
+                 * 3: program is not running
+                 * 4: program or service status is unknown
+                 */
+                if (info.pid_file && access(info.pid_file, F_OK) == 0)
+                        r = 1;
+                else
+                        r = 3;
+       }
 
         while ((p = info.exec)) {
                 LIST_REMOVE(ExecStatusInfo, exec, info.exec, p);
@@ -3735,7 +3749,7 @@ static int snapshot(DBusConnection *bus, char **args) {
         dbus_error_init(&error);
 
         if (strv_length(args) > 1)
-                n = snapshot_name_mangle(args[1]);
+                n = unit_name_mangle_with_suffix(args[1], ".snapshot");
         else
                 n = strdup("");
         if (!n)
@@ -3810,7 +3824,7 @@ static int delete_snapshot(DBusConnection *bus, char **args) {
                 _cleanup_free_ char *n = NULL;
                 int r;
 
-                n = snapshot_name_mangle(*name);
+                n = unit_name_mangle_with_suffix(*name, ".snapshot");
                 if (!n)
                         return log_oom();
 
@@ -4598,7 +4612,7 @@ static int systemctl_help(void) {
                "                      the 'list-unit-files' command instead.\n"
                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
                "     --failed         Show only failed units\n"
-               "     --full           Don't ellipsize unit names on output\n"
+               "  -l --full           Don't ellipsize unit names on output\n"
                "     --fail           When queueing a new job, fail if conflicting jobs are\n"
                "                      pending\n"
                "     --irreversible   Create jobs which cannot be implicitly cancelled\n"
@@ -4818,7 +4832,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_NO_PAGER,
                 ARG_NO_WALL,
                 ARG_ROOT,
-                ARG_FULL,
                 ARG_NO_RELOAD,
                 ARG_KILL_WHO,
                 ARG_NO_ASK_PASSWORD,
@@ -4839,7 +4852,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "before",    no_argument,       NULL, ARG_BEFORE    },
                 { "show-types", no_argument,      NULL, ARG_SHOW_TYPES },
                 { "failed",    no_argument,       NULL, ARG_FAILED    },
-                { "full",      no_argument,       NULL, ARG_FULL      },
+                { "full",      no_argument,       NULL, 'l'           },
                 { "fail",      no_argument,       NULL, ARG_FAIL      },
                 { "irreversible", no_argument,    NULL, ARG_IRREVERSIBLE },
                 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
@@ -4872,7 +4885,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:i", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:Pn:o:i", options, NULL)) >= 0) {
 
                 switch (c) {
 
@@ -5020,7 +5033,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         arg_root = optarg;
                         break;
 
-                case ARG_FULL:
+                case 'l':
                         arg_full = true;
                         break;
 
@@ -5065,7 +5078,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
 
                 case 'H':
                         arg_transport = TRANSPORT_SSH;
-                        arg_host = optarg;
+                        parse_user_at_host(optarg, &arg_user, &arg_host);
                         break;
 
                 case ARG_RUNTIME:
@@ -6086,7 +6099,7 @@ int main(int argc, char*argv[]) {
                         bus_connect_system_polkit(&bus, &error);
                         private_bus = false;
                 } else if (arg_transport == TRANSPORT_SSH) {
-                        bus_connect_system_ssh(NULL, arg_host, &bus, &error);
+                        bus_connect_system_ssh(arg_user, arg_host, &bus, &error);
                         private_bus = false;
                 } else
                         assert_not_reached("Uh, invalid transport...");