Remove multicall binary structure from OpenRC
This eliminates the need for the selinux-specific wrapper scrript we were installing in /lib*/rc/{bin,sbin}.
This commit is contained in:
parent
fe485f4433
commit
bf2f40828e
@ -53,6 +53,9 @@
|
||||
} while (/* CONSTCOND */ 0)
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
_unused static void *xmalloc (size_t size)
|
||||
{
|
||||
void *value = malloc(size);
|
||||
@ -104,4 +107,18 @@ _unused static const char *basename_c(const char *path)
|
||||
return (path);
|
||||
}
|
||||
|
||||
_unused static bool exists(const char *pathname)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
return (stat(pathname, &buf) == 0);
|
||||
}
|
||||
|
||||
_unused static bool existss(const char *pathname)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
return (stat(pathname, &buf) == 0 && buf.st_size != 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "helpers.h"
|
||||
#include "rc.h"
|
||||
|
||||
#define RC_LEVEL_BOOT "boot"
|
||||
#define RC_LEVEL_DEFAULT "default"
|
||||
@ -41,20 +42,6 @@
|
||||
#define RC_SVCDIR_STARTED RC_SVCDIR "/started"
|
||||
#define RC_SVCDIR_COLDPLUGGED RC_SVCDIR "/coldplugged"
|
||||
|
||||
_unused static bool exists(const char *pathname)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
return (stat(pathname, &buf) == 0);
|
||||
}
|
||||
|
||||
_unused static bool existss(const char *pathname)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
return (stat(pathname, &buf) == 0 && buf.st_size != 0);
|
||||
}
|
||||
|
||||
char *rc_conf_value(const char *var);
|
||||
bool rc_conf_yesno(const char *var);
|
||||
void env_filter(void);
|
||||
@ -78,4 +65,13 @@ const char *detect_prefix(void);
|
||||
const char *get_systype(void);
|
||||
const char *detect_container(void);
|
||||
const char *detect_vm(void);
|
||||
|
||||
/* Handy function so we can wrap einfo around our deptree */
|
||||
RC_DEPTREE *_rc_deptree_load (int, int *);
|
||||
|
||||
/* Test to see if we can see pid 1 or not */
|
||||
bool _rc_can_find_pids(void);
|
||||
|
||||
RC_SERVICE lookup_service_state(const char *service);
|
||||
|
||||
#endif
|
||||
|
133
src/rc/Makefile
133
src/rc/Makefile
@ -1,8 +1,4 @@
|
||||
PROG= openrc
|
||||
SRCS= checkpath.c fstabinfo.c mountinfo.c openrc-run.c \
|
||||
rc-applets.c rc-depend.c rc-logger.c \
|
||||
rc-misc.c rc-plugin.c rc-service.c rc-status.c rc-update.c \
|
||||
rc.c start-stop-daemon.c swclock.c
|
||||
SRCS= rc.c rc-logger.c rc-misc.c rc-plugin.c
|
||||
|
||||
ifeq (${MKSELINUX},yes)
|
||||
SRCS+= rc-selinux.c
|
||||
@ -14,26 +10,26 @@ BINDIR= ${PREFIX}/bin
|
||||
SBINDIR= ${PREFIX}/sbin
|
||||
LINKDIR= ${LIBEXECDIR}
|
||||
|
||||
BINLINKS= rc-status
|
||||
SBINLINKS= rc rc-service rc-update openrc-run runscript service \
|
||||
start-stop-daemon
|
||||
RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
||||
eindent eoutdent esyslog eval_ecolors ewaitfile \
|
||||
veinfo vewarn vebegin veend vewend veindent veoutdent \
|
||||
service_starting service_started \
|
||||
service_stopping service_stopped \
|
||||
service_inactive service_wasinactive \
|
||||
service_hotplugged service_started_daemon service_crashed \
|
||||
checkpath fstabinfo mountinfo rc-depend \
|
||||
service_get_value service_set_value get_options save_options \
|
||||
shell_var is_newer_than is_older_than
|
||||
RC_SBINLINKS= mark_service_starting mark_service_started \
|
||||
BINPROGS= rc-status
|
||||
SBINPROGS = openrc openrc-run rc rc-service rc-update runscript service start-stop-daemon
|
||||
RC_BINPROGS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
||||
eindent eoutdent esyslog eval_ecolors ewaitfile \
|
||||
veinfo vewarn vebegin veend vewend veindent veoutdent \
|
||||
checkpath fstabinfo mountinfo rc-depend \
|
||||
is_newer_than is_older_than \
|
||||
service_get_value service_set_value get_options save_options \
|
||||
service_starting service_started \
|
||||
service_stopping service_stopped \
|
||||
service_inactive service_wasinactive \
|
||||
service_hotplugged service_started_daemon service_crashed \
|
||||
shell_var
|
||||
RC_SBINPROGS= mark_service_starting mark_service_started \
|
||||
mark_service_stopping mark_service_stopped \
|
||||
mark_service_inactive mark_service_wasinactive \
|
||||
mark_service_hotplugged mark_service_failed \
|
||||
rc-abort swclock
|
||||
ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS}
|
||||
CLEANFILES+= ${ALL_LINKS}
|
||||
ALL_PROGS= ${BINPROGS} ${SBINPROGS} ${RC_BINPROGS} ${RC_SBINPROGS}
|
||||
CLEANFILES+= ${ALL_PROGS}
|
||||
|
||||
LOCAL_CPPFLAGS=-I../includes -I../librc -I../libeinfo
|
||||
LOCAL_LDFLAGS=-L../librc -L../libeinfo
|
||||
@ -49,22 +45,6 @@ include ${MK}/termcap.mk
|
||||
LDADD+= ${LIBDL} ${LIBKVM}
|
||||
include ${MK}/pam.mk
|
||||
|
||||
# create symlinks to rc if not an SELINUX system, otherwise create a wrapper
|
||||
# script to call rc with the proper name of the applet to execute.
|
||||
# $1 is a list of the links
|
||||
# $2 is the path+name of the target to link to (usually 'rc' or '/sbin/rc')
|
||||
# $3 is the path where the links are created
|
||||
define make-links
|
||||
for x in $(1); do \
|
||||
if [ "${MKSELINUX}" = yes ]; then \
|
||||
printf '#!/bin/sh\nexec ${2} --applet %s "$$@"\n' $$x >${3}/$$x; \
|
||||
chmod ${BINMODE} ${3}/$$x; \
|
||||
else \
|
||||
ln -sf ${2} ${3}/$$x; \
|
||||
fi; \
|
||||
done;
|
||||
endef
|
||||
|
||||
${SRCS}: version.h
|
||||
|
||||
.PHONY: version.h.tmp
|
||||
@ -79,15 +59,13 @@ version.h: version.h.tmp
|
||||
|
||||
install: all
|
||||
${INSTALL} -d ${DESTDIR}${SBINDIR}
|
||||
${INSTALL} -m ${BINMODE} ${PROG} ${DESTDIR}${SBINDIR}
|
||||
${INSTALL} -m ${BINMODE} ${SBINPROGS} ${DESTDIR}${SBINDIR}
|
||||
${INSTALL} -d ${DESTDIR}${BINDIR}
|
||||
$(call make-links,${BINLINKS},${SBINDIR}/${PROG},${DESTDIR}${BINDIR})
|
||||
${INSTALL} -d ${DESTDIR}${SBINDIR}
|
||||
$(call make-links,${SBINLINKS},${SBINDIR}/${PROG},${DESTDIR}${SBINDIR})
|
||||
${INSTALL} -m ${BINMODE} ${BINPROGS} ${DESTDIR}${BINDIR}
|
||||
${INSTALL} -d ${DESTDIR}${LINKDIR}/bin
|
||||
$(call make-links,${RC_BINLINKS},${SBINDIR}/${PROG},${DESTDIR}${LINKDIR}/bin)
|
||||
${INSTALL} -m ${BINMODE} ${RC_BINPROGS} ${DESTDIR}${LINKDIR}/bin
|
||||
${INSTALL} -d ${DESTDIR}${LINKDIR}/sbin
|
||||
$(call make-links, ${RC_SBINLINKS},${SBINDIR}/${PROG},${DESTDIR}${LINKDIR}/sbin)
|
||||
${INSTALL} -m ${BINMODE} ${RC_SBINPROGS} ${DESTDIR}${LINKDIR}/sbin
|
||||
if test "${MKPAM}" = pam; then \
|
||||
${INSTALL} -d ${DESTDIR}${PAMDIR}; \
|
||||
${INSTALL} -m ${PAMMODE} start-stop-daemon.pam ${DESTDIR}${PAMDIR}/start-stop-daemon; \
|
||||
@ -95,5 +73,70 @@ install: all
|
||||
|
||||
check test::
|
||||
|
||||
links: ${PROG}
|
||||
$(call make-links,${ALL_LINKS},${PROG},.)
|
||||
all: ${ALL_PROGS}
|
||||
|
||||
checkpath: checkpath.o _usage.o rc-misc.o rc-selinux.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
||||
eindent eoutdent esyslog eval_ecolors ewaitfile \
|
||||
veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
fstabinfo: fstabinfo.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
is_newer_than: is_newer_than.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
is_older_than: is_older_than.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
mark_service_starting mark_service_started \
|
||||
mark_service_stopping mark_service_stopped \
|
||||
mark_service_inactive mark_service_wasinactive \
|
||||
mark_service_hotplugged mark_service_failed: do_mark_service.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
mountinfo: mountinfo.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o rc-selinux.o _usage.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
rc-abort: rc-abort.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ -leinfo
|
||||
|
||||
rc-depend: rc-depend.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
rc-status: rc-status.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
rc-service service: rc-service.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
rc-update: rc-update.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
service_get_value service_set_value get_options save_options: do_value.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
service_starting service_started \
|
||||
service_stopping service_stopped \
|
||||
service_inactive service_wasinactive \
|
||||
service_hotplugged service_started_daemon \
|
||||
service_crashed: do_service.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
||||
shell_var: shell_var.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^
|
||||
|
||||
swclock: swclock.o _usage.o rc-misc.o
|
||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||
|
@ -10,8 +10,12 @@
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "version.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rc-misc.h"
|
||||
#include "_usage.h"
|
||||
#include "version.h"
|
||||
|
||||
#if lint
|
||||
# define _noreturn
|
||||
@ -22,7 +26,7 @@
|
||||
# define _noreturn
|
||||
#endif
|
||||
|
||||
static void set_quiet_options(void)
|
||||
void set_quiet_options(void)
|
||||
{
|
||||
static int qcount = 0;
|
||||
|
||||
@ -37,8 +41,7 @@ static void set_quiet_options(void)
|
||||
}
|
||||
}
|
||||
|
||||
_noreturn static void
|
||||
show_version(void)
|
||||
_noreturn void show_version(void)
|
||||
{
|
||||
const char *systype = NULL;
|
||||
|
||||
@ -56,8 +59,7 @@ show_version(void)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
_noreturn static void
|
||||
usage(int exit_status)
|
||||
_noreturn void usage(int exit_status)
|
||||
{
|
||||
const char * const has_arg[] = { "", "<arg>", "[arg]" };
|
||||
int i;
|
||||
@ -67,15 +69,15 @@ usage(int exit_status)
|
||||
char *token;
|
||||
char val[4] = "-?,";
|
||||
|
||||
#ifdef usagestring
|
||||
printf(usagestring);
|
||||
#else
|
||||
printf("Usage: %s [options] ", applet);
|
||||
#endif
|
||||
#ifdef extraopts
|
||||
printf(extraopts);
|
||||
#endif
|
||||
printf("\n\nOptions: [" getoptstring "]\n");
|
||||
if (usagestring)
|
||||
printf("%s", usagestring);
|
||||
else
|
||||
printf("Usage: %s [options] ", applet);
|
||||
|
||||
if (extraopts)
|
||||
printf("%s", extraopts);
|
||||
|
||||
printf("\n\nOptions: [ %s ]\n", getoptstring);
|
||||
for (i = 0; longopts[i].name; ++i) {
|
||||
val[1] = longopts[i].val;
|
||||
len = printf(" %3s --%s %s", isprint(longopts[i].val) ? val : "",
|
||||
|
@ -10,6 +10,8 @@
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#define getoptstring_COMMON "ChqVv"
|
||||
|
||||
#define longopts_COMMON \
|
||||
@ -41,3 +43,14 @@
|
||||
case 'v': case_RC_COMMON_getopt_case_v; break; \
|
||||
case 'q': case_RC_COMMON_getopt_case_q; break; \
|
||||
default: case_RC_COMMON_getopt_default; break;
|
||||
|
||||
extern const char *applet;
|
||||
extern const char *extraopts;
|
||||
extern const char *getoptstring;
|
||||
extern const struct option longopts[];
|
||||
extern const char * const longopts_help[];
|
||||
extern const char *usagestring;
|
||||
|
||||
void set_quiet_options(void);
|
||||
void show_version(void);
|
||||
void usage(int exit_status);
|
||||
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2015 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
|
||||
int checkpath(int, char **);
|
||||
int fstabinfo(int, char **);
|
||||
int mountinfo(int, char **);
|
||||
int openrc_run(int, char **);
|
||||
int rc_depend(int, char **);
|
||||
int rc_service(int, char **);
|
||||
int rc_status(int, char **);
|
||||
int rc_update(int, char **);
|
||||
int runscript(int, char **);
|
||||
int start_stop_daemon(int, char **);
|
||||
int swclock(int, char **);
|
||||
|
||||
void run_applets(int, char **);
|
||||
|
||||
/* Handy function so we can wrap einfo around our deptree */
|
||||
RC_DEPTREE *_rc_deptree_load (int, int *);
|
||||
|
||||
/* Test to see if we can see pid 1 or not */
|
||||
bool _rc_can_find_pids(void);
|
@ -29,10 +29,10 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "rc-misc.h"
|
||||
#include "rc-selinux.h"
|
||||
#include "_usage.h"
|
||||
|
||||
typedef enum {
|
||||
inode_unknown = 0,
|
||||
@ -41,7 +41,32 @@ typedef enum {
|
||||
inode_fifo = 3,
|
||||
} inode_t;
|
||||
|
||||
extern const char *applet;
|
||||
const char *applet = NULL;
|
||||
const char *extraopts ="path1 [path2] [...]";
|
||||
const char *getoptstring = "dDfFpm:o:W" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "directory", 0, NULL, 'd'},
|
||||
{ "directory-truncate", 0, NULL, 'D'},
|
||||
{ "file", 0, NULL, 'f'},
|
||||
{ "file-truncate", 0, NULL, 'F'},
|
||||
{ "pipe", 0, NULL, 'p'},
|
||||
{ "mode", 1, NULL, 'm'},
|
||||
{ "owner", 1, NULL, 'o'},
|
||||
{ "writable", 0, NULL, 'W'},
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"Create a directory if not exists",
|
||||
"Create/empty directory",
|
||||
"Create a file if not exists",
|
||||
"Truncate file",
|
||||
"Create a named pipe (FIFO) if not exists",
|
||||
"Mode to check",
|
||||
"Owner to check (user:group)",
|
||||
"Check whether the path is writable or not",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
const char *usagestring = NULL;
|
||||
|
||||
static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
|
||||
inode_t type, bool trunc, bool chowner, bool selinux_on)
|
||||
@ -187,34 +212,7 @@ static int parse_owner(struct passwd **user, struct group **group,
|
||||
return retval;
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define extraopts "path1 [path2] [...]"
|
||||
#define getoptstring "dDfFpm:o:W" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "directory", 0, NULL, 'd'},
|
||||
{ "directory-truncate", 0, NULL, 'D'},
|
||||
{ "file", 0, NULL, 'f'},
|
||||
{ "file-truncate", 0, NULL, 'F'},
|
||||
{ "pipe", 0, NULL, 'p'},
|
||||
{ "mode", 1, NULL, 'm'},
|
||||
{ "owner", 1, NULL, 'o'},
|
||||
{ "writable", 0, NULL, 'W'},
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"Create a directory if not exists",
|
||||
"Create/empty directory",
|
||||
"Create a file if not exists",
|
||||
"Truncate file",
|
||||
"Create a named pipe (FIFO) if not exists",
|
||||
"Mode to check",
|
||||
"Owner to check (user:group)",
|
||||
"Check whether the path is writable or not",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
int checkpath(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
uid_t uid = geteuid();
|
||||
@ -229,6 +227,7 @@ int checkpath(int argc, char **argv)
|
||||
bool writable = false;
|
||||
bool selinux_on = false;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||
longopts, (int *) 0)) != -1)
|
||||
{
|
||||
|
228
src/rc/do_e.c
Normal file
228
src/rc/do_e.c
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2015 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#define SYSLOG_NAMES
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "einfo.h"
|
||||
#include "helpers.h"
|
||||
|
||||
/* usecs to wait while we poll the file existance */
|
||||
#define WAIT_INTERVAL 20000000
|
||||
|
||||
const char *applet = NULL;
|
||||
|
||||
static int syslog_decode(char *name, CODE *codetab)
|
||||
{
|
||||
CODE *c;
|
||||
|
||||
if (isdigit((unsigned char)*name))
|
||||
return atoi(name);
|
||||
|
||||
for (c = codetab; c->c_name; c++)
|
||||
if (! strcasecmp(name, c->c_name))
|
||||
return c->c_val;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int retval = EXIT_SUCCESS;
|
||||
int i;
|
||||
size_t l = 0;
|
||||
char *message = NULL;
|
||||
char *p;
|
||||
int level = 0;
|
||||
struct timespec ts;
|
||||
struct timeval stop, now;
|
||||
int (*e) (const char *, ...) EINFO_PRINTF(1, 2) = NULL;
|
||||
int (*ee) (int, const char *, ...) EINFO_PRINTF(2, 3) = NULL;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (strcmp(applet, "eval_ecolors") == 0) {
|
||||
printf("GOOD='%s'\nWARN='%s'\nBAD='%s'\nHILITE='%s'\nBRACKET='%s'\nNORMAL='%s'\n",
|
||||
ecolor(ECOLOR_GOOD),
|
||||
ecolor(ECOLOR_WARN),
|
||||
ecolor(ECOLOR_BAD),
|
||||
ecolor(ECOLOR_HILITE),
|
||||
ecolor(ECOLOR_BRACKET),
|
||||
ecolor(ECOLOR_NORMAL));
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
if (strcmp(applet, "eend") == 0 ||
|
||||
strcmp(applet, "ewend") == 0 ||
|
||||
strcmp(applet, "veend") == 0 ||
|
||||
strcmp(applet, "vweend") == 0 ||
|
||||
strcmp(applet, "ewaitfile") == 0)
|
||||
{
|
||||
errno = 0;
|
||||
retval = (int)strtoimax(argv[0], &p, 0);
|
||||
if (!p || *p != '\0')
|
||||
errno = EINVAL;
|
||||
if (errno)
|
||||
retval = EXIT_FAILURE;
|
||||
else {
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
} else if (strcmp(applet, "esyslog") == 0 ||
|
||||
strcmp(applet, "elog") == 0) {
|
||||
p = strchr(argv[0], '.');
|
||||
if (!p ||
|
||||
(level = syslog_decode(p + 1, prioritynames)) == -1)
|
||||
eerrorx("%s: invalid log level `%s'", applet, argv[0]);
|
||||
|
||||
if (argc < 3)
|
||||
eerrorx("%s: not enough arguments", applet);
|
||||
|
||||
unsetenv("EINFO_LOG");
|
||||
setenv("EINFO_LOG", argv[1], 1);
|
||||
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(applet, "ewaitfile") == 0) {
|
||||
if (errno)
|
||||
eerrorx("%s: invalid timeout", applet);
|
||||
if (argc == 0)
|
||||
eerrorx("%s: not enough arguments", applet);
|
||||
|
||||
gettimeofday(&stop, NULL);
|
||||
/* retval stores the timeout */
|
||||
stop.tv_sec += retval;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = WAIT_INTERVAL;
|
||||
for (i = 0; i < argc; i++) {
|
||||
ebeginv("Waiting for %s", argv[i]);
|
||||
for (;;) {
|
||||
if (exists(argv[i]))
|
||||
break;
|
||||
if (nanosleep(&ts, NULL) == -1)
|
||||
return EXIT_FAILURE;
|
||||
gettimeofday(&now, NULL);
|
||||
if (retval <= 0)
|
||||
continue;
|
||||
if (timercmp(&now, &stop, <))
|
||||
continue;
|
||||
eendv(EXIT_FAILURE,
|
||||
"timed out waiting for %s", argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
eendv(EXIT_SUCCESS, NULL);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
for (i = 0; i < argc; i++)
|
||||
l += strlen(argv[i]) + 1;
|
||||
|
||||
message = xmalloc(l);
|
||||
p = message;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (i > 0)
|
||||
*p++ = ' ';
|
||||
l = strlen(argv[i]);
|
||||
memcpy(p, argv[i], l);
|
||||
p += l;
|
||||
}
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if (strcmp(applet, "einfo") == 0)
|
||||
e = einfo;
|
||||
else if (strcmp(applet, "einfon") == 0)
|
||||
e = einfon;
|
||||
else if (strcmp(applet, "ewarn") == 0)
|
||||
e = ewarn;
|
||||
else if (strcmp(applet, "ewarnn") == 0)
|
||||
e = ewarnn;
|
||||
else if (strcmp(applet, "eerror") == 0) {
|
||||
e = eerror;
|
||||
retval = 1;
|
||||
} else if (strcmp(applet, "eerrorn") == 0) {
|
||||
e = eerrorn;
|
||||
retval = 1;
|
||||
} else if (strcmp(applet, "ebegin") == 0)
|
||||
e = ebegin;
|
||||
else if (strcmp(applet, "eend") == 0)
|
||||
ee = eend;
|
||||
else if (strcmp(applet, "ewend") == 0)
|
||||
ee = ewend;
|
||||
else if (strcmp(applet, "esyslog") == 0) {
|
||||
elog(retval, "%s", message);
|
||||
retval = 0;
|
||||
} else if (strcmp(applet, "veinfo") == 0)
|
||||
e = einfov;
|
||||
else if (strcmp(applet, "veinfon") == 0)
|
||||
e = einfovn;
|
||||
else if (strcmp(applet, "vewarn") == 0)
|
||||
e = ewarnv;
|
||||
else if (strcmp(applet, "vewarnn") == 0)
|
||||
e = ewarnvn;
|
||||
else if (strcmp(applet, "vebegin") == 0)
|
||||
e = ebeginv;
|
||||
else if (strcmp(applet, "veend") == 0)
|
||||
ee = eendv;
|
||||
else if (strcmp(applet, "vewend") == 0)
|
||||
ee = ewendv;
|
||||
else if (strcmp(applet, "eindent") == 0)
|
||||
eindent();
|
||||
else if (strcmp(applet, "eoutdent") == 0)
|
||||
eoutdent();
|
||||
else if (strcmp(applet, "veindent") == 0)
|
||||
eindentv();
|
||||
else if (strcmp(applet, "veoutdent") == 0)
|
||||
eoutdentv();
|
||||
else {
|
||||
eerror("%s: unknown applet", applet);
|
||||
retval = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
if (e)
|
||||
e("%s", message);
|
||||
else if (ee)
|
||||
ee(retval, "%s", message);
|
||||
} else {
|
||||
if (e)
|
||||
e(NULL);
|
||||
else if (ee)
|
||||
ee(retval, NULL);
|
||||
}
|
||||
|
||||
free(message);
|
||||
return retval;
|
||||
}
|
91
src/rc/do_mark_service.c
Normal file
91
src/rc/do_mark_service.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2015 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "einfo.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
|
||||
const char *applet = NULL;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool ok = false;
|
||||
char *svcname = getenv("RC_SVCNAME");
|
||||
char *service = NULL;
|
||||
char *openrc_pid;
|
||||
/* char *mtime; */
|
||||
pid_t pid;
|
||||
RC_SERVICE bit;
|
||||
/* size_t l; */
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
if (argc > 1)
|
||||
service = argv[1];
|
||||
else
|
||||
service = svcname;
|
||||
|
||||
if (service == NULL || *service == '\0')
|
||||
eerrorx("%s: no service specified", applet);
|
||||
|
||||
if (!strncmp(applet, "mark_", 5) &&
|
||||
(bit = lookup_service_state(applet + 5)))
|
||||
ok = rc_service_mark(service, bit);
|
||||
else
|
||||
eerrorx("%s: unknown applet", applet);
|
||||
|
||||
/* If we're marking ourselves then we need to inform our parent
|
||||
openrc-run process so they do not mark us based on our exit code */
|
||||
/*
|
||||
* FIXME: svcname and service are almost always equal except called from a
|
||||
* shell with just argv[1] - So that doesn't seem to do what Roy initially
|
||||
* expected.
|
||||
* See 20120424041423.GA23657@odin.qasl.de (Tue, 24 Apr 2012 06:14:23 +0200,
|
||||
* openrc@gentoo.org).
|
||||
*/
|
||||
if (ok && svcname && strcmp(svcname, service) == 0) {
|
||||
openrc_pid = getenv("RC_OPENRC_PID");
|
||||
if (openrc_pid && sscanf(openrc_pid, "%d", &pid) == 1)
|
||||
if (kill(pid, SIGHUP) != 0)
|
||||
eerror("%s: failed to signal parent %d: %s",
|
||||
applet, pid, strerror(errno));
|
||||
|
||||
/* Remove the exclusive time test. This ensures that it's not
|
||||
in control as well */
|
||||
/*
|
||||
l = strlen(RC_SVCDIR "/exclusive") + strlen(svcname) +
|
||||
strlen(openrc_pid) + 4;
|
||||
mtime = xmalloc(l);
|
||||
snprintf(mtime, l, RC_SVCDIR "/exclusive/%s.%s",
|
||||
svcname, openrc_pid);
|
||||
if (exists(mtime) && unlink(mtime) != 0)
|
||||
eerror("%s: unlink: %s", applet, strerror(errno));
|
||||
free(mtime);
|
||||
*/
|
||||
}
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
78
src/rc/do_service.c
Normal file
78
src/rc/do_service.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2015 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "einfo.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
|
||||
const char *applet = NULL;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool ok = false;
|
||||
char *service;
|
||||
char *exec;
|
||||
int idx;
|
||||
RC_SERVICE state, bit;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
if (argc > 1)
|
||||
service = argv[1];
|
||||
else
|
||||
service = getenv("RC_SVCNAME");
|
||||
|
||||
if (service == NULL || *service == '\0')
|
||||
eerrorx("%s: no service specified", applet);
|
||||
|
||||
state = rc_service_state(service);
|
||||
bit = lookup_service_state(applet);
|
||||
if (bit) {
|
||||
ok = (state & bit);
|
||||
} else if (strcmp(applet, "service_started_daemon") == 0) {
|
||||
service = getenv("RC_SVCNAME");
|
||||
exec = argv[1];
|
||||
if (argc > 3) {
|
||||
service = argv[1];
|
||||
exec = argv[2];
|
||||
sscanf(argv[3], "%d", &idx);
|
||||
} else if (argc == 3) {
|
||||
if (sscanf(argv[2], "%d", &idx) != 1) {
|
||||
service = argv[1];
|
||||
exec = argv[2];
|
||||
}
|
||||
}
|
||||
ok = rc_service_started_daemon(service, exec, NULL, idx);
|
||||
|
||||
} else if (strcmp(applet, "service_crashed") == 0) {
|
||||
ok = (_rc_can_find_pids() &&
|
||||
rc_service_daemons_crashed(service) &&
|
||||
errno != EACCES);
|
||||
} else
|
||||
eerrorx("%s: unknown applet", applet);
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
64
src/rc/do_value.c
Normal file
64
src/rc/do_value.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#define SYSLOG_NAMES
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "einfo.h"
|
||||
#include "rc-misc.h"
|
||||
|
||||
const char *applet = NULL;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool ok = false;
|
||||
char *service = getenv("RC_SVCNAME");
|
||||
char *option;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
if (service == NULL)
|
||||
eerrorx("%s: no service specified", applet);
|
||||
|
||||
if (argc < 2 || ! argv[1] || *argv[1] == '\0')
|
||||
eerrorx("%s: no option specified", applet);
|
||||
|
||||
if (strcmp(applet, "service_get_value") == 0 ||
|
||||
strcmp(applet, "get_options") == 0)
|
||||
{
|
||||
option = rc_service_value_get(service, argv[1]);
|
||||
if (option) {
|
||||
printf("%s", option);
|
||||
free(option);
|
||||
ok = true;
|
||||
}
|
||||
} else if (strcmp(applet, "service_set_value") == 0 ||
|
||||
strcmp(applet, "save_options") == 0)
|
||||
ok = rc_service_value_set(service, argv[1], argv[2]);
|
||||
else
|
||||
eerrorx("%s: unknown applet", applet);
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
@ -55,11 +55,36 @@
|
||||
# define ENT_PASS(_ent) ent->fs_passno
|
||||
#endif
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
#include "_usage.h"
|
||||
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = NULL;
|
||||
const char *getoptstring = "MRbmop:t:" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "mount", 0, NULL, 'M' },
|
||||
{ "remount", 0, NULL, 'R' },
|
||||
{ "blockdevice", 0, NULL, 'b' },
|
||||
{ "mountargs", 0, NULL, 'm' },
|
||||
{ "options", 0, NULL, 'o' },
|
||||
{ "passno", 1, NULL, 'p' },
|
||||
{ "fstype", 1, NULL, 't' },
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"Mounts the filesytem from the mountpoint",
|
||||
"Remounts the filesystem based on the information in fstab",
|
||||
"Extract the block device",
|
||||
"Show arguments needed to mount the entry",
|
||||
"Extract the options field",
|
||||
"Extract or query the pass number field",
|
||||
"List entries with matching file system type",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
const char *usagestring = NULL;
|
||||
|
||||
#ifdef HAVE_GETMNTENT
|
||||
static struct mntent *
|
||||
@ -129,30 +154,6 @@ do_mount(struct ENT *ent, bool remount)
|
||||
}
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define getoptstring "MRbmop:t:" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "mount", 0, NULL, 'M' },
|
||||
{ "remount", 0, NULL, 'R' },
|
||||
{ "blockdevice", 0, NULL, 'b' },
|
||||
{ "mountargs", 0, NULL, 'm' },
|
||||
{ "options", 0, NULL, 'o' },
|
||||
{ "passno", 1, NULL, 'p' },
|
||||
{ "fstype", 1, NULL, 't' },
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"Mounts the filesytem from the mountpoint",
|
||||
"Remounts the filesystem based on the information in fstab",
|
||||
"Extract the block device",
|
||||
"Show arguments needed to mount the entry",
|
||||
"Extract the options field",
|
||||
"Extract or query the pass number field",
|
||||
"List entries with matching file system type",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
#define OUTPUT_FILE (1 << 1)
|
||||
#define OUTPUT_MOUNTARGS (1 << 2)
|
||||
#define OUTPUT_OPTIONS (1 << 3)
|
||||
@ -161,8 +162,7 @@ static const char * const longopts_help[] = {
|
||||
#define OUTPUT_MOUNT (1 << 6)
|
||||
#define OUTPUT_REMOUNT (1 << 7)
|
||||
|
||||
int
|
||||
fstabinfo(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct ENT *ent;
|
||||
int result = EXIT_SUCCESS;
|
||||
@ -181,6 +181,7 @@ fstabinfo(int argc, char **argv)
|
||||
/* Ensure that we are only quiet when explicitly told to be */
|
||||
unsetenv("EINFO_QUIET");
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||
longopts, (int *) 0)) != -1)
|
||||
{
|
||||
|
33
src/rc/is_newer_than.c
Normal file
33
src/rc/is_newer_than.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rc-misc.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc < 3)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* This test is correct as it's not present in baselayout */
|
||||
for (i = 2; i < argc; ++i)
|
||||
if (!rc_newer_than(argv[1], argv[i], NULL, NULL))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
34
src/rc/is_older_than.c
Normal file
34
src/rc/is_older_than.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rc-misc.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc < 3)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* This test is perverted - historically the baselayout function
|
||||
* returns 0 on *failure*, which is plain wrong */
|
||||
for (i = 2; i < argc; ++i)
|
||||
if (!rc_newer_than(argv[1], argv[i], NULL, NULL))
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
@ -39,13 +39,48 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
#include "_usage.h"
|
||||
|
||||
extern const char *applet;
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = "[mount1] [mount2] ...";
|
||||
const char *getoptstring = "f:F:n:N:o:O:p:P:iste:E:" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "fstype-regex", 1, NULL, 'f'},
|
||||
{ "skip-fstype-regex", 1, NULL, 'F'},
|
||||
{ "node-regex", 1, NULL, 'n'},
|
||||
{ "skip-node-regex", 1, NULL, 'N'},
|
||||
{ "options-regex", 1, NULL, 'o'},
|
||||
{ "skip-options-regex", 1, NULL, 'O'},
|
||||
{ "point-regex", 1, NULL, 'p'},
|
||||
{ "skip-point-regex", 1, NULL, 'P'},
|
||||
{ "options", 0, NULL, 'i'},
|
||||
{ "fstype", 0, NULL, 's'},
|
||||
{ "node", 0, NULL, 't'},
|
||||
{ "netdev", 0, NULL, 'e'},
|
||||
{ "nonetdev", 0, NULL, 'E'},
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"fstype regex to find",
|
||||
"fstype regex to skip",
|
||||
"node regex to find",
|
||||
"node regex to skip",
|
||||
"options regex to find",
|
||||
"options regex to skip",
|
||||
"point regex to find",
|
||||
"point regex to skip",
|
||||
"print options",
|
||||
"print fstype",
|
||||
"print node",
|
||||
"is it a network device",
|
||||
"is it not a network device",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
const char *usagestring = NULL;
|
||||
|
||||
typedef enum {
|
||||
mount_from,
|
||||
@ -334,45 +369,7 @@ get_regex(const char *string)
|
||||
return reg;
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define extraopts "[mount1] [mount2] ..."
|
||||
#define getoptstring "f:F:n:N:o:O:p:P:iste:E:" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "fstype-regex", 1, NULL, 'f'},
|
||||
{ "skip-fstype-regex", 1, NULL, 'F'},
|
||||
{ "node-regex", 1, NULL, 'n'},
|
||||
{ "skip-node-regex", 1, NULL, 'N'},
|
||||
{ "options-regex", 1, NULL, 'o'},
|
||||
{ "skip-options-regex", 1, NULL, 'O'},
|
||||
{ "point-regex", 1, NULL, 'p'},
|
||||
{ "skip-point-regex", 1, NULL, 'P'},
|
||||
{ "options", 0, NULL, 'i'},
|
||||
{ "fstype", 0, NULL, 's'},
|
||||
{ "node", 0, NULL, 't'},
|
||||
{ "netdev", 0, NULL, 'e'},
|
||||
{ "nonetdev", 0, NULL, 'E'},
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"fstype regex to find",
|
||||
"fstype regex to skip",
|
||||
"node regex to find",
|
||||
"node regex to skip",
|
||||
"options regex to find",
|
||||
"options regex to skip",
|
||||
"point regex to find",
|
||||
"point regex to skip",
|
||||
"print options",
|
||||
"print fstype",
|
||||
"print node",
|
||||
"is it a network device",
|
||||
"is it not a network device",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
int
|
||||
mountinfo(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct args args;
|
||||
regex_t *point_regex = NULL;
|
||||
@ -390,6 +387,7 @@ mountinfo(int argc, char **argv)
|
||||
#define REG_FREE(_var) \
|
||||
if (_var) { regfree(_var); free(_var); }
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
memset (&args, 0, sizeof(args));
|
||||
args.mount_type = mount_to;
|
||||
args.netdev = net_ignore;
|
||||
|
@ -47,13 +47,13 @@
|
||||
# include <libutil.h>
|
||||
#endif
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
#include "rc-plugin.h"
|
||||
#include "rc-selinux.h"
|
||||
#include "_usage.h"
|
||||
|
||||
#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
|
||||
|
||||
@ -61,7 +61,29 @@
|
||||
#define WAIT_TIMEOUT 60 /* seconds until we timeout */
|
||||
#define WARN_TIMEOUT 10 /* warn about this every N seconds */
|
||||
|
||||
static const char *applet;
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = "stop | start | restart | describe | zap";
|
||||
const char *getoptstring = "dDsSvl:Z" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "debug", 0, NULL, 'd'},
|
||||
{ "dry-run", 0, NULL, 'Z'},
|
||||
{ "ifstarted", 0, NULL, 's'},
|
||||
{ "ifstopped", 0, NULL, 'S'},
|
||||
{ "nodeps", 0, NULL, 'D'},
|
||||
{ "lockfd", 1, NULL, 'l'},
|
||||
longopts_COMMON
|
||||
};
|
||||
const char *const longopts_help[] = {
|
||||
"set xtrace when running the script",
|
||||
"show what would be done",
|
||||
"only run commands when started",
|
||||
"only run commands when stopped",
|
||||
"ignore dependencies",
|
||||
"fd of the exclusive lock from rc",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
const char *usagestring = NULL;
|
||||
|
||||
static char *service, *runlevel, *ibsave, *prefix;
|
||||
static RC_DEPTREE *deptree;
|
||||
static RC_STRINGLIST *applet_list, *services, *tmplist;
|
||||
@ -1063,31 +1085,7 @@ service_plugable(void)
|
||||
return allow;
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define getoptstring "dDsSvl:Z" getoptstring_COMMON
|
||||
#define extraopts "stop | start | restart | describe | zap"
|
||||
static const struct option longopts[] = {
|
||||
{ "debug", 0, NULL, 'd'},
|
||||
{ "dry-run", 0, NULL, 'Z'},
|
||||
{ "ifstarted", 0, NULL, 's'},
|
||||
{ "ifstopped", 0, NULL, 'S'},
|
||||
{ "nodeps", 0, NULL, 'D'},
|
||||
{ "lockfd", 1, NULL, 'l'},
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char *const longopts_help[] = {
|
||||
"set xtrace when running the script",
|
||||
"show what would be done",
|
||||
"only run commands when started",
|
||||
"only run commands when stopped",
|
||||
"ignore dependencies",
|
||||
"fd of the exclusive lock from rc",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
int
|
||||
openrc_run(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool doneone = false;
|
||||
int retval, opt, depoptions = RC_DEP_TRACE;
|
||||
@ -1396,10 +1394,3 @@ openrc_run(int argc, char **argv)
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
runscript(int argc, char **argv)
|
||||
{
|
||||
ewarnv("runscript is deprecated; please use openrc-run instead.");
|
||||
return (openrc_run(argc, argv));
|
||||
}
|
||||
|
43
src/rc/rc-abort.c
Normal file
43
src/rc/rc-abort.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2015 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "einfo.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const char *p = getenv("RC_PID");
|
||||
int pid;
|
||||
|
||||
if (p && sscanf(p, "%d", &pid) == 1) {
|
||||
if (kill(pid, SIGUSR1) != 0)
|
||||
eerrorx("rc-abort: failed to signal parent %d: %s",
|
||||
pid, strerror(errno));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
@ -1,557 +0,0 @@
|
||||
/*
|
||||
* rc-applets.c
|
||||
*
|
||||
* Handle multicall applets for use in our init scripts.
|
||||
* Basically this makes us a lot faster for the most part, and removes
|
||||
* any shell incompatabilities we might otherwise encounter.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2015 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#define SYSLOG_NAMES
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "rc-misc.h"
|
||||
|
||||
/* usecs to wait while we poll the file existance */
|
||||
#define WAIT_INTERVAL 20000000
|
||||
#define ONE_SECOND 690000000
|
||||
|
||||
/* Applet is first parsed in rc.c - no point in doing it again */
|
||||
extern const char *applet;
|
||||
|
||||
static int
|
||||
syslog_decode(char *name, CODE *codetab)
|
||||
{
|
||||
CODE *c;
|
||||
|
||||
if (isdigit((unsigned char)*name))
|
||||
return atoi(name);
|
||||
|
||||
for (c = codetab; c->c_name; c++)
|
||||
if (! strcasecmp(name, c->c_name))
|
||||
return c->c_val;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
do_e(int argc, char **argv)
|
||||
{
|
||||
int retval = EXIT_SUCCESS;
|
||||
int i;
|
||||
size_t l = 0;
|
||||
char *message = NULL;
|
||||
char *p;
|
||||
int level = 0;
|
||||
struct timespec ts;
|
||||
struct timeval stop, now;
|
||||
int (*e) (const char *, ...) EINFO_PRINTF(1, 2) = NULL;
|
||||
int (*ee) (int, const char *, ...) EINFO_PRINTF(2, 3) = NULL;
|
||||
|
||||
/* Punt applet */
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (strcmp(applet, "eval_ecolors") == 0) {
|
||||
printf("GOOD='%s'\nWARN='%s'\nBAD='%s'\nHILITE='%s'\nBRACKET='%s'\nNORMAL='%s'\n",
|
||||
ecolor(ECOLOR_GOOD),
|
||||
ecolor(ECOLOR_WARN),
|
||||
ecolor(ECOLOR_BAD),
|
||||
ecolor(ECOLOR_HILITE),
|
||||
ecolor(ECOLOR_BRACKET),
|
||||
ecolor(ECOLOR_NORMAL));
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
if (strcmp(applet, "eend") == 0 ||
|
||||
strcmp(applet, "ewend") == 0 ||
|
||||
strcmp(applet, "veend") == 0 ||
|
||||
strcmp(applet, "vweend") == 0 ||
|
||||
strcmp(applet, "ewaitfile") == 0)
|
||||
{
|
||||
errno = 0;
|
||||
retval = (int)strtoimax(argv[0], &p, 0);
|
||||
if (!p || *p != '\0')
|
||||
errno = EINVAL;
|
||||
if (errno)
|
||||
retval = EXIT_FAILURE;
|
||||
else {
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
} else if (strcmp(applet, "esyslog") == 0 ||
|
||||
strcmp(applet, "elog") == 0) {
|
||||
p = strchr(argv[0], '.');
|
||||
if (!p ||
|
||||
(level = syslog_decode(p + 1, prioritynames)) == -1)
|
||||
eerrorx("%s: invalid log level `%s'", applet, argv[0]);
|
||||
|
||||
if (argc < 3)
|
||||
eerrorx("%s: not enough arguments", applet);
|
||||
|
||||
unsetenv("EINFO_LOG");
|
||||
setenv("EINFO_LOG", argv[1], 1);
|
||||
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(applet, "ewaitfile") == 0) {
|
||||
if (errno)
|
||||
eerrorx("%s: invalid timeout", applet);
|
||||
if (argc == 0)
|
||||
eerrorx("%s: not enough arguments", applet);
|
||||
|
||||
gettimeofday(&stop, NULL);
|
||||
/* retval stores the timeout */
|
||||
stop.tv_sec += retval;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = WAIT_INTERVAL;
|
||||
for (i = 0; i < argc; i++) {
|
||||
ebeginv("Waiting for %s", argv[i]);
|
||||
for (;;) {
|
||||
if (exists(argv[i]))
|
||||
break;
|
||||
if (nanosleep(&ts, NULL) == -1)
|
||||
return EXIT_FAILURE;
|
||||
gettimeofday(&now, NULL);
|
||||
if (retval <= 0)
|
||||
continue;
|
||||
if (timercmp(&now, &stop, <))
|
||||
continue;
|
||||
eendv(EXIT_FAILURE,
|
||||
"timed out waiting for %s", argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
eendv(EXIT_SUCCESS, NULL);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
for (i = 0; i < argc; i++)
|
||||
l += strlen(argv[i]) + 1;
|
||||
|
||||
message = xmalloc(l);
|
||||
p = message;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (i > 0)
|
||||
*p++ = ' ';
|
||||
l = strlen(argv[i]);
|
||||
memcpy(p, argv[i], l);
|
||||
p += l;
|
||||
}
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if (strcmp(applet, "einfo") == 0)
|
||||
e = einfo;
|
||||
else if (strcmp(applet, "einfon") == 0)
|
||||
e = einfon;
|
||||
else if (strcmp(applet, "ewarn") == 0)
|
||||
e = ewarn;
|
||||
else if (strcmp(applet, "ewarnn") == 0)
|
||||
e = ewarnn;
|
||||
else if (strcmp(applet, "eerror") == 0) {
|
||||
e = eerror;
|
||||
retval = 1;
|
||||
} else if (strcmp(applet, "eerrorn") == 0) {
|
||||
e = eerrorn;
|
||||
retval = 1;
|
||||
} else if (strcmp(applet, "ebegin") == 0)
|
||||
e = ebegin;
|
||||
else if (strcmp(applet, "eend") == 0)
|
||||
ee = eend;
|
||||
else if (strcmp(applet, "ewend") == 0)
|
||||
ee = ewend;
|
||||
else if (strcmp(applet, "esyslog") == 0) {
|
||||
elog(retval, "%s", message);
|
||||
retval = 0;
|
||||
} else if (strcmp(applet, "veinfo") == 0)
|
||||
e = einfov;
|
||||
else if (strcmp(applet, "veinfon") == 0)
|
||||
e = einfovn;
|
||||
else if (strcmp(applet, "vewarn") == 0)
|
||||
e = ewarnv;
|
||||
else if (strcmp(applet, "vewarnn") == 0)
|
||||
e = ewarnvn;
|
||||
else if (strcmp(applet, "vebegin") == 0)
|
||||
e = ebeginv;
|
||||
else if (strcmp(applet, "veend") == 0)
|
||||
ee = eendv;
|
||||
else if (strcmp(applet, "vewend") == 0)
|
||||
ee = ewendv;
|
||||
else if (strcmp(applet, "eindent") == 0)
|
||||
eindent();
|
||||
else if (strcmp(applet, "eoutdent") == 0)
|
||||
eoutdent();
|
||||
else if (strcmp(applet, "veindent") == 0)
|
||||
eindentv();
|
||||
else if (strcmp(applet, "veoutdent") == 0)
|
||||
eoutdentv();
|
||||
else {
|
||||
eerror("%s: unknown applet", applet);
|
||||
retval = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
if (e)
|
||||
e("%s", message);
|
||||
else if (ee)
|
||||
ee(retval, "%s", message);
|
||||
} else {
|
||||
if (e)
|
||||
e(NULL);
|
||||
else if (ee)
|
||||
ee(retval, NULL);
|
||||
}
|
||||
|
||||
free(message);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char * const name;
|
||||
RC_SERVICE bit;
|
||||
} service_bits[] = {
|
||||
{ "service_started", RC_SERVICE_STARTED, },
|
||||
{ "service_stopped", RC_SERVICE_STOPPED, },
|
||||
{ "service_inactive", RC_SERVICE_INACTIVE, },
|
||||
{ "service_starting", RC_SERVICE_STARTING, },
|
||||
{ "service_stopping", RC_SERVICE_STOPPING, },
|
||||
{ "service_hotplugged", RC_SERVICE_HOTPLUGGED, },
|
||||
{ "service_wasinactive", RC_SERVICE_WASINACTIVE, },
|
||||
{ "service_failed", RC_SERVICE_FAILED, },
|
||||
};
|
||||
|
||||
static RC_SERVICE
|
||||
lookup_service_state(const char *service)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(service_bits); ++i)
|
||||
if (!strcmp(service, service_bits[i].name))
|
||||
return service_bits[i].bit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_service(int argc, char **argv)
|
||||
{
|
||||
bool ok = false;
|
||||
char *service;
|
||||
char *exec;
|
||||
int idx;
|
||||
RC_SERVICE state, bit;
|
||||
|
||||
if (argc > 1)
|
||||
service = argv[1];
|
||||
else
|
||||
service = getenv("RC_SVCNAME");
|
||||
|
||||
if (service == NULL || *service == '\0')
|
||||
eerrorx("%s: no service specified", applet);
|
||||
|
||||
state = rc_service_state(service);
|
||||
bit = lookup_service_state(applet);
|
||||
if (bit) {
|
||||
ok = (state & bit);
|
||||
} else if (strcmp(applet, "service_started_daemon") == 0) {
|
||||
service = getenv("RC_SVCNAME");
|
||||
exec = argv[1];
|
||||
if (argc > 3) {
|
||||
service = argv[1];
|
||||
exec = argv[2];
|
||||
sscanf(argv[3], "%d", &idx);
|
||||
} else if (argc == 3) {
|
||||
if (sscanf(argv[2], "%d", &idx) != 1) {
|
||||
service = argv[1];
|
||||
exec = argv[2];
|
||||
}
|
||||
}
|
||||
ok = rc_service_started_daemon(service, exec, NULL, idx);
|
||||
|
||||
} else if (strcmp(applet, "service_crashed") == 0) {
|
||||
ok = (_rc_can_find_pids() &&
|
||||
rc_service_daemons_crashed(service) &&
|
||||
errno != EACCES);
|
||||
} else
|
||||
eerrorx("%s: unknown applet", applet);
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static int
|
||||
do_mark_service(int argc, char **argv)
|
||||
{
|
||||
bool ok = false;
|
||||
char *svcname = getenv("RC_SVCNAME");
|
||||
char *service = NULL;
|
||||
char *openrc_pid;
|
||||
/* char *mtime; */
|
||||
pid_t pid;
|
||||
RC_SERVICE bit;
|
||||
/* size_t l; */
|
||||
|
||||
if (argc > 1)
|
||||
service = argv[1];
|
||||
else
|
||||
service = svcname;
|
||||
|
||||
if (service == NULL || *service == '\0')
|
||||
eerrorx("%s: no service specified", applet);
|
||||
|
||||
if (!strncmp(applet, "mark_", 5) &&
|
||||
(bit = lookup_service_state(applet + 5)))
|
||||
ok = rc_service_mark(service, bit);
|
||||
else
|
||||
eerrorx("%s: unknown applet", applet);
|
||||
|
||||
/* If we're marking ourselves then we need to inform our parent
|
||||
openrc-run process so they do not mark us based on our exit code */
|
||||
/*
|
||||
* FIXME: svcname and service are almost always equal except called from a
|
||||
* shell with just argv[1] - So that doesn't seem to do what Roy initially
|
||||
* expected.
|
||||
* See 20120424041423.GA23657@odin.qasl.de (Tue, 24 Apr 2012 06:14:23 +0200,
|
||||
* openrc@gentoo.org).
|
||||
*/
|
||||
if (ok && svcname && strcmp(svcname, service) == 0) {
|
||||
openrc_pid = getenv("RC_OPENRC_PID");
|
||||
if (openrc_pid && sscanf(openrc_pid, "%d", &pid) == 1)
|
||||
if (kill(pid, SIGHUP) != 0)
|
||||
eerror("%s: failed to signal parent %d: %s",
|
||||
applet, pid, strerror(errno));
|
||||
|
||||
/* Remove the exclusive time test. This ensures that it's not
|
||||
in control as well */
|
||||
/*
|
||||
l = strlen(RC_SVCDIR "/exclusive") + strlen(svcname) +
|
||||
strlen(openrc_pid) + 4;
|
||||
mtime = xmalloc(l);
|
||||
snprintf(mtime, l, RC_SVCDIR "/exclusive/%s.%s",
|
||||
svcname, openrc_pid);
|
||||
if (exists(mtime) && unlink(mtime) != 0)
|
||||
eerror("%s: unlink: %s", applet, strerror(errno));
|
||||
free(mtime);
|
||||
*/
|
||||
}
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static int
|
||||
do_value(int argc, char **argv)
|
||||
{
|
||||
bool ok = false;
|
||||
char *service = getenv("RC_SVCNAME");
|
||||
char *option;
|
||||
|
||||
if (service == NULL)
|
||||
eerrorx("%s: no service specified", applet);
|
||||
|
||||
if (argc < 2 || ! argv[1] || *argv[1] == '\0')
|
||||
eerrorx("%s: no option specified", applet);
|
||||
|
||||
if (strcmp(applet, "service_get_value") == 0 ||
|
||||
strcmp(applet, "get_options") == 0)
|
||||
{
|
||||
option = rc_service_value_get(service, argv[1]);
|
||||
if (option) {
|
||||
printf("%s", option);
|
||||
free(option);
|
||||
ok = true;
|
||||
}
|
||||
} else if (strcmp(applet, "service_set_value") == 0 ||
|
||||
strcmp(applet, "save_options") == 0)
|
||||
ok = rc_service_value_set(service, argv[1], argv[2]);
|
||||
else
|
||||
eerrorx("%s: unknown applet", applet);
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static int
|
||||
shell_var(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
int c;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
p = argv[i];
|
||||
if (i != 1)
|
||||
putchar(' ');
|
||||
while (*p) {
|
||||
c = (unsigned char)*p++;
|
||||
if (! isalnum(c))
|
||||
c = '_';
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
is_older_than(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc < 3)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* This test is perverted - historically the baselayout function
|
||||
* returns 0 on *failure*, which is plain wrong */
|
||||
for (i = 2; i < argc; ++i)
|
||||
if (!rc_newer_than(argv[1], argv[i], NULL, NULL))
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static int
|
||||
is_newer_than(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc < 3)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* This test is correct as it's not present in baselayout */
|
||||
for (i = 2; i < argc; ++i)
|
||||
if (!rc_newer_than(argv[1], argv[i], NULL, NULL))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
is_runlevel_start(_unused int argc, _unused char **argv)
|
||||
{
|
||||
return rc_runlevel_starting() ? 0 : 1;
|
||||
}
|
||||
|
||||
static int
|
||||
is_runlevel_stop(_unused int argc, _unused char **argv)
|
||||
{
|
||||
return rc_runlevel_stopping() ? 0 : 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rc_abort(_unused int argc, _unused char **argv)
|
||||
{
|
||||
const char *p = getenv("RC_PID");
|
||||
int pid;
|
||||
|
||||
if (p && sscanf(p, "%d", &pid) == 1) {
|
||||
if (kill(pid, SIGUSR1) != 0)
|
||||
eerrorx("rc-abort: failed to signal parent %d: %s",
|
||||
pid, strerror(errno));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char * const name;
|
||||
int (* const applet)(int argc, char **argv);
|
||||
} applets[] = {
|
||||
#define A(a) { #a, a }
|
||||
A(fstabinfo),
|
||||
A(mountinfo),
|
||||
{ "openrc-run", openrc_run, },
|
||||
{ "rc-depend", rc_depend, },
|
||||
{ "rc-service", rc_service, },
|
||||
{ "rc-status", rc_status, },
|
||||
{ "rc-update", rc_update, },
|
||||
{ "service", rc_service, },
|
||||
{ "update-rc", rc_update, },
|
||||
A(runscript),
|
||||
{ "start-stop-daemon", start_stop_daemon, },
|
||||
A(checkpath),
|
||||
A(swclock),
|
||||
A(shell_var),
|
||||
A(is_older_than),
|
||||
A(is_newer_than),
|
||||
A(is_runlevel_start),
|
||||
A(is_runlevel_stop),
|
||||
{ "rc-abort", rc_abort, },
|
||||
/* These are purely for init scripts and do not make sense as
|
||||
* anything else */
|
||||
{ "service_get_value", do_value, },
|
||||
{ "service_set_value", do_value, },
|
||||
{ "get_options", do_value, },
|
||||
{ "save_options", do_value, },
|
||||
#undef A
|
||||
};
|
||||
|
||||
void
|
||||
run_applets(int argc, char **argv)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* The "rc" applet is deprecated and should be referred to as
|
||||
* "openrc", so output a warning.
|
||||
*/
|
||||
if (strcmp(applet, "rc") == 0)
|
||||
ewarnv("The 'rc' applet is deprecated; please use 'openrc' instead.");
|
||||
/* Bug 351712: We need an extra way to explicitly select an applet OTHER
|
||||
* than trusting argv[0], as argv[0] is not going to be the applet value if
|
||||
* we are doing SELinux context switching. For this, we allow calls such as
|
||||
* 'rc --applet APPLET', and shift ALL of argv down by two array items. */
|
||||
if ((strcmp(applet, "rc") == 0 || strcmp(applet, "openrc") == 0) &&
|
||||
argc >= 3 &&
|
||||
(strcmp(argv[1],"--applet") == 0 || strcmp(argv[1], "-a") == 0)) {
|
||||
applet = argv[2];
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(applets); ++i)
|
||||
if (!strcmp(applet, applets[i].name))
|
||||
exit(applets[i].applet(argc, argv));
|
||||
|
||||
if (applet[0] == 'e' || (applet[0] == 'v' && applet[1] == 'e'))
|
||||
exit(do_e(argc, argv));
|
||||
|
||||
if (strncmp(applet, "service_", strlen("service_")) == 0)
|
||||
exit(do_service(argc, argv));
|
||||
|
||||
if (strncmp(applet, "mark_service_", strlen("mark_service_")) == 0)
|
||||
exit(do_mark_service(argc, argv));
|
||||
|
||||
if (strcmp(applet, "rc") != 0 && strcmp(applet, "openrc") != 0)
|
||||
eerrorx("%s: unknown applet", applet);
|
||||
}
|
@ -31,70 +31,16 @@
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
|
||||
extern const char *applet;
|
||||
|
||||
RC_DEPTREE *
|
||||
_rc_deptree_load(int force, int *regen) {
|
||||
int fd;
|
||||
int retval;
|
||||
int serrno = errno;
|
||||
int merrno;
|
||||
time_t t;
|
||||
char file[PATH_MAX];
|
||||
struct stat st;
|
||||
struct utimbuf ut;
|
||||
FILE *fp;
|
||||
|
||||
t = 0;
|
||||
if (rc_deptree_update_needed(&t, file) || force != 0) {
|
||||
/* Test if we have permission to update the deptree */
|
||||
fd = open(RC_DEPTREE_CACHE, O_WRONLY);
|
||||
merrno = errno;
|
||||
errno = serrno;
|
||||
if (fd == -1 && merrno == EACCES)
|
||||
return rc_deptree_load();
|
||||
close(fd);
|
||||
|
||||
if (regen)
|
||||
*regen = 1;
|
||||
ebegin("Caching service dependencies");
|
||||
retval = rc_deptree_update() ? 0 : -1;
|
||||
eend (retval, "Failed to update the dependency tree");
|
||||
|
||||
if (retval == 0) {
|
||||
stat(RC_DEPTREE_CACHE, &st);
|
||||
if (st.st_mtime < t) {
|
||||
eerror("Clock skew detected with `%s'", file);
|
||||
eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
|
||||
"' to %s", ctime(&t));
|
||||
fp = fopen(RC_DEPTREE_SKEWED, "w");
|
||||
if (fp != NULL) {
|
||||
fprintf(fp, "%s\n", file);
|
||||
fclose(fp);
|
||||
}
|
||||
ut.actime = t;
|
||||
ut.modtime = t;
|
||||
utime(RC_DEPTREE_CACHE, &ut);
|
||||
} else {
|
||||
if (exists(RC_DEPTREE_SKEWED))
|
||||
unlink(RC_DEPTREE_SKEWED);
|
||||
}
|
||||
}
|
||||
if (force == -1 && regen != NULL)
|
||||
*regen = retval;
|
||||
}
|
||||
return rc_deptree_load();
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define getoptstring "aot:suTF:" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = NULL;
|
||||
const char *getoptstring = "aot:suTF:" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "starting", 0, NULL, 'a'},
|
||||
{ "stopping", 0, NULL, 'o'},
|
||||
{ "type", 1, NULL, 't'},
|
||||
@ -104,7 +50,7 @@ static const struct option longopts[] = {
|
||||
{ "deptree-file", 1, NULL, 'F'},
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
const char * const longopts_help[] = {
|
||||
"Order services as if runlevel is starting",
|
||||
"Order services as if runlevel is stopping",
|
||||
"Type(s) of dependency to list",
|
||||
@ -114,10 +60,9 @@ static const char * const longopts_help[] = {
|
||||
"File to load cached deptree from",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
const char *usagestring = NULL;
|
||||
|
||||
int
|
||||
rc_depend(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
RC_STRINGLIST *list;
|
||||
RC_STRINGLIST *types;
|
||||
@ -132,6 +77,7 @@ rc_depend(int argc, char **argv)
|
||||
char *token;
|
||||
char *deptree_file = NULL;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
types = rc_stringlist_new();
|
||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||
longopts, (int *) 0)) != -1)
|
||||
|
107
src/rc/rc-misc.c
107
src/rc/rc-misc.c
@ -23,6 +23,7 @@
|
||||
# include <sys/sysinfo.h>
|
||||
#endif
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
@ -31,7 +32,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
@ -488,3 +491,107 @@ const char *detect_vm(void)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RC_DEPTREE * _rc_deptree_load(int force, int *regen)
|
||||
{
|
||||
int fd;
|
||||
int retval;
|
||||
int serrno = errno;
|
||||
int merrno;
|
||||
time_t t;
|
||||
char file[PATH_MAX];
|
||||
struct stat st;
|
||||
struct utimbuf ut;
|
||||
FILE *fp;
|
||||
|
||||
t = 0;
|
||||
if (rc_deptree_update_needed(&t, file) || force != 0) {
|
||||
/* Test if we have permission to update the deptree */
|
||||
fd = open(RC_DEPTREE_CACHE, O_WRONLY);
|
||||
merrno = errno;
|
||||
errno = serrno;
|
||||
if (fd == -1 && merrno == EACCES)
|
||||
return rc_deptree_load();
|
||||
close(fd);
|
||||
|
||||
if (regen)
|
||||
*regen = 1;
|
||||
ebegin("Caching service dependencies");
|
||||
retval = rc_deptree_update() ? 0 : -1;
|
||||
eend (retval, "Failed to update the dependency tree");
|
||||
|
||||
if (retval == 0) {
|
||||
stat(RC_DEPTREE_CACHE, &st);
|
||||
if (st.st_mtime < t) {
|
||||
eerror("Clock skew detected with `%s'", file);
|
||||
eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
|
||||
"' to %s", ctime(&t));
|
||||
fp = fopen(RC_DEPTREE_SKEWED, "w");
|
||||
if (fp != NULL) {
|
||||
fprintf(fp, "%s\n", file);
|
||||
fclose(fp);
|
||||
}
|
||||
ut.actime = t;
|
||||
ut.modtime = t;
|
||||
utime(RC_DEPTREE_CACHE, &ut);
|
||||
} else {
|
||||
if (exists(RC_DEPTREE_SKEWED))
|
||||
unlink(RC_DEPTREE_SKEWED);
|
||||
}
|
||||
}
|
||||
if (force == -1 && regen != NULL)
|
||||
*regen = retval;
|
||||
}
|
||||
return rc_deptree_load();
|
||||
}
|
||||
|
||||
bool _rc_can_find_pids(void)
|
||||
{
|
||||
RC_PIDLIST *pids;
|
||||
RC_PID *pid;
|
||||
RC_PID *pid2;
|
||||
bool retval = false;
|
||||
|
||||
if (geteuid() == 0)
|
||||
return true;
|
||||
|
||||
/* If we cannot see process 1, then we don't test to see if
|
||||
* services crashed or not */
|
||||
pids = rc_find_pids(NULL, NULL, 0, 1);
|
||||
if (pids) {
|
||||
pid = LIST_FIRST(pids);
|
||||
if (pid) {
|
||||
retval = true;
|
||||
while (pid) {
|
||||
pid2 = LIST_NEXT(pid, entries);
|
||||
free(pid);
|
||||
pid = pid2;
|
||||
}
|
||||
}
|
||||
free(pids);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char * const name;
|
||||
RC_SERVICE bit;
|
||||
} service_bits[] = {
|
||||
{ "service_started", RC_SERVICE_STARTED, },
|
||||
{ "service_stopped", RC_SERVICE_STOPPED, },
|
||||
{ "service_inactive", RC_SERVICE_INACTIVE, },
|
||||
{ "service_starting", RC_SERVICE_STARTING, },
|
||||
{ "service_stopping", RC_SERVICE_STOPPING, },
|
||||
{ "service_hotplugged", RC_SERVICE_HOTPLUGGED, },
|
||||
{ "service_wasinactive", RC_SERVICE_WASINACTIVE, },
|
||||
{ "service_failed", RC_SERVICE_FAILED, },
|
||||
};
|
||||
|
||||
RC_SERVICE lookup_service_state(const char *service)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(service_bits); ++i)
|
||||
if (!strcmp(service, service_bits[i].name))
|
||||
return service_bits[i].bit;
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
@ -384,3 +386,5 @@ out:
|
||||
free(run_init_t);
|
||||
free(curr_t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -21,39 +21,36 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
|
||||
extern char *applet;
|
||||
|
||||
#include "_usage.h"
|
||||
#define usagestring "" \
|
||||
"Usage: rc-service [options] [-i] <service> <cmd>...\n" \
|
||||
" or: rc-service [options] -e <service>\n" \
|
||||
" or: rc-service [options] -l\n" \
|
||||
" or: rc-service [options] -r <service>"
|
||||
#define getoptstring "e:ilr:" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = NULL;
|
||||
const char *getoptstring = "e:ilr:" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "exists", 1, NULL, 'e' },
|
||||
{ "ifexists", 0, NULL, 'i' },
|
||||
{ "list", 0, NULL, 'l' },
|
||||
{ "resolve", 1, NULL, 'r' },
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
const char * const longopts_help[] = {
|
||||
"tests if the service exists or not",
|
||||
"if the service exists then run the command",
|
||||
"list all available services",
|
||||
"resolve the service name to an init script",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
const char *usagestring = "" \
|
||||
"Usage: rc-service [options] [-i] <service> <cmd>...\n" \
|
||||
" or: rc-service [options] -e <service>\n" \
|
||||
" or: rc-service [options] -l\n" \
|
||||
" or: rc-service [options] -r <service>";
|
||||
|
||||
int
|
||||
rc_service(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
char *service;
|
||||
@ -61,6 +58,7 @@ rc_service(int argc, char **argv)
|
||||
RC_STRING *s;
|
||||
bool if_exists = false;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
/* Ensure that we are only quiet when explicitly told to be */
|
||||
unsetenv("EINFO_QUIET");
|
||||
|
||||
|
@ -21,13 +21,37 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
#include "_usage.h"
|
||||
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = NULL;
|
||||
const char *getoptstring = "aclrsu" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{"all", 0, NULL, 'a'},
|
||||
{"crashed", 0, NULL, 'c'},
|
||||
{"list", 0, NULL, 'l'},
|
||||
{"runlevel", 0, NULL, 'r'},
|
||||
{"servicelist", 0, NULL, 's'},
|
||||
{"unused", 0, NULL, 'u'},
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"Show services from all run levels",
|
||||
"Show crashed services",
|
||||
"Show list of run levels",
|
||||
"Show the name of the current runlevel",
|
||||
"Show service list",
|
||||
"Show services not assigned to any runlevel",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
const char *usagestring = "" \
|
||||
"Usage: rc-status [options] <runlevel>...\n" \
|
||||
" or: rc-status [options] [-a | -c | -l | -r | -s | -u]";
|
||||
|
||||
extern const char *applet;
|
||||
static bool test_crashed = false;
|
||||
static RC_DEPTREE *deptree;
|
||||
static RC_STRINGLIST *types;
|
||||
@ -35,35 +59,6 @@ static RC_STRINGLIST *types;
|
||||
static RC_STRINGLIST *levels, *services, *tmp, *alist;
|
||||
static RC_STRINGLIST *sservices, *nservices, *needsme;
|
||||
|
||||
bool
|
||||
_rc_can_find_pids(void)
|
||||
{
|
||||
RC_PIDLIST *pids;
|
||||
RC_PID *pid;
|
||||
RC_PID *pid2;
|
||||
bool retval = false;
|
||||
|
||||
if (geteuid() == 0)
|
||||
return true;
|
||||
|
||||
/* If we cannot see process 1, then we don't test to see if
|
||||
* services crashed or not */
|
||||
pids = rc_find_pids(NULL, NULL, 0, 1);
|
||||
if (pids) {
|
||||
pid = LIST_FIRST(pids);
|
||||
if (pid) {
|
||||
retval = true;
|
||||
while (pid) {
|
||||
pid2 = LIST_NEXT(pid, entries);
|
||||
free(pid);
|
||||
pid = pid2;
|
||||
}
|
||||
}
|
||||
free(pids);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
print_level(const char *prefix, const char *level)
|
||||
{
|
||||
@ -178,33 +173,7 @@ print_stacked_services(const char *runlevel)
|
||||
stackedlevels = NULL;
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define usagestring "" \
|
||||
"Usage: rc-status [options] <runlevel>...\n" \
|
||||
" or: rc-status [options] [-a | -c | -l | -r | -s | -u]"
|
||||
#define getoptstring "aclrsu" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{"all", 0, NULL, 'a'},
|
||||
{"crashed", 0, NULL, 'c'},
|
||||
{"list", 0, NULL, 'l'},
|
||||
{"runlevel", 0, NULL, 'r'},
|
||||
{"servicelist", 0, NULL, 's'},
|
||||
{"unused", 0, NULL, 'u'},
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"Show services from all run levels",
|
||||
"Show crashed services",
|
||||
"Show list of run levels",
|
||||
"Show the name of the current runlevel",
|
||||
"Show service list",
|
||||
"Show services not assigned to any runlevel",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
int
|
||||
rc_status(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
RC_STRING *s, *l, *t, *level;
|
||||
|
||||
@ -213,6 +182,7 @@ rc_status(int argc, char **argv)
|
||||
|
||||
test_crashed = _rc_can_find_pids();
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
||||
(int *) 0)) != -1)
|
||||
switch (opt) {
|
||||
|
@ -24,13 +24,31 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
#include "_usage.h"
|
||||
|
||||
extern const char *applet;
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = NULL;
|
||||
const char *usagestring = "" \
|
||||
"Usage: rc-update [options] add <service> [<runlevel>...]\n" \
|
||||
" or: rc-update [options] del <service> [<runlevel>...]\n" \
|
||||
" or: rc-update [options] [show [<runlevel>...]]";
|
||||
const char *getoptstring = "asu" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "all", 0, NULL, 'a' },
|
||||
{ "stack", 0, NULL, 's' },
|
||||
{ "update", 0, NULL, 'u' },
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"Process all runlevels",
|
||||
"Stack a runlevel instead of a service",
|
||||
"Force an update of the dependency tree",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
|
||||
/* Return the number of changes made:
|
||||
* -1 = no changes (error)
|
||||
@ -182,32 +200,11 @@ show(RC_STRINGLIST *runlevels, bool verbose)
|
||||
rc_stringlist_free (services);
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define usagestring "" \
|
||||
"Usage: rc-update [options] add <service> [<runlevel>...]\n" \
|
||||
" or: rc-update [options] del <service> [<runlevel>...]\n" \
|
||||
" or: rc-update [options] [show [<runlevel>...]]"
|
||||
#define getoptstring "asu" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "all", 0, NULL, 'a' },
|
||||
{ "stack", 0, NULL, 's' },
|
||||
{ "update", 0, NULL, 'u' },
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"Process all runlevels",
|
||||
"Stack a runlevel instead of a service",
|
||||
"Force an update of the dependency tree",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
#define DOADD (1 << 1)
|
||||
#define DODELETE (1 << 2)
|
||||
#define DOSHOW (1 << 3)
|
||||
|
||||
int
|
||||
rc_update(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
RC_DEPTREE *deptree;
|
||||
RC_STRINGLIST *runlevels;
|
||||
@ -222,6 +219,7 @@ rc_update(int argc, char **argv)
|
||||
int (*actfunc)(const char *, const char *);
|
||||
int ret;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||
longopts, (int *)0)) != -1)
|
||||
switch (opt) {
|
||||
|
55
src/rc/rc.c
55
src/rc/rc.c
@ -45,7 +45,6 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
@ -54,6 +53,27 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
|
||||
#include "rc-plugin.h"
|
||||
|
||||
#include "version.h"
|
||||
#include "_usage.h"
|
||||
|
||||
const char *extraopts = NULL;
|
||||
const char *getoptstring = "a:no:s:S" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "no-stop", 0, NULL, 'n' },
|
||||
{ "override", 1, NULL, 'o' },
|
||||
{ "service", 1, NULL, 's' },
|
||||
{ "sys", 0, NULL, 'S' },
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"do not stop any services",
|
||||
"override the next runlevel to change into\n"
|
||||
"when leaving single user or boot runlevels",
|
||||
"runs the service specified with the rest\nof the arguments",
|
||||
"output the RC system type, if any",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
const char *usagestring = "" \
|
||||
"Usage: openrc [options] [<runlevel>]";
|
||||
|
||||
#define INITSH RC_LIBEXECDIR "/sh/init.sh"
|
||||
#define INITEARLYSH RC_LIBEXECDIR "/sh/init-early.sh"
|
||||
@ -721,31 +741,7 @@ handle_bad_signal(int sig)
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "_usage.h"
|
||||
#define usagestring "" \
|
||||
"Usage: openrc [options] [<runlevel>]"
|
||||
#define getoptstring "a:no:s:S" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "applet", 1, NULL, 'a' },
|
||||
{ "no-stop", 0, NULL, 'n' },
|
||||
{ "override", 1, NULL, 'o' },
|
||||
{ "service", 1, NULL, 's' },
|
||||
{ "sys", 0, NULL, 'S' },
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"runs the applet specified by the next argument",
|
||||
"do not stop any services",
|
||||
"override the next runlevel to change into\n"
|
||||
"when leaving single user or boot runlevels",
|
||||
"runs the service specified with the rest\nof the arguments",
|
||||
"output the RC system type, if any",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bootlevel = NULL;
|
||||
char *newlevel = NULL;
|
||||
@ -785,9 +781,6 @@ main(int argc, char **argv)
|
||||
if (!applet)
|
||||
eerrorx("arguments required");
|
||||
|
||||
/* Run our built in applets. If we ran one, we don't return. */
|
||||
run_applets(argc, argv);
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
@ -813,10 +806,6 @@ main(int argc, char **argv)
|
||||
longopts, (int *) 0)) != -1)
|
||||
{
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
/* Do nothing, actual logic in run_applets, this
|
||||
* is a placeholder */
|
||||
break;
|
||||
case 'n':
|
||||
nostop = true;
|
||||
break;
|
||||
|
41
src/rc/shell_var.c
Normal file
41
src/rc/shell_var.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2015 The OpenRC Authors.
|
||||
* See the Authors file at the top-level directory of this distribution and
|
||||
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||
*
|
||||
* This file is part of OpenRC. It is subject to the license terms in
|
||||
* the LICENSE file found in the top-level directory of this
|
||||
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||
* This file may not be copied, modified, propagated, or distributed
|
||||
* except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
int c;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
p = argv[i];
|
||||
if (i != 1)
|
||||
putchar(' ');
|
||||
while (*p) {
|
||||
c = (unsigned char)*p++;
|
||||
if (! isalnum(c))
|
||||
c = '_';
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -59,11 +59,75 @@
|
||||
static struct pam_conv conv = { NULL, NULL};
|
||||
#endif
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
#include "_usage.h"
|
||||
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = NULL;
|
||||
const char *getoptstring = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:" \
|
||||
getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "ionice", 1, NULL, 'I'},
|
||||
{ "stop", 0, NULL, 'K'},
|
||||
{ "nicelevel", 1, NULL, 'N'},
|
||||
{ "retry", 1, NULL, 'R'},
|
||||
{ "start", 0, NULL, 'S'},
|
||||
{ "startas", 1, NULL, 'a'},
|
||||
{ "background", 0, NULL, 'b'},
|
||||
{ "chuid", 1, NULL, 'c'},
|
||||
{ "chdir", 1, NULL, 'd'},
|
||||
{ "env", 1, NULL, 'e'},
|
||||
{ "umask", 1, NULL, 'k'},
|
||||
{ "group", 1, NULL, 'g'},
|
||||
{ "interpreted", 0, NULL, 'i'},
|
||||
{ "make-pidfile", 0, NULL, 'm'},
|
||||
{ "name", 1, NULL, 'n'},
|
||||
{ "oknodo", 0, NULL, 'o'},
|
||||
{ "pidfile", 1, NULL, 'p'},
|
||||
{ "signal", 1, NULL, 's'},
|
||||
{ "test", 0, NULL, 't'},
|
||||
{ "user", 1, NULL, 'u'},
|
||||
{ "chroot", 1, NULL, 'r'},
|
||||
{ "wait", 1, NULL, 'w'},
|
||||
{ "exec", 1, NULL, 'x'},
|
||||
{ "stdout", 1, NULL, '1'},
|
||||
{ "stderr", 1, NULL, '2'},
|
||||
{ "progress", 0, NULL, 'P'},
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"Set an ionice class:data when starting",
|
||||
"Stop daemon",
|
||||
"Set a nicelevel when starting",
|
||||
"Retry schedule to use when stopping",
|
||||
"Start daemon",
|
||||
"deprecated, use --exec or --name",
|
||||
"Force daemon to background",
|
||||
"deprecated, use --user",
|
||||
"Change the PWD",
|
||||
"Set an environment string",
|
||||
"Set the umask for the daemon",
|
||||
"Change the process group",
|
||||
"Match process name by interpreter",
|
||||
"Create a pidfile",
|
||||
"Match process name",
|
||||
"deprecated",
|
||||
"Match pid found in this file",
|
||||
"Send a different signal",
|
||||
"Test actions, don't do them",
|
||||
"Change the process user",
|
||||
"Chroot to this directory",
|
||||
"Milliseconds to wait for daemon start",
|
||||
"Binary to start/stop",
|
||||
"Redirect stdout to file",
|
||||
"Redirect stderr to file",
|
||||
"Print dots each second while waiting",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
const char *usagestring = NULL;
|
||||
|
||||
typedef struct scheduleitem
|
||||
{
|
||||
@ -81,7 +145,6 @@ typedef struct scheduleitem
|
||||
TAILQ_HEAD(, scheduleitem) schedule;
|
||||
static char **nav;
|
||||
|
||||
extern const char *applet;
|
||||
static char *changeuser, *ch_root, *ch_dir;
|
||||
|
||||
extern char **environ;
|
||||
@ -567,70 +630,7 @@ expand_home(const char *home, const char *path)
|
||||
return nh;
|
||||
}
|
||||
|
||||
#include "_usage.h"
|
||||
#define getoptstring "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "ionice", 1, NULL, 'I'},
|
||||
{ "stop", 0, NULL, 'K'},
|
||||
{ "nicelevel", 1, NULL, 'N'},
|
||||
{ "retry", 1, NULL, 'R'},
|
||||
{ "start", 0, NULL, 'S'},
|
||||
{ "startas", 1, NULL, 'a'},
|
||||
{ "background", 0, NULL, 'b'},
|
||||
{ "chuid", 1, NULL, 'c'},
|
||||
{ "chdir", 1, NULL, 'd'},
|
||||
{ "env", 1, NULL, 'e'},
|
||||
{ "umask", 1, NULL, 'k'},
|
||||
{ "group", 1, NULL, 'g'},
|
||||
{ "interpreted", 0, NULL, 'i'},
|
||||
{ "make-pidfile", 0, NULL, 'm'},
|
||||
{ "name", 1, NULL, 'n'},
|
||||
{ "oknodo", 0, NULL, 'o'},
|
||||
{ "pidfile", 1, NULL, 'p'},
|
||||
{ "signal", 1, NULL, 's'},
|
||||
{ "test", 0, NULL, 't'},
|
||||
{ "user", 1, NULL, 'u'},
|
||||
{ "chroot", 1, NULL, 'r'},
|
||||
{ "wait", 1, NULL, 'w'},
|
||||
{ "exec", 1, NULL, 'x'},
|
||||
{ "stdout", 1, NULL, '1'},
|
||||
{ "stderr", 1, NULL, '2'},
|
||||
{ "progress", 0, NULL, 'P'},
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"Set an ionice class:data when starting",
|
||||
"Stop daemon",
|
||||
"Set a nicelevel when starting",
|
||||
"Retry schedule to use when stopping",
|
||||
"Start daemon",
|
||||
"deprecated, use --exec or --name",
|
||||
"Force daemon to background",
|
||||
"deprecated, use --user",
|
||||
"Change the PWD",
|
||||
"Set an environment string",
|
||||
"Set the umask for the daemon",
|
||||
"Change the process group",
|
||||
"Match process name by interpreter",
|
||||
"Create a pidfile",
|
||||
"Match process name",
|
||||
"deprecated",
|
||||
"Match pid found in this file",
|
||||
"Send a different signal",
|
||||
"Test actions, don't do them",
|
||||
"Change the process user",
|
||||
"Chroot to this directory",
|
||||
"Milliseconds to wait for daemon start",
|
||||
"Binary to start/stop",
|
||||
"Redirect stdout to file",
|
||||
"Redirect stderr to file",
|
||||
"Print dots each second while waiting",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
int
|
||||
start_stop_daemon(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int devnull_fd = -1;
|
||||
#ifdef TIOCNOTTY
|
||||
@ -686,6 +686,7 @@ start_stop_daemon(int argc, char **argv)
|
||||
char **margv;
|
||||
unsigned int start_wait = 0;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
TAILQ_INIT(&schedule);
|
||||
#ifdef DEBUG_MEMORY
|
||||
atexit(cleanup);
|
||||
|
@ -25,40 +25,39 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "rc-misc.h"
|
||||
#include "_usage.h"
|
||||
|
||||
#define RC_SHUTDOWNTIME RC_SVCDIR "/shutdowntime"
|
||||
|
||||
extern const char *applet;
|
||||
|
||||
#include "_usage.h"
|
||||
#define extraopts "file"
|
||||
#define getoptstring "sw" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
const char *applet = NULL;
|
||||
const char *extraopts = "file";
|
||||
const char *getoptstring = "sw" getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "save", 0, NULL, 's' },
|
||||
{ "warn", 0, NULL, 'w' },
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
const char * const longopts_help[] = {
|
||||
"saves the time",
|
||||
"no error if no reference file",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
const char *usagestring = NULL;
|
||||
|
||||
int
|
||||
swclock(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt, sflag = 0, wflag = 0;
|
||||
const char *file = RC_SHUTDOWNTIME;
|
||||
struct stat sb;
|
||||
struct timeval tv;
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||
longopts, (int *) 0)) != -1)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user