chiark / gitweb /
Compiling.
[elogind.git] / src / sysv-generator / sysv-generator.c
index 984beab70ad397ed5760dd4e2cc00d64b3095c9d..4beea4dd02ed9a4d4332166713680d34e1ff86db 100644 (file)
 #include "unit.h"
 #include "unit-name.h"
 #include "special.h"
-#include "exit-status.h"
-#include "def.h"
-#include "env-util.h"
-#include "fileio.h"
 #include "hashmap.h"
 
 typedef enum RunlevelType {
@@ -51,11 +47,11 @@ static const struct {
         const RunlevelType type;
 } rcnd_table[] = {
         /* Standard SysV runlevels for start-up */
-        { "rc1.d",  SPECIAL_RESCUE_TARGET,    RUNLEVEL_UP },
-        { "rc2.d",  SPECIAL_RUNLEVEL2_TARGET, RUNLEVEL_UP },
-        { "rc3.d",  SPECIAL_RUNLEVEL3_TARGET, RUNLEVEL_UP },
-        { "rc4.d",  SPECIAL_RUNLEVEL4_TARGET, RUNLEVEL_UP },
-        { "rc5.d",  SPECIAL_RUNLEVEL5_TARGET, RUNLEVEL_UP },
+        { "rc1.d",  SPECIAL_RESCUE_TARGET,     RUNLEVEL_UP },
+        { "rc2.d",  SPECIAL_MULTI_USER_TARGET, RUNLEVEL_UP },
+        { "rc3.d",  SPECIAL_MULTI_USER_TARGET, RUNLEVEL_UP },
+        { "rc4.d",  SPECIAL_MULTI_USER_TARGET, RUNLEVEL_UP },
+        { "rc5.d",  SPECIAL_GRAPHICAL_TARGET,  RUNLEVEL_UP },
 
         /* Standard SysV runlevels for shutdown */
         { "rc0.d",  SPECIAL_POWEROFF_TARGET,  RUNLEVEL_DOWN },
@@ -119,11 +115,6 @@ static int add_alias(const char *service, const char *alias) {
         assert(service);
         assert(alias);
 
-        if (streq(service, alias)) {
-                log_error("Ignoring creation of an alias %s for itself", service);
-                return 0;
-        }
-
         link = strjoin(arg_dest, "/", alias, NULL);
         if (!link)
                 return log_oom();
@@ -171,7 +162,7 @@ static int generate_unit_file(SysvStub *s) {
         /* 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,
          * so remove an existing link */
-        if (is_symlink(unit)) {
+        if (is_symlink(unit) > 0) {
                 log_warning("Overwriting existing symlink %s with real service", unit);
                 (void) unlink(unit);
         }
@@ -299,7 +290,7 @@ static int sysv_translate_facility(const char *name, const char *filename, char
 
         /* strip ".sh" suffix from file name for comparison */
         filename_no_sh = strdupa(filename);
-        e = endswith(filename, ".sh");
+        e = endswith(filename_no_sh, ".sh");
         if (e) {
                 *e = '\0';
                 filename = filename_no_sh;
@@ -314,13 +305,12 @@ static int sysv_translate_facility(const char *name, const char *filename, char
 
                 /* Facilities starting with $ are most likely targets */
                 r = unit_name_build(n, NULL, ".target");
-        } else if (filename && streq(name, filename))
+        } else if (streq_ptr(n, filename))
                 /* Names equaling the file name of the services are redundant */
                 return 0;
         else
                 /* Everything else we assume to be normal service names */
                 r = sysv_translate_name(n);
-
         if (!r)
                 return -ENOMEM;
 
@@ -729,10 +719,10 @@ static int fix_order(SysvStub *s, Hashmap *all_services) {
         return 0;
 }
 
-static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
+static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
         char **path;
 
-        STRV_FOREACH(path, lp.sysvinit_path) {
+        STRV_FOREACH(path, lp->sysvinit_path) {
                 _cleanup_closedir_ DIR *d = NULL;
                 struct dirent *de;
 
@@ -749,12 +739,10 @@ static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
                         struct stat st;
                         int r;
 
-                        dirent_ensure_type(d, de);
-
-                        if (!dirent_is_file(de))
-                            continue;
+                        if (hidden_file(de->d_name))
+                                continue;
 
-                        if (fstatat(dirfd(d), de->d_name, &st, 0) < 0) {
+                        if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
                                 log_warning_errno(errno, "stat() failed on %s/%s: %m", *path, de->d_name);
                                 continue;
                         }
@@ -769,12 +757,17 @@ static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
                         if (!name)
                                 return log_oom();
 
+                        if (hashmap_contains(all_services, name))
+                                continue;
+
                         fpath = strjoin(*path, "/", de->d_name, NULL);
                         if (!fpath)
                                 return log_oom();
 
-                        if (hashmap_contains(all_services, name))
+                        if (unit_file_lookup_state(UNIT_FILE_SYSTEM, NULL, lp, name) >= 0) {
+                                log_debug("Native unit for %s already exists, skipping", name);
                                 continue;
+                        }
 
                         service = new0(SysvStub, 1);
                         if (!service)
@@ -796,7 +789,7 @@ static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
         return 0;
 }
 
-static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) {
+static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_services) {
         char **p;
         unsigned i;
         _cleanup_closedir_ DIR *d = NULL;
@@ -807,7 +800,7 @@ static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) {
         _cleanup_set_free_ Set *shutdown_services = NULL;
         int r = 0;
 
-        STRV_FOREACH(p, lp.sysvrcnd_path)
+        STRV_FOREACH(p, lp->sysvrcnd_path)
                 for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
                         struct dirent *de;
 
@@ -860,7 +853,8 @@ static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) {
 
                                 service = hashmap_get(all_services, name);
                                 if (!service){
-                                        log_warning("Could not find init script for %s", name);
+                                        log_debug("Ignoring %s symlink in %s, not generating %s.",
+                                                  de->d_name, rcnd_table[i].path, name);
                                         continue;
                                 }
 
@@ -956,13 +950,13 @@ int main(int argc, char *argv[]) {
                 return EXIT_FAILURE;
         }
 
-        r = enumerate_sysv(lp, all_services);
+        r = enumerate_sysv(&lp, all_services);
         if (r < 0) {
                 log_error("Failed to generate units for all init scripts.");
                 return EXIT_FAILURE;
         }
 
-        r = set_dependencies_from_rcnd(lp, all_services);
+        r = set_dependencies_from_rcnd(&lp, all_services);
         if (r < 0) {
                 log_error("Failed to read runlevels from rcnd links.");
                 return EXIT_FAILURE;