-#ifdef HAVE_SYSV_COMPAT
-
-static int service_enumerate(Manager *m) {
- char **p;
- unsigned i;
- _cleanup_closedir_ DIR *d = NULL;
- _cleanup_free_ char *path = NULL, *fpath = NULL, *name = NULL;
- Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
- _cleanup_set_free_ Set *shutdown_services = NULL;
- Unit *service;
- Iterator j;
- int r;
-
- assert(m);
-
- if (m->running_as != SYSTEMD_SYSTEM)
- return 0;
-
- STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path)
- for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
- struct dirent *de;
-
- free(path);
- path = strjoin(*p, "/", rcnd_table[i].path, NULL);
- if (!path) {
- r = -ENOMEM;
- goto finish;
- }
-
- if (d)
- closedir(d);
-
- d = opendir(path);
- if (!d) {
- if (errno != ENOENT)
- log_warning("opendir(%s) failed: %m", path);
-
- continue;
- }
-
- while ((de = readdir(d))) {
- int a, b;
-
- if (ignore_file(de->d_name))
- continue;
-
- if (de->d_name[0] != 'S' && de->d_name[0] != 'K')
- continue;
-
- if (strlen(de->d_name) < 4)
- continue;
-
- a = undecchar(de->d_name[1]);
- b = undecchar(de->d_name[2]);
-
- if (a < 0 || b < 0)
- continue;
-
- free(fpath);
- fpath = strjoin(path, "/", de->d_name, NULL);
- if (!fpath) {
- r = -ENOMEM;
- goto finish;
- }
-
- if (access(fpath, X_OK) < 0) {
-
- if (errno != ENOENT)
- log_warning("access() failed on %s: %m", fpath);
-
- continue;
- }
-
- free(name);
- name = sysv_translate_name(de->d_name + 3);
- if (!name) {
- r = log_oom();
- goto finish;
- }
-
- r = manager_load_unit_prepare(m, name, NULL, NULL, &service);
- if (r < 0) {
- log_warning("Failed to prepare unit %s: %s", name, strerror(-r));
- continue;
- }
-
- if (de->d_name[0] == 'S') {
-
- if (rcnd_table[i].type == RUNLEVEL_UP) {
- SERVICE(service)->sysv_start_priority_from_rcnd =
- MAX(a*10 + b, SERVICE(service)->sysv_start_priority_from_rcnd);
-
- SERVICE(service)->sysv_enabled = true;
- }
-
- r = set_ensure_allocated(&runlevel_services[i],
- trivial_hash_func, trivial_compare_func);
- if (r < 0)
- goto finish;
-
- r = set_put(runlevel_services[i], service);
- if (r < 0)
- goto finish;
-
- } else if (de->d_name[0] == 'K' &&
- (rcnd_table[i].type == RUNLEVEL_DOWN)) {
-
- r = set_ensure_allocated(&shutdown_services,
- trivial_hash_func, trivial_compare_func);
- if (r < 0)
- goto finish;
-
- r = set_put(shutdown_services, service);
- if (r < 0)
- goto finish;
- }
- }
- }
-
- /* Now we loaded all stubs and are aware of the lowest
- start-up priority for all services, not let's actually load
- the services, this will also tell us which services are
- actually native now */
- manager_dispatch_load_queue(m);
-
- /* If this is a native service, rely on native ways to pull in
- * a service, don't pull it in via sysv rcN.d links. */
- for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
- SET_FOREACH(service, runlevel_services[i], j) {
- service = unit_follow_merge(service);
-
- if (service->fragment_path)
- continue;
-
- r = unit_add_two_dependencies_by_name_inverse(
- service, UNIT_AFTER, UNIT_WANTS,
- rcnd_table[i].target, NULL, true);
- if (r < 0)
- goto finish;
- }
-
- /* We honour K links only for halt/reboot. For the normal
- * runlevels we assume the stop jobs will be implicitly added
- * by the core logic. Also, we don't really distinguish here
- * between the runlevels 0 and 6 and just add them to the
- * special shutdown target. */
- SET_FOREACH(service, shutdown_services, j) {
- service = unit_follow_merge(service);
-
- if (service->fragment_path)
- continue;
-
- r = unit_add_two_dependencies_by_name(
- service, UNIT_BEFORE, UNIT_CONFLICTS,
- SPECIAL_SHUTDOWN_TARGET, NULL, true);
- if (r < 0)
- goto finish;
- }
-
- r = 0;
-
-finish:
-
- for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
- set_free(runlevel_services[i]);
-
- return r;
-}
-#endif
-