From f29d2733c7e536a549fccf02ba8364274842b54c Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Sat, 6 Oct 2012 15:45:37 +0200 Subject: [PATCH] Fix incorrect use of variable arguments in run_parts() and simplify code The run_parts() implementation used variable arguments in a bad way, resulting in it not working properly. Replaced va_*() code with a simple cmd argument that's passed to each script called. Also, the opendir()/readdir() code has been replaced with scandir() using regular alphasort(). This simplifies the code somewhat as well. Otherwise, minor cleanups. Signed-off-by: Joachim Nilsson --- finit.c | 2 +- helpers.c | 92 +++++++++++++++++--------------------------- helpers.h | 6 ++- libite/fmode.c | 2 +- plugin.c | 4 +- plugins/resolvconf.c | 2 +- svc.c | 2 +- 7 files changed, 46 insertions(+), 64 deletions(-) diff --git a/finit.c b/finit.c index 23a60e36..97f019d0 100644 --- a/finit.c +++ b/finit.c @@ -185,7 +185,7 @@ int main(int UNUSED(args), char *argv[]) */ if (rcsd && fisdir(rcsd)) { _d("Running startup scripts in %s ...", rcsd); - run_parts(rcsd); + run_parts(rcsd, NULL); } /* diff --git a/helpers.c b/helpers.c index ce9c2326..da9adb49 100644 --- a/helpers.c +++ b/helpers.c @@ -566,81 +566,61 @@ pid_t run_getty(char *cmd, char *argv[]) return pid; } -static int cmp(const void *s1, const void *s2) +int run_parts(char *dir, char *cmd) { - return strcmp(*(char **)s1, *(char **)s2); -} + struct dirent **e; + int i, num; -int run_parts(char *dir, ...) -{ - DIR *d; - struct dirent *e; - struct stat st; - char *oldpwd = NULL; - char *ent[NUM_SCRIPTS]; - int i, num = 0, argnum = 1; - char *args[NUM_ARGS]; - va_list ap; - - oldpwd = getcwd (NULL, 0); - if (chdir(dir)) { - if (oldpwd) free(oldpwd); + num = scandir(dir, &e, NULL, alphasort); + if (num < 0) { + _d("No files found in %s, skipping ...", dir); return -1; } - if ((d = opendir(dir)) == NULL) { - if (oldpwd) free(oldpwd); - return -1; - } - - va_start(ap, dir); - while (argnum < NUM_ARGS && (args[argnum++] = va_arg(ap, char *))); - va_end(ap); - - while ((e = readdir(d))) { - if (e->d_type == DT_REG && stat(e->d_name, &st) == 0) { - _d("Found %s/%s ...", dir, e->d_name); - if (st.st_mode & S_IXUSR) { - ent[num++] = strdup(e->d_name); - if (num >= NUM_SCRIPTS) - break; - } - } - } - - closedir(d); - - if (num == 0) { - if (oldpwd) free(oldpwd); - return 0; - } - - qsort(ent, num, sizeof(char *), cmp); for (i = 0; i < num; i++) { int j = 0, status; pid_t pid = 0; + mode_t mode; + char *args[NUM_ARGS]; + char *name = e[i]->d_name; + char path[CMD_SIZE]; - args[j++] = ent[i]; - /* Check if Sservice or Kservice notation is used */ - if (ent[i][0] == 'S' && isdigit(ent[i][1])) { - args[j++] = "start"; - } else if (ent[i][0] == 'K' && isdigit(ent[i][1])) { - args[j++] = "stop"; + snprintf(path, sizeof(path), "%s/%s", dir, name); + mode = fmode(path); + if (!S_ISEXEC(mode) || S_ISDIR(mode)) { + _d("Skipping %s ...", path); + continue; + } + + /* Fill in args[], starting with full path to executable */ + args[j++] = path; + + /* If the callee didn't supply a run_parts() argument */ + if (!cmd) { + /* Check if Sservice or Kservice notation is used */ + _d("Checking if %s is a sysvinit startstop script ...", name); + if (name[0] == 'S' && isdigit(name[1])) { + args[j++] = "start"; + } else if (name[0] == 'K' && isdigit(name[1])) { + args[j++] = "stop"; + } + } else { + args[j++] = cmd; } args[j++] = NULL; pid = fork(); if (!pid) { - _d("Calling %s ...", ent[i]); - execv(ent[i], args); + _d("Calling %s ...", path); + execv(path, args); exit(0); } waitpid(pid, &status, 0); - free(ent[i]); } - chdir(oldpwd); - free(oldpwd); + while (num--) + free(e[num]); + free(e); return 0; } diff --git a/helpers.h b/helpers.h index 68f368d5..86ea8773 100644 --- a/helpers.h +++ b/helpers.h @@ -50,7 +50,9 @@ #ifndef blkdev # define blkdev(x,m,maj,min) mknod((x), S_IFBLK|(m), makedev((maj),(min))) #endif - +#ifndef S_ISEXEC +# define S_ISEXEC(m) (((m) & S_IXUSR) == S_IXUSR) +#endif #ifndef UNUSED #define UNUSED(x) UNUSED_ ## x __attribute__ ((unused)) #endif @@ -87,7 +89,7 @@ void set_hostname (char *hostname); int run (char *cmd); int run_interactive (char *cmd, char *fmt, ...); pid_t run_getty (char *cmd, char *argv[]); -int run_parts (char *dir, ...); +int run_parts (char *dir, char *cmd); /* strlcpy.c */ size_t strlcpy(char *dst, const char *src, size_t siz); diff --git a/libite/fmode.c b/libite/fmode.c index 7b3e68fc..6f27ecb9 100644 --- a/libite/fmode.c +++ b/libite/fmode.c @@ -39,7 +39,7 @@ mode_t fmode(char *file) if (!file) { errno = EINVAL; - return 0; /* Doesn't exist ... */ + return 0; } if (!stat(file, &sb)) diff --git a/plugin.c b/plugin.c index b5cd98f7..d9971e01 100644 --- a/plugin.c +++ b/plugin.c @@ -161,7 +161,7 @@ plugin_t *plugin_find(char *name) if (name[0] != '/') { int noext; - char path[256]; + char path[CMD_SIZE]; noext = strcmp(name + strlen(name) - 3, ".so"); snprintf (path, sizeof(path), "%s%s%s%s", plugpath, @@ -262,7 +262,7 @@ static void init_plugins(void) static int load_one(char *path, char *name) { int noext; - char plugin[256]; + char plugin[CMD_SIZE]; void *handle; if (!path || !fisdir(path) || !name) { diff --git a/plugins/resolvconf.c b/plugins/resolvconf.c index e92ed185..c53de5a1 100644 --- a/plugins/resolvconf.c +++ b/plugins/resolvconf.c @@ -59,7 +59,7 @@ static void setup(void *UNUSED(arg)) touch("/etc/resolvconf/run/enable-updates"); chdir("/etc/resolvconf/run/interface"); - run_parts("/etc/resolvconf/update.d", "-i", NULL); + run_parts("/etc/resolvconf/update.d", "-i"); chdir("/"); #endif /* USE_ETC_RESOLVCONF_RUN */ } diff --git a/svc.c b/svc.c index 92a4ee3d..d3943d63 100644 --- a/svc.c +++ b/svc.c @@ -325,7 +325,7 @@ int svc_start(svc_t *svc) if (debug) { int fd; - char buf[256] = ""; + char buf[CMD_SIZE] = ""; fd = open (CONSOLE, O_WRONLY | O_APPEND); if (-1 != fd) {