else if (endswith(name, ".sh"))
/* Drop Debian-style .sh suffix */
strcpy(stpcpy(r, name) - 3, ".service");
+#ifdef TARGET_ARCH
+ else if (startswith(name, "@"))
+ /* Drop Arch-style background prefix */
+ strcpy(stpcpy(r, name + 1), ".service");
+#endif
else
/* Normal init scripts */
strcpy(stpcpy(r, name), ".service");
#ifdef TARGET_FEDORA
/* Fedora extensions, lacking the $ prefix */
"MTA", SPECIAL_MAIL_TRANSFER_AGENT_TARGET,
- "smtpdaemon", SPECIAL_MAIL_TRANSFER_AGENT_TARGET
+ "smtpdaemon", SPECIAL_MAIL_TRANSFER_AGENT_TARGET,
+ "httpd", SPECIAL_HTTP_DAEMON_TARGET,
#endif
};
}
if (*name == '$')
- return 0;
+ r = unit_name_build(name+1, NULL, ".target");
+ else
+ r = sysv_translate_name(name);
- if (!(r = sysv_translate_name(name)))
+ if (!r)
return -ENOMEM;
finish:
/* If both units have modern headers we don't care
* about the priorities */
- if ((!s->sysv_path || s->sysv_has_lsb) &&
- (!t->sysv_path || t->sysv_has_lsb))
+ if ((s->meta.fragment_path || s->sysv_has_lsb) &&
+ (t->meta.fragment_path || t->sysv_has_lsb))
continue;
special_s = s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels);
assert(s);
assert(pid >= 0);
- if (s->sysv_path)
+ if (!s->meta.fragment_path)
success = is_clean_exit_lsb(code, status);
else
success = is_clean_exit(code, status);
Unit *service;
Iterator j;
int r;
+#ifdef TARGET_ARCH
+ Unit *previous = NULL;
+ char *arch_daemons = NULL;
+ char *arch_daemons_stripped = NULL;
+ char **arch_daemons_split = NULL;
+#endif
assert(m);
+#ifdef TARGET_ARCH
+ if ((r = parse_env_file("/etc/rc.conf", NEWLINE,
+ "DAEMONS", &arch_daemons,
+ NULL)) < 0) {
+
+ if (r != -ENOENT)
+ log_warning("Failed to read /etc/rc.conf: %s", strerror(-r));
+
+ } else if (arch_daemons) {
+ if (!(arch_daemons_stripped = strchr(arch_daemons, '(')))
+ arch_daemons_stripped = arch_daemons;
+ else
+ arch_daemons_stripped++; /* strip start paren */
+
+ arch_daemons_stripped[strcspn(arch_daemons_stripped, ")")] = 0; /* strip end paren */
+
+ if (!(arch_daemons_split = strv_split_quoted(arch_daemons_stripped))) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ STRV_FOREACH(p, arch_daemons_split) {
+
+ free(name);
+
+ if (**p == '!') /* daemons prefixed with ! are disabled, so ignore them */
+ continue;
+
+ if (!(name = sysv_translate_name(*p))) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if ((r = manager_load_unit_prepare(m, name, NULL, NULL, &service)) < 0) {
+ log_warning("Failed to prepare unit %s: %s", name, strerror(-r));
+ continue;
+ }
+
+ if ((r = unit_add_two_dependencies_by_name_inverse(service, UNIT_AFTER, UNIT_WANTS, "multi-user.target", NULL, true)) < 0)
+ goto finish;
+
+ if (previous)
+ if ((r = unit_add_dependency(service, UNIT_AFTER, previous, true)) < 0)
+ goto finish;
+
+ if (**p != '@') /* daemons prefixed with @ can be started in the background */
+ previous = service;
+ }
+ }
+#endif
+
zero(runlevel_services);
STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path)
free(path);
free(fpath);
free(name);
+#ifdef TARGET_ARCH
+ free(arch_daemons);
+ free(arch_daemons_split);
+#endif
for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
set_free(runlevel_services[i]);