chiark / gitweb /
util: generalize code that checks whether PIDs are alive or unwaited for
[elogind.git] / src / shared / install-printf.c
index 85aebc42cc010045bad17445afc7a9b2c715080c..1ee1243f4d191c63e0acda1be7c06682db04efc3 100644 (file)
 
 #include "specifier.h"
 #include "unit-name.h"
+#include "util.h"
 #include "install-printf.h"
 
-static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) {
+static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
         InstallInfo *i = userdata;
+        char *n;
+
         assert(i);
 
-        return unit_name_to_prefix_and_instance(i->name);
+        n = unit_name_to_prefix_and_instance(i->name);
+        if (!n)
+                return -ENOMEM;
+
+        *ret = n;
+        return 0;
 }
 
-static char *specifier_prefix(char specifier, void *data, void *userdata) {
+static int specifier_prefix(char specifier, void *data, void *userdata, char **ret) {
         InstallInfo *i = userdata;
+        char *n;
+
         assert(i);
 
-        return unit_name_to_prefix(i->name);
+        n = unit_name_to_prefix(i->name);
+        if (!n)
+                return -ENOMEM;
+
+        *ret = n;
+        return 0;
 }
 
-static char *specifier_instance(char specifier, void *data, void *userdata) {
+static int specifier_instance(char specifier, void *data, void *userdata, char **ret) {
         InstallInfo *i = userdata;
         char *instance;
         int r;
@@ -49,14 +64,57 @@ static char *specifier_instance(char specifier, void *data, void *userdata) {
 
         r = unit_name_to_instance(i->name, &instance);
         if (r < 0)
-                return NULL;
-        if (instance != NULL)
-                return instance;
+                return r;
+
+        if (!instance) {
+                instance = strdup("");
+                if (!instance)
+                        return -ENOMEM;
+        }
+
+        *ret = instance;
+        return 0;
+}
+
+static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
+        InstallInfo *i = userdata;
+        const char *username;
+        _cleanup_free_ char *tmp = NULL;
+        char *printed = NULL;
+
+        assert(i);
+
+        if (i->user)
+                username = i->user;
         else
-                return strdup("");
+                /* get USER env from env or our own uid */
+                username = tmp = getusername_malloc();
+
+        switch (specifier) {
+        case 'u':
+                printed = strdup(username);
+                break;
+        case 'U': {
+                /* fish username from passwd */
+                uid_t uid;
+                int r;
+
+                r = get_user_creds(&username, &uid, NULL, NULL, NULL);
+                if (r < 0)
+                        return r;
+
+                if (asprintf(&printed, "%d", uid) < 0)
+                        return -ENOMEM;
+                break;
+        }}
+
+
+        *ret = printed;
+        return 0;
 }
 
-char *install_full_printf(InstallInfo *i, const char *format) {
+
+int install_full_printf(InstallInfo *i, const char *format, char **ret) {
 
         /* This is similar to unit_full_printf() but does not support
          * anything path-related.
@@ -71,6 +129,7 @@ char *install_full_printf(InstallInfo *i, const char *format) {
          * %m the machine ID of the running system
          * %H the host name of the running system
          * %b the boot ID of the running system
+         * %v `uname -r` of the running system
          */
 
         const Specifier table[] = {
@@ -79,17 +138,19 @@ char *install_full_printf(InstallInfo *i, const char *format) {
                 { 'p', specifier_prefix,              NULL },
                 { 'i', specifier_instance,            NULL },
 
-//                { 'U', specifier_user_name,           NULL },
-//                { 'u', specifier_user_name,           NULL },
+                { 'U', specifier_user_name,           NULL },
+                { 'u', specifier_user_name,           NULL },
 
                 { 'm', specifier_machine_id,          NULL },
                 { 'H', specifier_host_name,           NULL },
                 { 'b', specifier_boot_id,             NULL },
-                { 0, NULL, NULL }
+                { 'v', specifier_kernel_release,      NULL },
+                {}
         };
 
         assert(i);
         assert(format);
+        assert(ret);
 
-        return specifier_printf(format, table, i);
+        return specifier_printf(format, table, i, ret);
 }