mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 10:12:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
685618691d | ||
|
|
f29d2733c7 | ||
|
|
af59174e49 | ||
|
|
785c21d27b | ||
|
|
40c7a44d4f |
@@ -1,3 +1,11 @@
|
||||
1.6 (20121006)
|
||||
- Skip . and .. in plugin loader and display error on failed plugins
|
||||
- Support for overriding /etc/finit.d with "runparts DIR" in finit.conf
|
||||
- Revoke support for starting services not starting with a slash.
|
||||
- Prevent endless restart of non-existing services in finit.conf
|
||||
- Support for sysvinit style startstop scripts in /etc/finit.d
|
||||
- Minor fix to alsa-utils plugin to silence on non-existing cards
|
||||
|
||||
1.5 (20121003)
|
||||
- Use bootmisc plugin to setup standard FHS 2.3 structure in /var
|
||||
- Added FLOG_WARN() syslog macro, for plugins
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
ROOTDIR = $(shell pwd)
|
||||
|
||||
#VERSION ?= $(shell git tag -l | tail -1)
|
||||
VERSION ?= 1.5
|
||||
VERSION ?= 1.6
|
||||
NAME = finit
|
||||
PKG = $(NAME)-$(VERSION)
|
||||
DEV = $(NAME)-dev
|
||||
|
||||
@@ -122,6 +122,11 @@ void parse_finit_conf(char *file)
|
||||
network = build_cmd(NULL, x, CMD_SIZE);
|
||||
continue;
|
||||
}
|
||||
if (MATCH_CMD(line, "runparts ", x)) {
|
||||
if (rcsd) free(rcsd);
|
||||
hostname = build_cmd(NULL, x, CMD_SIZE);
|
||||
continue;
|
||||
}
|
||||
if (MATCH_CMD(line, "startx ", x)) {
|
||||
svc_register(x, username);
|
||||
continue;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "plugin.h"
|
||||
#include "svc.h"
|
||||
#include "sig.h"
|
||||
#include "lite.h"
|
||||
|
||||
int debug = 0;
|
||||
int verbose = 1;
|
||||
@@ -40,6 +41,7 @@ char *sdown = NULL;
|
||||
char *network = NULL;
|
||||
char *username = NULL;
|
||||
char *hostname = NULL;
|
||||
char *rcsd = FINIT_RCSD;
|
||||
|
||||
|
||||
static void parse_kernel_cmdline(void)
|
||||
@@ -181,8 +183,10 @@ int main(int UNUSED(args), char *argv[])
|
||||
/*
|
||||
* Run startup scripts in /etc/finit.d/, if any.
|
||||
*/
|
||||
_d("Running startup scripts in /etc/finit.d/ ...");
|
||||
run_parts(FINIT_RCSD);
|
||||
if (rcsd && fisdir(rcsd)) {
|
||||
_d("Running startup scripts in %s ...", rcsd);
|
||||
run_parts(rcsd, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hooks that should run at the very end
|
||||
|
||||
@@ -66,6 +66,7 @@ extern char *sdown;
|
||||
extern char *network;
|
||||
extern char *hostname;
|
||||
extern char *username;
|
||||
extern char *rcsd;
|
||||
|
||||
/* conf.c */
|
||||
void parse_finit_conf(char *file);
|
||||
|
||||
@@ -566,75 +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;
|
||||
int status;
|
||||
mode_t mode;
|
||||
char *args[NUM_ARGS];
|
||||
char *name = e[i]->d_name;
|
||||
char path[CMD_SIZE];
|
||||
|
||||
args[0] = ent[i];
|
||||
args[1] = NULL;
|
||||
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 S<NUM>service or K<NUM>service 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ mode_t fmode(char *file)
|
||||
|
||||
if (!file) {
|
||||
errno = EINVAL;
|
||||
return 0; /* Doesn't exist ... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!stat(file, &sb))
|
||||
|
||||
@@ -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,20 +262,22 @@ 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)) {
|
||||
if (!path || !fisdir(path) || !name) {
|
||||
errno = EINVAL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Compose full path, with optional .so extension, to plugin */
|
||||
noext = strcmp(name + strlen(name) - 3, ".so");
|
||||
snprintf(plugin, sizeof(plugin), "%s/%s%s", path, name, noext ? ".so" : "");
|
||||
|
||||
_d("Loading plugin %s ...", basename(plugin));
|
||||
handle = dlopen(plugin, RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (!handle) {
|
||||
_d("Failed loading plugin %s: %s", plugin, dlerror());
|
||||
_e("Failed loading plugin %s: %s", plugin, dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -321,6 +323,9 @@ int plugin_load_all(char *path)
|
||||
plugpath = path;
|
||||
|
||||
while ((entry = readdir(dp))) {
|
||||
if (entry->d_name[0] == '.')
|
||||
continue; /* Skip . and .. directories */
|
||||
|
||||
// print_desc(" Loading plugin ", basename(plugin));
|
||||
if (load_one(path, entry->d_name))
|
||||
fail++;
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
|
||||
static void save(void *UNUSED(arg))
|
||||
{
|
||||
_d("Saving system clock to RTC ...");
|
||||
run_interactive("/usr/sbin/alsactl store > /dev/null 2>&1", "Saving sound settings");
|
||||
_d("Saving sound settings ...");
|
||||
run_interactive("/usr/sbin/alsactl -g store", "Saving sound settings");
|
||||
}
|
||||
|
||||
static void restore(void *UNUSED(arg))
|
||||
{
|
||||
_d("Restoring system clock from RTC ...");
|
||||
run_interactive("/usr/sbin/alsactl restore > /dev/null 2>&1", "Restoring sound settings");
|
||||
_d("Restoring sound settings ...");
|
||||
run_interactive("/usr/sbin/alsactl -g restore", "Restoring sound settings");
|
||||
}
|
||||
|
||||
static plugin_t plugin = {
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -273,6 +273,20 @@ int svc_start(svc_t *svc)
|
||||
sigset_t nmask, omask;
|
||||
char *args[MAX_NUM_SVC_ARGS];
|
||||
|
||||
if (!svc)
|
||||
return 0;
|
||||
|
||||
/* Don't try and start service if it doesn't exist. */
|
||||
if (!fexist(svc->cmd)) {
|
||||
char msg[80];
|
||||
|
||||
snprintf(msg, sizeof(msg), "Service %s does not exist!", svc->cmd);
|
||||
print_desc("", msg);
|
||||
print_result(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ignore if finit is SIGSTOP'ed */
|
||||
if (is_norespawn())
|
||||
return 0;
|
||||
@@ -311,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) {
|
||||
@@ -329,7 +343,10 @@ int svc_start(svc_t *svc)
|
||||
_e("%starting %s: %s", respawn ? "Res" : "S", svc->cmd, buf);
|
||||
}
|
||||
|
||||
execvp(svc->cmd, args);
|
||||
/* XXX: Maybe change to use execve() to be able to launch scripts? */
|
||||
execv(svc->cmd, args);
|
||||
|
||||
/* Only reach this point if exec() fails. */
|
||||
exit(0);
|
||||
}
|
||||
svc->pid = pid;
|
||||
|
||||
Reference in New Issue
Block a user