]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/sysv-generator/sysv-generator.c
Define FOREACH_DIRENT through FOREACH_DIRENT_ALL
[thirdparty/systemd.git] / src / sysv-generator / sysv-generator.c
index 13a9a77e81d55a3045f8e8a08f70f8021e50b9c2..e9976540b5a45a08206df8f143819201273cdbb4 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <errno.h>
 #include <stdio.h>
@@ -59,9 +59,9 @@ typedef struct SysvStub {
         bool loaded;
 } SysvStub;
 
-static void free_sysvstub(SysvStub *s) {
+static SysvStub* free_sysvstub(SysvStub *s) {
         if (!s)
-                return;
+                return NULL;
 
         free(s->name);
         free(s->path);
@@ -71,9 +71,8 @@ static void free_sysvstub(SysvStub *s) {
         strv_free(s->after);
         strv_free(s->wants);
         strv_free(s->wanted_by);
-        free(s);
+        return mfree(s);
 }
-
 DEFINE_TRIVIAL_CLEANUP_FUNC(SysvStub*, free_sysvstub);
 
 static void free_sysvstub_hashmapp(Hashmap **h) {
@@ -87,7 +86,7 @@ static int add_alias(const char *service, const char *alias) {
         assert(service);
         assert(alias);
 
-        link = strjoina(arg_dest, "/", alias);
+        link = prefix_roota(arg_dest, alias);
 
         r = symlink(service, link);
         if (r < 0) {
@@ -116,7 +115,7 @@ static int generate_unit_file(SysvStub *s) {
         if (!path_escaped)
                 return log_oom();
 
-        unit = strjoina(arg_dest, "/", s->name);
+        unit = prefix_roota(arg_dest, s->name);
 
         /* We might already have a symlink with the same name from a Provides:,
          * or from backup files like /etc/init.d/foo.bak. Real scripts always win,
@@ -138,7 +137,7 @@ static int generate_unit_file(SysvStub *s) {
                 path_escaped);
 
         if (s->description) {
-                _cleanup_free_ char *t;
+                _cleanup_free_ char *t = NULL;
 
                 t = specifier_escape(s->description);
                 if (!t)
@@ -166,7 +165,7 @@ static int generate_unit_file(SysvStub *s) {
                 yes_no(!s->pid_file));
 
         if (s->pid_file) {
-                _cleanup_free_ char *t;
+                _cleanup_free_ char *t = NULL;
 
                 t = specifier_escape(s->pid_file);
                 if (!t)
@@ -290,7 +289,7 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
         }
 
         /* Strip ".sh" suffix from file name for comparison */
-        filename_no_sh = strdupa(filename);
+        filename_no_sh = strdupa_safe(filename);
         e = endswith(filename_no_sh, ".sh");
         if (e) {
                 *e = '\0';
@@ -322,7 +321,7 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co
         for (;;) {
                 _cleanup_free_ char *word = NULL, *m = NULL;
 
-                r = extract_first_word(&text, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
+                r = extract_first_word(&text, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RELAX);
                 if (r < 0)
                         return log_error_errno(r, "[%s:%u] Failed to parse word from provides string: %m", s->path, line);
                 if (r == 0)
@@ -391,7 +390,7 @@ static int handle_dependencies(SysvStub *s, unsigned line, const char *full_text
                 _cleanup_free_ char *word = NULL, *m = NULL;
                 bool is_before;
 
-                r = extract_first_word(&text, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
+                r = extract_first_word(&text, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RELAX);
                 if (r < 0)
                         return log_error_errno(r, "[%s:%u] Failed to parse word from provides string: %m", s->path, line);
                 if (r == 0)
@@ -420,7 +419,7 @@ static int handle_dependencies(SysvStub *s, unsigned line, const char *full_text
 }
 
 static int load_sysv(SysvStub *s) {
-        _cleanup_fclose_ FILE *f;
+        _cleanup_fclose_ FILE *f = NULL;
         unsigned line = 0;
         int r;
         enum {
@@ -534,7 +533,7 @@ static int load_sysv(SysvStub *s) {
                          * continuation */
 
                         size_t k;
-                        char *j;
+                        const char *j;
 
                         k = strlen(t);
                         if (k > 0 && t[k-1] == '\\')
@@ -543,19 +542,8 @@ static int load_sysv(SysvStub *s) {
                                 state = NORMAL;
 
                         j = strstrip(t);
-                        if (!isempty(j)) {
-                                char *d = NULL;
-
-                                if (chkconfig_description)
-                                        d = strjoin(chkconfig_description, " ", j);
-                                else
-                                        d = strdup(j);
-                                if (!d)
-                                        return log_oom();
-
-                                free(chkconfig_description);
-                                chkconfig_description = d;
-                        }
+                        if (!isempty(j) && !strextend_with_separator(&chkconfig_description, " ", j))
+                                return log_oom();
 
                 } else if (IN_SET(state, LSB, LSB_DESCRIPTION)) {
 
@@ -605,20 +593,8 @@ static int load_sysv(SysvStub *s) {
                                         const char *j;
 
                                         j = strstrip(t);
-                                        if (!isempty(j)) {
-                                                char *d = NULL;
-
-                                                if (long_description)
-                                                        d = strjoin(long_description, " ", t);
-                                                else
-                                                        d = strdup(j);
-                                                if (!d)
-                                                        return log_oom();
-
-                                                free(long_description);
-                                                long_description = d;
-                                        }
-
+                                        if (!isempty(j) && !strextend_with_separator(&long_description, " ", j))
+                                                return log_oom();
                                 } else
                                         state = LSB;
                         }
@@ -642,7 +618,7 @@ static int load_sysv(SysvStub *s) {
         if (description) {
                 char *d;
 
-                d = strappend(s->has_lsb ? "LSB: " : "SYSV: ", description);
+                d = strjoin(s->has_lsb ? "LSB: " : "SYSV: ", description);
                 if (!d)
                         return log_oom();
 
@@ -655,7 +631,6 @@ static int load_sysv(SysvStub *s) {
 
 static int fix_order(SysvStub *s, Hashmap *all_services) {
         SysvStub *other;
-        Iterator j;
         int r;
 
         assert(s);
@@ -666,7 +641,7 @@ static int fix_order(SysvStub *s, Hashmap *all_services) {
         if (s->sysv_start_priority < 0)
                 return 0;
 
-        HASHMAP_FOREACH(other, all_services, j) {
+        HASHMAP_FOREACH(other, all_services) {
                 if (s == other)
                         continue;
 
@@ -743,7 +718,6 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
 
         STRV_FOREACH(path, sysvinit_path) {
                 _cleanup_closedir_ DIR *d = NULL;
-                struct dirent *de;
 
                 d = opendir(*path);
                 if (!d) {
@@ -788,19 +762,25 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
                         if (!fpath)
                                 return log_oom();
 
-                        service = new0(SysvStub, 1);
+                        log_warning("SysV service '%s' lacks a native systemd unit file. "
+                                    "Automatically generating a unit file for compatibility. "
+                                    "Please update package to include a native systemd unit file, in order to make it more safe and robust.", fpath);
+
+                        service = new(SysvStub, 1);
                         if (!service)
                                 return log_oom();
 
-                        service->sysv_start_priority = -1;
-                        service->name = TAKE_PTR(name);
-                        service->path = TAKE_PTR(fpath);
+                        *service = (SysvStub) {
+                                .sysv_start_priority = -1,
+                                .name = TAKE_PTR(name),
+                                .path = TAKE_PTR(fpath),
+                        };
 
                         r = hashmap_put(all_services, service->name, service);
                         if (r < 0)
                                 return log_oom();
 
-                        service = NULL;
+                        TAKE_PTR(service);
                 }
         }
 
@@ -811,8 +791,6 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
         Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
         _cleanup_strv_free_ char **sysvrcnd_path = NULL;
         SysvStub *service;
-        unsigned i;
-        Iterator j;
         char **p;
         int r;
 
@@ -822,12 +800,10 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
         if (r < 0)
                 return r;
 
-        STRV_FOREACH(p, sysvrcnd_path) {
-                for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
-
+        STRV_FOREACH(p, sysvrcnd_path)
+                for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
                         _cleanup_closedir_ DIR *d = NULL;
                         _cleanup_free_ char *path = NULL;
-                        struct dirent *de;
 
                         path = path_join(*p, rcnd_table[i].path);
                         if (!path) {
@@ -843,7 +819,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
                                 continue;
                         }
 
-                        FOREACH_DIRENT(de, d, log_error_errno(errno, "Failed to enumerate directory %s, ignoring: %m", path)) {
+                        FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to enumerate directory %s, ignoring: %m", path)) {
                                 _cleanup_free_ char *name = NULL, *fpath = NULL;
                                 int a, b;
 
@@ -879,23 +855,16 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
 
                                 service->sysv_start_priority = MAX(a*10 + b, service->sysv_start_priority);
 
-                                r = set_ensure_allocated(&runlevel_services[i], NULL);
-                                if (r < 0) {
-                                        log_oom();
-                                        goto finish;
-                                }
-
-                                r = set_put(runlevel_services[i], service);
+                                r = set_ensure_put(&runlevel_services[i], NULL, service);
                                 if (r < 0) {
                                         log_oom();
                                         goto finish;
                                 }
                         }
                 }
-        }
 
-        for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
-                SET_FOREACH(service, runlevel_services[i], j) {
+        for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
+                SET_FOREACH(service, runlevel_services[i]) {
                         r = strv_extend(&service->before, rcnd_table[i].target);
                         if (r < 0) {
                                 log_oom();
@@ -911,7 +880,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic
         r = 0;
 
 finish:
-        for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
+        for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
                 set_free(runlevel_services[i]);
 
         return r;
@@ -921,7 +890,6 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
         _cleanup_(free_sysvstub_hashmapp) Hashmap *all_services = NULL;
         _cleanup_(lookup_paths_free) LookupPaths lp = {};
         SysvStub *service;
-        Iterator j;
         int r;
 
         assert_se(arg_dest = dest_late);
@@ -942,10 +910,10 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
         if (r < 0)
                 return r;
 
-        HASHMAP_FOREACH(service, all_services, j)
+        HASHMAP_FOREACH(service, all_services)
                 (void) load_sysv(service);
 
-        HASHMAP_FOREACH(service, all_services, j) {
+        HASHMAP_FOREACH(service, all_services) {
                 (void) fix_order(service, all_services);
                 (void) generate_unit_file(service);
         }