-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stdio.h>
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);
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) {
assert(service);
assert(alias);
- link = strjoina(arg_dest, "/", alias);
+ link = prefix_roota(arg_dest, alias);
r = symlink(service, link);
if (r < 0) {
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,
path_escaped);
if (s->description) {
- _cleanup_free_ char *t;
+ _cleanup_free_ char *t = NULL;
t = specifier_escape(s->description);
if (!t)
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)
}
/* 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';
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)
_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)
}
static int load_sysv(SysvStub *s) {
- _cleanup_fclose_ FILE *f;
+ _cleanup_fclose_ FILE *f = NULL;
unsigned line = 0;
int r;
enum {
* continuation */
size_t k;
- char *j;
+ const char *j;
k = strlen(t);
if (k > 0 && t[k-1] == '\\')
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)) {
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;
}
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();
static int fix_order(SysvStub *s, Hashmap *all_services) {
SysvStub *other;
- Iterator j;
int r;
assert(s);
if (s->sysv_start_priority < 0)
return 0;
- HASHMAP_FOREACH(other, all_services, j) {
+ HASHMAP_FOREACH(other, all_services) {
if (s == other)
continue;
STRV_FOREACH(path, sysvinit_path) {
_cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
d = opendir(*path);
if (!d) {
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);
}
}
Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
_cleanup_strv_free_ char **sysvrcnd_path = NULL;
SysvStub *service;
- unsigned i;
- Iterator j;
char **p;
int r;
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) {
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;
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();
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;
_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);
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);
}