chiark / gitweb /
util: user parse_uid() wherever applicable
[elogind.git] / src / util.c
index 4e441a7dbe5310cc429ca079a0b765053fcada76..3a82ef7600f53453416eb487b076c4415c1172a4 100644 (file)
@@ -317,6 +317,26 @@ int parse_pid(const char *s, pid_t* ret_pid) {
         return 0;
 }
 
+int parse_uid(const char *s, uid_t* ret_uid) {
+        unsigned long ul = 0;
+        uid_t uid;
+        int r;
+
+        assert(s);
+        assert(ret_uid);
+
+        if ((r = safe_atolu(s, &ul)) < 0)
+                return r;
+
+        uid = (uid_t) ul;
+
+        if ((unsigned long) uid != ul)
+                return -ERANGE;
+
+        *ret_uid = uid;
+        return 0;
+}
+
 int safe_atou(const char *s, unsigned *ret_u) {
         char *x = NULL;
         unsigned long l;
@@ -4801,7 +4821,7 @@ static int file_is_conf(const struct dirent *d, const char *suffix) {
 
 static int files_add(Hashmap *h, const char *path, const char *suffix) {
         DIR *dir;
-        struct dirent *de;
+        struct dirent buffer, *de;
         int r = 0;
 
         dir = opendir(path);
@@ -4811,9 +4831,18 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
                 return -errno;
         }
 
-        for (de = readdir(dir); de; de = readdir(dir)) {
+        for (;;) {
+                int k;
                 char *p, *f;
-                const char *base;
+
+                k = readdir_r(dir, &buffer, &de);
+                if (k != 0) {
+                        r = -k;
+                        goto finish;
+                }
+
+                if (!de)
+                        break;
 
                 if (!file_is_conf(de, suffix))
                         continue;
@@ -4832,8 +4861,7 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
                 free(p);
 
                 log_debug("found: %s\n", f);
-                base = f + strlen(path) + 1;
-                if (hashmap_put(h, base, f) <= 0)
+                if (hashmap_put(h, file_name_from_path(f), f) <= 0)
                         free(f);
         }
 
@@ -5234,7 +5262,7 @@ int socket_from_display(const char *display, char **path) {
 
 int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home) {
         struct passwd *p;
-        unsigned long lu;
+        uid_t u;
 
         assert(username);
         assert(*username);
@@ -5253,9 +5281,9 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h
                 return 0;
         }
 
-        if (safe_atolu(*username, &lu) >= 0) {
+        if (parse_uid(*username, &u) >= 0) {
                 errno = 0;
-                p = getpwuid((uid_t) lu);
+                p = getpwuid(u);
 
                 /* If there are multiple users with the same id, make
                  * sure to leave $USER to the configured value instead
@@ -5349,6 +5377,70 @@ int in_search_path(const char *path, char **search) {
         return r;
 }
 
+int get_files_in_directory(const char *path, char ***list) {
+        DIR *d;
+        int r = 0;
+        unsigned n = 0;
+        char **l = NULL;
+
+        assert(path);
+        assert(list);
+
+        d = opendir(path);
+        for (;;) {
+                struct dirent buffer, *de;
+                int k;
+
+                k = readdir_r(d, &buffer, &de);
+                if (k != 0) {
+                        r = -k;
+                        goto finish;
+                }
+
+                if (!de)
+                        break;
+
+                dirent_ensure_type(d, de);
+
+                if (!dirent_is_file(de))
+                        continue;
+
+                if ((unsigned) r >= n) {
+                        char **t;
+
+                        n = MAX(16, 2*r);
+                        t = realloc(l, sizeof(char*) * n);
+                        if (!t) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        l = t;
+                }
+
+                assert((unsigned) r < n);
+
+                l[r] = strdup(de->d_name);
+                if (!l[r]) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                l[++r] = NULL;
+        }
+
+finish:
+        if (d)
+                closedir(d);
+
+        if (r >= 0)
+                *list = l;
+        else
+                strv_free(l);
+
+        return r;
+}
+
 static const char *const ioprio_class_table[] = {
         [IOPRIO_CLASS_NONE] = "none",
         [IOPRIO_CLASS_RT] = "realtime",