Пример #1
0
int
main(int argc, char **argv)
{
    int		errflag = 0;
    int		sts;
    int		c;

    __pmSetProgname(argv[0]);

    indomp = (__pmInDom_int *)&indom;

    while ((c = getopt(argc, argv, "D:")) != EOF) {
	switch (c) {

#ifdef PCP_DEBUG
	case 'D':	/* debug flag */
	    sts = __pmParseDebug(optarg);
	    if (sts < 0) {
		fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
		    pmProgname, optarg);
		errflag++;
	    }
	    else
		pmDebug |= sts;
	    break;
#endif

	case '?':
	default:
	    errflag++;
	    break;
	}
    }

    if (errflag) {
	fprintf(stderr, "Usage: %s [-D...] [a|b|c|d|...|i 1|2|3}\n", pmProgname);
	exit(1);
    }

    while (optind < argc) {
	if (strcmp(argv[optind], "a") == 0) _a(0, 1, 1);
	else if (strcmp(argv[optind], "b") == 0) _b();
	else if (strcmp(argv[optind], "c") == 0) _c();
	else if (strcmp(argv[optind], "d") == 0) _a(1, 0, 1);
	else if (strcmp(argv[optind], "e") == 0) _e(0);
	else if (strcmp(argv[optind], "f") == 0) _e(3600);
	else if (strcmp(argv[optind], "g") == 0) _g();
	else if (strcmp(argv[optind], "h") == 0) _h();
	else if (strcmp(argv[optind], "i") == 0) {
	    optind++;
	    _i(atoi(argv[optind]));
	}
	else if (strcmp(argv[optind], "j") == 0) _j();
	else
	    fprintf(stderr, "torture_cache: no idea what to do with option \"%s\"\n", argv[optind]);
	optind++;
    }

    exit(0);
}
Пример #2
0
/**
 * load_one - Load one plugin
 * @path: Path to finit plugins, usually %PLUGIN_PATH
 * @name: Name of plugin, optionally ending in ".so"
 *
 * Loads a plugin from @path/@name[.so].  Note, if ".so" is missing from
 * the plugin @name it is added before attempting to load.
 *
 * It is up to the plugin itself ot register itself as a "ctor" with the
 * %PLUGIN_INIT macro so that plugin_register() is called automatically.
 *
 * Returns:
 * POSIX OK(0) on success, non-zero otherwise.
 */
static int load_one(char *path, char *name)
{
	int noext;
	char sofile[CMD_SIZE];
	void *handle;
	plugin_t *plugin;

	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(sofile, sizeof(sofile), "%s/%s%s", path, name, noext ? ".so" : "");

	_d("Loading plugin %s ...", basename(sofile));
	handle = dlopen(sofile, RTLD_LAZY | RTLD_LOCAL);
	if (!handle) {
		_e("Failed loading plugin %s: %s", sofile, dlerror());
		return 1;
	}

	plugin = TAILQ_LAST(&plugins, plugin_head);
	if (!plugin) {
		_e("Plugin %s failed to register, unloading from memory", sofile);
		dlclose(handle);
		return 1;
	}

	/* Remember handle from dlopen() for plugin_unregister() */
	plugin->handle = handle;

	return 0;
}
Пример #3
0
/* Standard reboot/shutdown utilities talk to init using /dev/initctl.
 * We should check if the fifo was recreated and reopen it.
 */
static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
{
	struct init_request rq;

	_d("Receiving request on %s...", FINIT_FIFO);
	while (1) {
		ssize_t len = read(fd, &rq, sizeof(rq));

		if (len <= 0) {
			if (-1 == len) {
				if (EINTR == errno)
					continue;

				if (EAGAIN == errno)
					break;

				_e("Failed reading initctl request, error %d: %s", errno, strerror(errno));
			}
			break;
		}

		if (rq.magic != INIT_MAGIC || len != sizeof(rq)) {
			_e("Invalid initctl request.");
			break;
		}

		_d("Magic OK...");
		if (rq.cmd == INIT_CMD_RUNLVL) {
			switch (rq.runlevel) {
			case '0':
				_d("Halting system (SIGUSR2)");
				do_shutdown(SIGUSR2);
				break;

			case 's':
			case 'S':
				rq.runlevel = '1';
				/* Fall through to regular processing */
			case '1'...'5':
				_d("Setting new runlevel %c ...", rq.runlevel);
				svc_runlevel(rq.runlevel - '0');
				break;

			case '6':
				_d("Rebooting system (SIGUSR1)");
				do_shutdown(SIGUSR1);
				break;

			default:
				_d("Unsupported runlevel: %d", rq.runlevel);
				break;
			}
		} else if (rq.cmd == INIT_CMD_DEBUG) {
			debug = !debug;
		} else {
			_d("Unsupported cmd: %d", rq.cmd);
		}
	}
Пример #4
0
char*
XMLDecode(const char* src)
{
    typedef const struct XMLEntity {
        const char* name;
        size_t nameLen;
        char value;
    } XMLEntity;
    
    /* This is ugly, but better than specifying the lengths by hand */
    #define _e(str,c) {str,sizeof(str)-1,c}
    const XMLEntity ents[] = {
        _e("quot;",'"'), _e("apos;",'\''),
        _e("lt;",  '<'), _e("gt;",  '>'),
        _e("amp;", '&')
    };
    
    size_t len;
    const char *s;
    char *out, *o;
    
    if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) )
        return 0;
    
    o = out;
    s = src;
    while (s <= src+len) /* Make sure the terminator is also copied */
    {
        if ( *s == '&' )
        {
            bool entFound = false;
            int i;
            
            s++;
            for ( i = 0; i < sizeof(ents)/sizeof(ents[0]); i++)
            {
                if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 )
                {
                    entFound = true;
                    break;
                }
            }
            if ( entFound )
            {
                *o++ = ents[i].value;
                s += ents[i].nameLen;
                continue;
            }
        }
        
        *o++ = *s++;
    }

    return out;
}                    
Пример #5
0
CHAR8*
XMLDecode(const CHAR8* src)
{
    typedef const struct XMLEntity {
        const CHAR8* name;
        UINTN nameLen;
        CHAR8 value;
    } XMLEntity;
    
    /* This is ugly, but better than specifying the lengths by hand */
#define _e(str,c) {str,sizeof(str)-1,c}
    const XMLEntity ents[] = {
        _e("quot;",'"'), _e("apos;",'\''),
        _e("lt;",  '<'), _e("gt;",  '>'),
        _e("amp;", '&')
    };
    
    UINTN len;
    const CHAR8 *s;
    CHAR8 *out, *o;
    
    if ( !src || !(len = AsciiStrLen(src)) || !(out = AllocateZeroPool(len+1)) )
        return 0;
    
    o = out;
    s = src;
    while (s <= src+len) /* Make sure the terminator is also copied */
    {
        if ( *s == '&' )
        {
            BOOLEAN entFound = FALSE;
            UINTN i;
            
            s++;
            for ( i = 0; i < sizeof(ents); i++)
            {
                if ( AsciiStrnCmp(s, ents[i].name, ents[i].nameLen) == 0 )
                {
                    entFound = TRUE;
                    break;
                }
            }
            if ( entFound )
            {
                *o++ = ents[i].value;
                s += ents[i].nameLen;
                continue;
            }
        }
        
        *o++ = *s++;
    }

    return out;
}   
Пример #6
0
/**
 * service_enabled - Should the service run?
 * @svc:   Pointer to &svc_t object
 * @event: Dynamic event, opaque flag passed to callback
 * @arg:   Event argument, used only by external service plugins.
 *
 * This method calls an associated service callback, if registered by a
 * plugin, and returns the &svc_cmd_t status. If no plugin is registered
 * the service is statically enabled in /etc/finit.conf and the result
 * will always be %SVC_START.
 *
 * Returns:
 * Either one of %SVC_START, %SVC_STOP, %SVC_RELOAD.
 */
svc_cmd_t service_enabled(svc_t *svc, int event, void *arg)
{
	if (!svc) {
		errno = EINVAL;
		return SVC_STOP;
	}

	if (!svc_in_runlevel(svc, runlevel))
		return SVC_STOP;

	/*
	 * Event conditions for services are ignored during bootstrap.
	 */
	if (runlevel && !event_service_cond(svc->events))
		return SVC_STOP;

	/* Is there a service plugin registered? */
	if (svc->cb) {
		int   status;
		pid_t pid;

		/* Let callback run in separate process so it doesn't crash PID 1 */
		pid = fork();
		if (-1 == pid) {
			_pe("Failed in %s callback", svc->cmd);
			return SVC_STOP;
		}

		if (!pid) {
			status = svc->cb(svc, event, arg);
			exit(status);
		}

		if (waitpid(pid, &status, 0) == -1) {
			_pe("Failed reading status from %s callback", svc->cmd);
			return SVC_STOP;
		}

		/* Callback normally exits here. */
		if (WIFEXITED(status))
			return WEXITSTATUS(status);

		/* Check for SEGFAULT or other error ... */
		if (WIFSIGNALED(status) && WCOREDUMP(status))
			_e("Callback to %s crashed!\n", svc->cmd);
		else
			_e("Callback to %s did not exit normally!\n", svc->cmd);

		return SVC_STOP;
	}

	/* No service plugin, default to start, since listed in finit.conf */
	return SVC_START;
}
Пример #7
0
int svc_stop(svc_t *svc)
{
	int res = 1;

	if (!svc) {
		_e("Failed, no svc pointer.");
		return 1;
	}

	if (svc->pid <= 1) {
		_d("Bad PID %d for %s, SIGTERM", svc->pid, svc->desc);
		svc->pid = 0;
		svc->stat_restart_counter = 0;
		return 1;
	}

	if (runlevel != 1)
		print_desc("Stopping ", svc->desc);
	_d("Sending SIGTERM to pid:%d name:'%s'", svc->pid, pid_get_name(svc->pid, NULL, 0));
	res = kill(svc->pid, SIGTERM);
	if (runlevel != 1)
		print_result(res);
	svc->pid = 0;
	svc->stat_restart_counter = 0;

	return res;
}
Пример #8
0
int plugin_load_all(char *path)
{
	int fail = 0;
	DIR *dp = opendir(path);
	struct dirent *entry;

	if (!dp) {
		_e("Failed, cannot open plugin directory %s: %s", path, strerror(errno));
		return 1;
	}
	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++;
//		print_result(result);
	}

	closedir(dp);
	init_plugins();

	return fail;
}
Пример #9
0
void conf_parse_cond(svc_t *svc, char *cond)
{
    size_t i = 0;
    char *ptr;

    if (!svc) {
        _e("Invalid service pointer");
        return;
    }

    /* By default we assume UNIX daemons support SIGHUP */
    if (svc_is_daemon(svc))
        svc->sighup = 1;

    if (!cond)
        return;

    /* First character must be '!' if SIGHUP is not supported. */
    ptr = cond;
    if (ptr[i] == '!') {
        svc->sighup = 0;
        ptr++;
    }

    while (ptr[i] != '>' && ptr[i] != 0)
        i++;
    ptr[i] = 0;

    if (i >= sizeof(svc->cond)) {
        logit(LOG_WARNING, "Too long event list in declaration of %s: %s", svc->cmd, ptr);
        return;
    }

    strlcpy(svc->cond, ptr, sizeof(svc->cond));
}
Пример #10
0
static int load_plugins(char *path)
{
	int fail = 0;
	DIR *dp;
	struct dirent *entry;

	if (!silent)
		print_desc("Loading plugins", NULL);

	dp = opendir(path);
	if (!dp) {
		_e("Failed, cannot open plugin directory %s: %s", path, strerror(errno));
		return 1;
	}
	plugpath = path;

	while ((entry = readdir(dp))) {
		if (entry->d_name[0] == '.')
			continue; /* Skip . and .. directories */

		if (load_one(path, entry->d_name))
			fail++;
	}

	closedir(dp);

	return fail;
}
Пример #11
0
void svc_monitor(pid_t lost)
{
	svc_t *svc;

	if (was_stopped && !is_norespawn()) {
		was_stopped = 0;
		restart_any_lost_procs();
		return;
	}

	if (fexist(SYNC_SHUTDOWN) || lost <= 1)
		return;

	/* Power user at the console, don't respawn tasks. */
	if (is_norespawn()) {
		was_stopped = 1;
		return;
	}

	if (tty_respawn(lost))
		return;

#ifndef INETD_DISABLED
	if (inetd_respawn(lost))
		return;
#endif

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		if (lost != svc->pid)
			continue;

		if (SVC_CMD_SERVICE != svc->type) {
			svc->pid = 0;
			continue;
		}

		_d("Ouch, lost pid %d - %s(%d)", lost, basename(svc->cmd), svc->pid);

		/* No longer running, update books. */
		svc->pid = 0;

		if (sig_stopped()) {
			_e("Stopped, not respawning killed processes.");
			break;
		}

		/* Cleanup any lingering or semi-restarting tasks before respawning */
		_d("Sending SIGTERM to service group %s", basename(svc->cmd));
		procname_kill(basename(svc->cmd), SIGTERM);

		/* Restarting lost service. */
		if (svc_enabled(svc, 0, NULL)) {
			svc->restart_counter++;
			svc_start(svc);
		}

		break;
	}
}
Пример #12
0
static void fifo_open(void)
{
	plugin.io.fd = open(FINIT_FIFO, O_RDWR | O_NONBLOCK | O_CLOEXEC);
	if (-1 == plugin.io.fd) {
		_e("Failed opening %s FIFO, error %d: %s", FINIT_FIFO, errno, strerror(errno));
		return;
	}
}
Пример #13
0
/* Wait for process completion, returns status of waitpid(2) syscall */
int complete(char *cmd, int pid)
{
	int status = 0;

	if (waitpid(pid, &status, 0) == -1) {
		if (errno == EINTR)
			_e("Caught unblocked signal waiting for %s, aborting.", cmd);
		else if (errno == ECHILD)
			_e("Caught SIGCHLD waiting for %s, aborting.", cmd);
		else
			_e("Failed starting %s, error %d: %s", cmd, errno, strerror (errno));

		return -1;
	}

	return status;
}
Пример #14
0
Файл: tty.c Проект: wkz/finit
static void setup(void)
{
	if (plugin.io.fd)
		close(plugin.io.fd);

	plugin.io.fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
	if (-1 == plugin.io.fd || inotify_add_watch(plugin.io.fd, "/dev", IN_CREATE | IN_DELETE) < 0)
		_e("Failed starting TTY watcher: %s", strerror(errno));
}
Пример #15
0
 bool exist(vector<vector<char> > &board, string word) {
     int m = (int)board.size(), n = (int)board.front().size(), len = (int)word.length();
     for (int i=0; i<m; ++i) for (int j=0; j<n; ++j) if (board[i][j] == word[0]) {
         memset(v, false, sizeof(v));
         v[i][j] = true;
         if (_e(i, j, 0, m, n, len, board, word)) return true;
     }
     return false;
 }
Пример #16
0
static void nl_link(struct nlmsghdr *nlmsg)
{
	int la;
	char ifname[IFNAMSIZ + 1];
	struct rtattr *a;
	struct ifinfomsg *i;

	if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
		_e("Packet too small or truncated!");
		return;
	}

	i  = NLMSG_DATA(nlmsg);
	a  = (struct rtattr *)((char *)i + NLMSG_ALIGN(sizeof(struct ifinfomsg)));
	la = NLMSG_PAYLOAD(nlmsg, sizeof(struct ifinfomsg));

	while (RTA_OK(a, la)) {
		if (a->rta_type == IFLA_IFNAME) {
			strlcpy(ifname, RTA_DATA(a), sizeof(ifname));
			switch (nlmsg->nlmsg_type) {
			case RTM_NEWLINK:
				/*
				 * New interface has appeared, or interface flags has changed.
				 * Check ifi_flags here to see if the interface is UP/DOWN
				 */
				_d("%s: New link, flags 0x%x, change 0x%x", ifname, i->ifi_flags, i->ifi_change);
				net_cond_set(ifname, "exist",   1);
				net_cond_set(ifname, "up",      i->ifi_flags & IFF_UP);
				net_cond_set(ifname, "running", i->ifi_flags & IFF_RUNNING);
				break;

			case RTM_DELLINK:
				/* NOTE: Interface has disappeared, not link down ... */
				_d("%s: Delete link", ifname);
				net_cond_set(ifname, "exist",   0);
				net_cond_set(ifname, "up",      0);
				net_cond_set(ifname, "running", 0);
				break;

			case RTM_NEWADDR:
				_d("%s: New Address", ifname);
				break;

			case RTM_DELADDR:
				_d("%s: Deconfig Address", ifname);
				break;

			default:
				_d("%s: Msg 0x%x", ifname, nlmsg->nlmsg_type);
				break;
			}
		}

		a = RTA_NEXT(a, la);
	}
}
Пример #17
0
 bool _e(int x, int y, int d, const int m, const int n, const int len, vector<vector<char> > &board, string &word) {
     if (d == len - 1) return true;
     for (int k=0; k<4; ++k) {
         int tx = x + dx[k], ty = y + dy[k];
         if (tx < 0 || tx >= m || ty < 0 || ty >= n || board[tx][ty] != word[d+1] || v[tx][ty]) continue;
         v[tx][ty] = true;
         if (_e(tx, ty, d+1, m, n, len, board, word)) return true;
         v[tx][ty] = false;
     }
     return false;
 }
Пример #18
0
void plugin_exit(void)
{
#ifndef ENABLE_STATIC
	plugin_t *p, *tmp;

        PLUGIN_ITERATOR(p, tmp) {
                if (dlclose(p->handle))
                        _e("Failed: unloading plugin %s: %s", p->name, dlerror());
        }
#endif
}
Пример #19
0
/* Connect to/create shared memory area of registered servies */
static void __connect_shm(void)
{
	if (!services) {
		services = finit_svc_connect();
		if (!services) {
			/* This should never happen, but if it does we're probably
			 * knee-deep in more serious problems already... */
			_e("Failed allocating shared memory, error %d: %s", errno, strerror (errno));
			abort();
		}
	}
}
Пример #20
0
int plugin_io_init(plugin_t *p)
{
	if (!is_io_plugin(p))
		return 0;

	_d("Initializing plugin %s for I/O", basename(p->name));
	if (uev_io_init(ctx, &p->watcher, generic_io_cb, p, p->io.fd, p->io.flags)) {
		_e("Failed setting up I/O plugin %s", basename(p->name));
		return 1;
	}

	return 0;
}
Пример #21
0
static void nl_route(struct nlmsghdr *nlmsg)
{
	struct rtmsg *r;
	struct rtattr *a;
	int la;
	int gw = 0, dst = 0, mask = 0, idx = 0;

	if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg))) {
		_e("Packet too small or truncated!");
		return;
	}

	r  = NLMSG_DATA(nlmsg);
	a  = RTM_RTA(r);
	la = RTM_PAYLOAD(nlmsg);
	while (RTA_OK(a, la)) {
		void *data = RTA_DATA(a);
		switch (a->rta_type) {
		case RTA_GATEWAY:
			gw = *((int *)data);
			//_d("GW: 0x%04x", gw);
			break;

		case RTA_DST:
			dst = *((int *)data);
			mask = r->rtm_dst_len;
			//_d("MASK: 0x%04x", mask);
			break;

		case RTA_OIF:
			idx = *((int *)data);
			//_d("IDX: 0x%04x", idx);
			break;
		}

		a = RTA_NEXT(a, la);
	}

	if ((!dst && !mask) && (gw || idx)) {
		if (nlmsg->nlmsg_type == RTM_DELROUTE)
			cond_clear("net/route/default");
		else
			cond_set("net/route/default");
	}
}
Пример #22
0
void svc_monitor(void)
{
	pid_t lost;
	svc_t *svc;

	lost = waitpid(-1, NULL, WNOHANG);
	if (lost < 1)
		return;

	if (fexist(SYNC_SHUTDOWN) || lost <= 1)
		return;

	/* Power user at the console, don't respawn tasks. */
	if (is_norespawn())
		return;

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		char *name = basename(svc->cmd);

		if (lost != svc->pid)
			continue;

		_d("Ouch, lost pid %d - %s(%d)", lost, name, svc->pid);

		/* No longer running, update books. */
		svc->pid = 0;

		if (sig_stopped()) {
			_e("Stopped, not respawning killed processes.");
			break;
		}

		/* Cleanup any lingering or semi-restarting tasks before respawning */
		_d("Sending SIGTERM to service group %s", name);
		procname_kill(name, SIGTERM);

		/* Restarting lost service. */
		if (svc_enabled(svc, 0, NULL)) {
			svc->stat_restart_counter++;
			svc_start(svc);
		}

		break;
	}
}
Пример #23
0
/**
 * service_reload - Send SIGHUP to a service
 * @svc: Service to reload
 *
 * This function does some basic checks of the runtime state of Finit
 * and a sanity check of the @svc before sending %SIGHUP.
 * 
 * Returns:
 * POSIX OK(0) or non-zero on error.
 */
int service_reload(svc_t *svc)
{
	/* Ignore if finit is SIGSTOP'ed */
	if (is_norespawn())
		return 0;

	if (!svc) {
		_e("Failed, no svc pointer.");
		return 1;
	}

	if (svc->pid <= 1) {
		_d("Bad PID %d for %s, SIGHUP", svc->pid, svc->cmd);
		svc->pid = 0;
		return 1;
	}

	_d("Sending SIGHUP to PID %d", svc->pid);
	return kill(svc->pid, SIGHUP);
}
Пример #24
0
static void parse_dynamic(char *line, time_t mtime)
{
	char *x;

	/* Skip comments, i.e. lines beginning with # */
	if (MATCH_CMD(line, "#", x))
		return;

	/* Monitored daemon, will be respawned on exit, as
	 * long as the (optional) service callback returns
	 * non-zero */
	if (MATCH_CMD(line, "service ", x)) {
		service_register(SVC_TYPE_SERVICE, x, mtime, NULL);
		return;
	}

	/* One-shot task, will not be respawned. Only runs if
	 * the (optional) service callback returns true */
	if (MATCH_CMD(line, "task ", x)) {
		service_register(SVC_TYPE_TASK, x, mtime, NULL);
		return;
	}

	/* Like task but waits for completion, useful w/ [S] */
	if (MATCH_CMD(line, "run ", x)) {
		service_register(SVC_TYPE_RUN, x, mtime, NULL);
		return;
	}

	/* Classic inetd service */
	if (MATCH_CMD(line, "inetd ", x)) {
#ifndef INETD_DISABLED
		service_register(SVC_TYPE_INETD, x, mtime, NULL);
#else
		_e("Finit built with inetd support disabled, cannot register service inetd %s!", x);
#endif
		return;
	}
}
Пример #25
0
static int do_query_inetd(char *buf, size_t len)
{
	int id = 1;
	char *ptr, *input = sanitize(buf, len);
	svc_t *svc;

	if (!input)
		return -1;

	ptr = strchr(input, ':');
	if (ptr) {
		*ptr++ = 0;
		id = atonum(ptr);
	}

	svc = svc_find_by_jobid(atonum(input), id);
	if (!svc || !svc_is_inetd(svc)) {
		_e("Cannot %s svc %s ...", !svc ? "find" : "query, not an inetd", input);
		return 1;
	}

	return inetd_filter_str(&svc->inetd, buf, len);
}
Пример #26
0
/**
 * load_one - Load one plugin
 * @path: Path to finit plugins, usually %PLUGIN_PATH
 * @name: Name of plugin, optionally ending in ".so"
 *
 * Loads a plugin from @path/@name[.so].  Note, if ".so" is missing from
 * the plugin @name it is added before attempting to load.
 *
 * It is up to the plugin itself ot register itself as a "ctor" with the
 * %PLUGIN_INIT macro so that plugin_register() is called automatically.
 *
 * Returns:
 * POSIX OK(0) on success, non-zero otherwise.
 */
static int load_one(char *path, char *name)
{
	int noext;
	char plugin[CMD_SIZE];
	void *handle;

	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) {
		_e("Failed loading plugin %s: %s", plugin, dlerror());
		return 1;
	}

	return 0;
}
Пример #27
0
void plugin_monitor(void)
{
	int ret;
	size_t i;

	while ((ret = poll(fds, num_fds, 500))) {
		if (-1 == ret) {
			if (EINTR == errno)
				continue;

			_e("Failed polling I/O plugin descriptors, error %d: %s",
			   errno, strerror(errno));
			break;
		}

		/* Traverse all I/O fds and run callbacks */
		for (i = 0; i < num_fds; i++) {
			if (fds[i].revents)
				generic_io_cb(&fds[i]);
		}

		break;
	}
}
Пример #28
0
static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
{
	int sd;
	struct init_request rq;

	sd = accept(w->fd, NULL, NULL);
	if (sd < 0) {
		_pe("Failed serving API request");
		return;
	}

	while (1) {
		int result = 0;
		ssize_t len;

		len = read(sd, &rq, sizeof(rq));
		if (len <= 0) {
			if (-1 == len) {
				if (EINTR == errno)
					continue;

				if (EAGAIN == errno)
					break;

				_e("Failed reading initctl request, error %d: %s", errno, strerror(errno));
			}

			break;
		}

		if (rq.magic != INIT_MAGIC || len != sizeof(rq)) {
			_e("Invalid initctl request.");
			break;
		}

		switch (rq.cmd) {
		case INIT_CMD_RUNLVL:
			switch (rq.runlevel) {
			case '0':
				_d("Halting system (SIGUSR2)");
				do_shutdown(SIGUSR2);
				break;

			case 's':
			case 'S':
				_d("Cannot enter bootstrap after boot ...");
				rq.runlevel = '1';
				/* Fall through to regular processing */

			case '1'...'5':
			case '7'...'9':
				_d("Setting new runlevel %c", rq.runlevel);
				service_runlevel(rq.runlevel - '0');
				break;

			case '6':
				_d("Rebooting system (SIGUSR1)");
				do_shutdown(SIGUSR1);
				break;

			default:
				_d("Unsupported runlevel: %d", rq.runlevel);
				break;
			}
			break;

		case INIT_CMD_DEBUG:
			debug = !debug;
			if (debug)
				silent = 0;
			else
				silent = quiet ? 1 : SILENT_MODE;
			break;

		case INIT_CMD_RELOAD: /* 'init q' and 'initctl reload' */
			service_reload_dynamic();
			break;

		case INIT_CMD_START_SVC:
			result = do_start(rq.data, sizeof(rq.data));
			break;

		case INIT_CMD_STOP_SVC:
			result = do_pause(rq.data, sizeof(rq.data));
			break;

		case INIT_CMD_RESTART_SVC:
			result = do_restart(rq.data, sizeof(rq.data));
			break;

#ifndef INETD_DISABLED
		case INIT_CMD_QUERY_INETD:
			result = do_query_inetd(rq.data, sizeof(rq.data));
			break;
#endif

		case INIT_CMD_EMIT:
			result = do_handle_emit(rq.data, sizeof(rq.data));
			break;

		case INIT_CMD_GET_RUNLEVEL:
			rq.runlevel = runlevel;
			result = 0;
			break;

		case INIT_CMD_ACK:
			_d("Client failed reading ACK.");
			goto leave;

		default:
			_d("Unsupported cmd: %d", rq.cmd);
			break;
		}

		if (result)
			rq.cmd = INIT_CMD_NACK;
		else
			rq.cmd = INIT_CMD_ACK;
		len = write(sd, &rq, sizeof(rq));
		if (len != sizeof(rq))
			_d("Failed sending ACK/NACK back to client.");
	}

leave:
	close(sd);
}
Пример #29
0
/* Standard reboot/shutdown utilities talk to init using /dev/initctl.
 * We should check if the fifo was recreated and reopen it.
 */
static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
{
	struct init_request rq;

	while (1) {
		ssize_t len = read(fd, &rq, sizeof(rq));

		if (len <= 0) {
			if (-1 == len) {
				if (EINTR == errno)
					continue;

				if (EAGAIN == errno)
					break;

				_e("Failed reading initctl request, error %d: %s", errno, strerror(errno));
			}

			_d("Nothing to do, bailing out.");
			break;
		}

		if (rq.magic != INIT_MAGIC || len != sizeof(rq)) {
			_e("Invalid initctl request.");
			break;
		}

		switch (rq.cmd) {
		case INIT_CMD_RUNLVL:
			switch (rq.runlevel) {
			case '0':
				_d("Halting system (SIGUSR2)");
				do_shutdown(SIGUSR2);
				break;

			case 's':
			case 'S':
				_d("Cannot enter bootstrap after boot ...");
				rq.runlevel = '1';
				/* Fall through to regular processing */

			case '1'...'5':
			case '7'...'9':
				_d("Setting new runlevel %c", rq.runlevel);
				service_runlevel(rq.runlevel - '0');
				break;

			case '6':
				_d("Rebooting system (SIGUSR1)");
				do_shutdown(SIGUSR1);
				break;

			default:
				_d("Unsupported runlevel: %d", rq.runlevel);
				break;
			}
			break;

		case INIT_CMD_RELOAD:
			service_reload_dynamic();
			break;

		default:
			_d("Unsupported cmd: %d", rq.cmd);
			break;
		}
	}

	close(fd);
	fifo_open();
}
Пример #30
0
/*
 * SIGSEGV: mostly if service callbacks segfault
 */
static void sigsegv_cb(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
{
	_e("PID %d caused a segfault!\n", getpid());
	exit(-1);
}