chiark / gitweb /
binfmt,tmpfiles,modules-load,sysctl: rework the various early-boot services that...
[elogind.git] / src / shared / util.c
index 5b795d4a246e1e2be581479cb46acdd848b35647..24f9e7ee58338c4ad293012e7811671e3a1dad9e 100644 (file)
@@ -766,77 +766,82 @@ fail:
         return r;
 }
 
         return r;
 }
 
-int load_env_file(const char *fname,
-                  char ***rl) {
+int load_env_file(const char *fname, char ***rl) {
 
 
-        FILE _cleanup_fclose_ *f;
-        char *b;
-        char _cleanup_free_ *c = NULL;
-        char _cleanup_strv_free_ **m = NULL;
+        _cleanup_fclose_ FILE *f;
+        _cleanup_strv_free_ char **m = NULL;
+        _cleanup_free_ char *c = NULL;
 
         assert(fname);
         assert(rl);
 
 
         assert(fname);
         assert(rl);
 
+        /* This reads an environment file, but will not complain about
+         * any invalid assignments, that needs to be done by the
+         * caller */
+
         f = fopen(fname, "re");
         if (!f)
                 return -errno;
 
         while (!feof(f)) {
         f = fopen(fname, "re");
         if (!f)
                 return -errno;
 
         while (!feof(f)) {
-                char l[LINE_MAX], *p, *u, *cs;
-                char **t;
+                char l[LINE_MAX], *p, *cs, *b;
 
                 if (!fgets(l, sizeof(l), f)) {
 
                 if (!fgets(l, sizeof(l), f)) {
-                        if (!feof(f))
+                        if (ferror(f))
                                 return -errno;
                                 return -errno;
-                        else if (!c)
-                                break;
+
+                        /* The previous line was a continuation line?
+                         * Let's process it now, before we leave the
+                         * loop */
+                        if (c)
+                                goto process;
+
+                        break;
                 }
 
                 }
 
+                /* Is this a continuation line? If so, just append
+                 * this to c, and go to next line right-away */
                 cs = endswith(l, "\\\n");
                 if (cs) {
                         *cs = '\0';
                         b = strappend(c, l);
                         if (!b)
                 cs = endswith(l, "\\\n");
                 if (cs) {
                         *cs = '\0';
                         b = strappend(c, l);
                         if (!b)
-                                return log_oom();
+                                return -ENOMEM;
 
                         free(c);
                         c = b;
 
                         free(c);
                         c = b;
-                        *l = '\0';
                         continue;
                 }
 
                         continue;
                 }
 
+                /* If the previous line was a continuation line,
+                 * append the current line to it */
                 if (c) {
                         b = strappend(c, l);
                         if (!b)
                 if (c) {
                         b = strappend(c, l);
                         if (!b)
-                                return log_oom();
+                                return -ENOMEM;
 
                         free(c);
                         c = b;
                 }
 
 
                         free(c);
                         c = b;
                 }
 
+        process:
                 p = strstrip(c ? c : l);
 
                 p = strstrip(c ? c : l);
 
-                if (!*p)
-                        continue;
+                if (*p && !strchr(COMMENTS, *p)) {
+                        _cleanup_free_ char *u;
+                        int k;
 
 
-                if (strchr(COMMENTS, *p))
-                        continue;
+                        u = normalize_env_assignment(p);
+                        if (!u)
+                                return -ENOMEM;
 
 
-                u = normalize_env_assignment(p);
-                if (!u)
-                        return log_oom();
+                        k = strv_extend(&m, u);
+                        if (k < 0)
+                                return -ENOMEM;
+                }
 
                 free(c);
                 c = NULL;
 
                 free(c);
                 c = NULL;
-
-                t = strv_append(m, u);
-                free(u);
-
-                if (!t)
-                        return log_oom();
-
-                strv_free(m);
-                m = t;
         }
 
         *rl = m;
         }
 
         *rl = m;
@@ -1063,10 +1068,10 @@ int get_process_exe(pid_t pid, char **name) {
 }
 
 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
 }
 
 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
-        char *p;
-        FILE *f;
-        int r;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *p = NULL;
 
 
+        assert(field);
         assert(uid);
 
         if (pid == 0)
         assert(uid);
 
         if (pid == 0)
@@ -1076,21 +1081,11 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
                 return -ENOMEM;
 
         f = fopen(p, "re");
                 return -ENOMEM;
 
         f = fopen(p, "re");
-        free(p);
-
         if (!f)
                 return -errno;
 
         if (!f)
                 return -errno;
 
-        while (!feof(f)) {
-                char line[LINE_MAX], *l;
-
-                if (!fgets(line, sizeof(line), f)) {
-                        if (feof(f))
-                                break;
-
-                        r = -errno;
-                        goto finish;
-                }
+        FOREACH_LINE(f, line, return -errno) {
+                char *l;
 
                 l = strstrip(line);
 
 
                 l = strstrip(line);
 
@@ -1100,17 +1095,11 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
 
                         l[strcspn(l, WHITESPACE)] = 0;
 
 
                         l[strcspn(l, WHITESPACE)] = 0;
 
-                        r = parse_uid(l, uid);
-                        goto finish;
+                        return parse_uid(l, uid);
                 }
         }
 
                 }
         }
 
-        r = -EIO;
-
-finish:
-        fclose(f);
-
-        return r;
+        return -EIO;
 }
 
 int get_process_uid(pid_t pid, uid_t *uid) {
 }
 
 int get_process_uid(pid_t pid, uid_t *uid) {
@@ -5920,3 +5909,82 @@ int on_ac_power(void) {
 
         return found_online || !found_offline;
 }
 
         return found_online || !found_offline;
 }
+
+static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) {
+        char **i;
+
+        assert(path);
+        assert(mode);
+        assert(_f);
+
+        if (!path_strv_canonicalize_uniq(search))
+                return -ENOMEM;
+
+        STRV_FOREACH(i, search) {
+                _cleanup_free_ char *p = NULL;
+                FILE *f;
+
+                p = strjoin(*i, "/", path, NULL);
+                if (!p)
+                        return -ENOMEM;
+
+                f = fopen(p, mode);
+                if (f) {
+                        *_f = f;
+                        return 0;
+                }
+
+                if (errno != ENOENT)
+                        return -errno;
+        }
+
+        return -ENOENT;
+}
+
+int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) {
+        _cleanup_strv_free_ char **copy = NULL;
+
+        assert(path);
+        assert(mode);
+        assert(_f);
+
+        if (path_is_absolute(path)) {
+                FILE *f;
+
+                f = fopen(path, mode);
+                if (f) {
+                        *_f = f;
+                        return 0;
+                }
+
+                return -errno;
+        }
+
+        copy = strv_copy((char**) search);
+        if (!copy)
+                return -ENOMEM;
+
+        return search_and_fopen_internal(path, mode, copy, _f);
+}
+
+int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) {
+        _cleanup_strv_free_ char **s = NULL;
+
+        if (path_is_absolute(path)) {
+                FILE *f;
+
+                f = fopen(path, mode);
+                if (f) {
+                        *_f = f;
+                        return 0;
+                }
+
+                return -errno;
+        }
+
+        s = strv_split_nulstr(search);
+        if (!s)
+                return -ENOMEM;
+
+        return search_and_fopen_internal(path, mode, s, _f);
+}