public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/openrc:master commit in: src/rc/, man/
@ 2017-12-04 23:31 William Hubbs
  0 siblings, 0 replies; 4+ messages in thread
From: William Hubbs @ 2017-12-04 23:31 UTC (permalink / raw
  To: gentoo-commits

commit:     a2447dfb420cbd97a65cc085404c031d42cb3dfb
Author:     William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Mon Dec  4 23:17:17 2017 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Mon Dec  4 23:17:17 2017 +0000
URL:        https://gitweb.gentoo.org/proj/openrc.git/commit/?id=a2447dfb

rc-service: add --ifcrashed option

This works like the other --if options. If the service is crashed, run
the command.

This fixes #154.

 man/rc-service.8    |  4 ++++
 src/rc/rc-service.c | 10 +++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/man/rc-service.8 b/man/rc-service.8
index 80deb5eb..8f075de4 100644
--- a/man/rc-service.8
+++ b/man/rc-service.8
@@ -16,6 +16,10 @@
 .Nd locate and run an OpenRC service with the given arguments
 .Sh SYNOPSIS
 .Nm
+.Op Fl c , -ifcrashed
+.Ar service cmd
+.Op Ar ...
+.Nm
 .Op Fl i , -ifexists
 .Ar service cmd
 .Op Ar ...

diff --git a/src/rc/rc-service.c b/src/rc/rc-service.c
index d0a64999..8e7b00dc 100644
--- a/src/rc/rc-service.c
+++ b/src/rc/rc-service.c
@@ -29,9 +29,10 @@
 
 const char *applet = NULL;
 const char *extraopts = NULL;
-const char *getoptstring = "e:ilr:IN" getoptstring_COMMON;
+const char *getoptstring = "ce:ilr:IN" getoptstring_COMMON;
 const struct option longopts[] = {
 	{ "exists",   1, NULL, 'e' },
+	{ "ifcrashed", 0, NULL, 'c' },
 	{ "ifexists", 0, NULL, 'i' },
 	{ "ifinactive", 0, NULL, 'I' },
 	{ "ifnotstarted", 0, NULL, 'N' },
@@ -41,6 +42,7 @@ const struct option longopts[] = {
 };
 const char * const longopts_help[] = {
 	"tests if the service exists or not",
+	"if the service is crashed then run the command",
 	"if the service exists then run the command",
 	"if the service is inactive then run the command",
 	"if the service is not started then run the command",
@@ -61,6 +63,7 @@ int main(int argc, char **argv)
 	RC_STRINGLIST *list;
 	RC_STRING *s;
 	RC_SERVICE state;
+	bool if_crashed = false;
 	bool if_exists = false;
 	bool if_inactive = false;
 	bool if_notstarted = false;
@@ -79,6 +82,9 @@ int main(int argc, char **argv)
 			free(service);
 			return opt;
 			/* NOTREACHED */
+		case 'c':
+			if_crashed = true;
+			break;
 		case 'i':
 			if_exists = true;
 			break;
@@ -121,6 +127,8 @@ int main(int argc, char **argv)
 		eerrorx("%s: service `%s' does not exist", applet, *argv);
 	}
 	state = rc_service_state(*argv);
+	if (if_crashed &&  ! (rc_service_daemons_crashed(*argv) && errno != EACCES))
+		return 0;
 	if (if_inactive && ! (state & RC_SERVICE_INACTIVE))
 		return 0;
 	if (if_notstarted && (state & RC_SERVICE_STARTED))


^ permalink raw reply related	[flat|nested] 4+ messages in thread
* [gentoo-commits] proj/openrc:master commit in: src/rc/, man/
@ 2018-10-18 23:01 William Hubbs
  0 siblings, 0 replies; 4+ messages in thread
From: William Hubbs @ 2018-10-18 23:01 UTC (permalink / raw
  To: gentoo-commits

commit:     3f918161aafa61c1c2005709fda0b9bec4c412d8
Author:     William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Fri Oct  5 19:10:59 2018 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Thu Oct 18 22:56:36 2018 +0000
URL:        https://gitweb.gentoo.org/proj/openrc.git/commit/?id=3f918161

openrc-shutdown: Add scheduled shutdown and the ability to cancel a shutdown

You can now schedule a shutdown for a certain time or a cpecific number
of minutes into the future.

When a shutdown is running, you can now cancel it with ^c from the
keyboard or by running "openrc-shutdown -c" from another shell.

 man/openrc-shutdown.8    |   3 +
 src/rc/Makefile          |   4 +-
 src/rc/broadcast.c       | 209 +++++++++++++++++++++++++++++++++++++++++++++++
 src/rc/broadcast.h       |  16 ++++
 src/rc/openrc-shutdown.c | 179 ++++++++++++++++++++++++++++++++++++++--
 5 files changed, 402 insertions(+), 9 deletions(-)

diff --git a/man/openrc-shutdown.8 b/man/openrc-shutdown.8
index 5db21334..b09e8c20 100644
--- a/man/openrc-shutdown.8
+++ b/man/openrc-shutdown.8
@@ -16,6 +16,7 @@
 .Nd bring the system down
 .Sh SYNOPSIS
 .Nm
+.Op Fl c , -cancel
 .Op Fl d , -no-write
 .Op Fl D , -dry-run
 .Op Fl H , -halt
@@ -32,6 +33,8 @@ is the utility that communicates with
 to bring down the system or instruct openrc-init to re-execute itself.
 It supports the following options:
 .Bl -tag -width "poweroff"
+.It Fl c , -cancel
+Cancel a pending shutdown.
 .It Fl d , -no-write
 Do not write the wtmp boot record.
 .It Fl D , -dry-run

diff --git a/src/rc/Makefile b/src/rc/Makefile
index b09c5058..9ba240fa 100644
--- a/src/rc/Makefile
+++ b/src/rc/Makefile
@@ -14,7 +14,7 @@ SRCS+=		rc-selinux.c
 endif
 
 ifeq (${OS},Linux)
-SRCS+=		kill_all.c openrc-init.c openrc-shutdown.c rc-wtmp.c
+SRCS+=		kill_all.c openrc-init.c openrc-shutdown.c broadcast.c rc-wtmp.c
 endif
 
 CLEANFILES=	version.h rc-selinux.o
@@ -134,7 +134,7 @@ mountinfo: mountinfo.o _usage.o rc-misc.o
 openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
 	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 
-openrc-shutdown: openrc-shutdown.o _usage.o rc-wtmp.o
+openrc-shutdown: openrc-shutdown.o rc-misc.o _usage.o broadcast.o rc-wtmp.o
 	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 
 openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o

diff --git a/src/rc/broadcast.c b/src/rc/broadcast.c
new file mode 100644
index 00000000..dbc861d1
--- /dev/null
+++ b/src/rc/broadcast.c
@@ -0,0 +1,209 @@
+/*
+ * broadcast.c
+ * broadcast a message to every logged in user
+ */
+
+/*
+ * Copyright 2018 Sony Interactive Entertainment Inc. 
+ *
+ * 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 <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <utmpx.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <paths.h>
+#include <sys/utsname.h>
+
+#include "broadcast.h"
+#include "helpers.h"
+
+#ifndef _PATH_DEV
+# define _PATH_DEV	"/dev/"
+#endif
+
+#ifndef UT_LINESIZE
+#define UT_LINESIZE __UT_LINESIZE
+#endif
+
+static sigjmp_buf jbuf;
+
+/*
+ *	Alarm handler
+ */
+/*ARGSUSED*/
+# ifdef __GNUC__
+static void handler(int arg __attribute__((unused)))
+# else
+static void handler(int arg)
+# endif
+{
+	siglongjmp(jbuf, 1);
+}
+
+static void getuidtty(char **userp, char **ttyp)
+{
+	struct passwd 		*pwd;
+	uid_t			uid;
+	char			*tty;
+	static char		uidbuf[32];
+	static char		ttynm[UT_LINESIZE + 4];
+
+	uid = getuid();
+	if ((pwd = getpwuid(uid)) != NULL) {
+		uidbuf[0] = 0;
+		strncat(uidbuf, pwd->pw_name, sizeof(uidbuf) - 1);
+	} else {
+		if (uid)
+			sprintf(uidbuf, "uid %d", (int) uid);
+		else
+			sprintf(uidbuf, "root");
+	}
+
+	if ((tty = ttyname(0)) != NULL) {
+		const size_t plen = strlen(_PATH_DEV);
+		if (strncmp(tty, _PATH_DEV, plen) == 0) {
+			tty += plen;
+			if (tty[0] == '/')
+				tty++;
+		}
+		snprintf(ttynm, sizeof(ttynm), "(%.*s) ",
+				 UT_LINESIZE, tty);
+	} else
+		ttynm[0] = 0;
+
+	*userp = uidbuf;
+	*ttyp  = ttynm;
+}
+
+/*
+ *	Check whether the given filename looks like a tty device.
+ */
+static int file_isatty(const char *fname)
+{
+	struct stat		st;
+	int			major;
+
+	if (stat(fname, &st) < 0)
+		return 0;
+
+	if (st.st_nlink != 1 || !S_ISCHR(st.st_mode))
+		return 0;
+
+	/*
+	 *	It would be an impossible task to list all major/minors
+	 *	of tty devices here, so we just exclude the obvious
+	 *	majors of which just opening has side-effects:
+	 *	printers and tapes.
+	 */
+	major = major(st.st_dev);
+	if (major == 1 || major == 2 || major == 6 || major == 9 ||
+	    major == 12 || major == 16 || major == 21 || major == 27 ||
+	    major == 37 || major == 96 || major == 97 || major == 206 ||
+	    major == 230)
+		return 0;
+	return 1;
+}
+
+/*
+ *	broadcast function.
+ */
+void broadcast(char *text)
+{
+	char *tty;
+	char *user;
+	struct utsname name;
+	time_t t;
+	char	*date;
+	char *p;
+	char *line = NULL;
+	struct sigaction sa;
+	int fd;
+	FILE *tp;
+	int	flags;
+	char *term = NULL;
+	struct utmpx *utmp;
+
+	getuidtty(&user, &tty);
+
+	/*
+	 * Get and report current hostname, to make it easier to find out
+	 * which machine is being shut down.
+	 */
+	uname(&name);
+
+	/* Get the time */
+	time(&t);
+	date = ctime(&t);
+	p = strchr(date, '\n');
+	if (p)
+		*p = 0;
+	
+	xasprintf(&line, "\007\r\nBroadcast message from %s@%s %s(%s):\r\n\r\n",
+			user, name.nodename, tty, date);
+
+	/*
+	 *	Fork to avoid hanging in a write()
+	 */
+	if (fork() != 0)
+		return;
+	
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = handler;
+	sigemptyset(&sa.sa_mask);
+	sigaction(SIGALRM, &sa, NULL);
+
+	setutxent();
+
+	while ((utmp = getutxent()) != NULL) {
+		if (utmp->ut_type != USER_PROCESS || utmp->ut_user[0] == 0)
+			continue;
+		if (strncmp(utmp->ut_line, _PATH_DEV, strlen(_PATH_DEV)) == 0)
+			xasprintf(&term, "%s", utmp->ut_line);
+		else
+			xasprintf(&term, "%s%s", _PATH_DEV, utmp->ut_line);
+		if (strstr(term, "/../")) {
+			free(term);
+			continue;
+		}
+
+		/*
+		 *	Open it non-delay
+		 */
+		if (sigsetjmp(jbuf, 1) == 0) {
+			alarm(2);
+			flags = O_WRONLY|O_NDELAY|O_NOCTTY;
+			if (file_isatty(term) && (fd = open(term, flags)) >= 0) {
+				if (isatty(fd) && (tp = fdopen(fd, "w")) != NULL) {
+					fputs(line, tp);
+					fputs(text, tp);
+					fflush(tp);
+				}
+			}
+		}
+		alarm(0);
+		if (fd >= 0)
+			close(fd);
+		if (tp != NULL)
+			fclose(tp);
+		free(term);
+	}
+	endutxent();
+	free(line);
+	exit(0);
+}

diff --git a/src/rc/broadcast.h b/src/rc/broadcast.h
new file mode 100644
index 00000000..5f948272
--- /dev/null
+++ b/src/rc/broadcast.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018 Sony Interactive Entertainment Inc. 
+ *
+ * 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.
+ */
+
+#ifndef BROADCAST_H
+#define BROADCAST_H
+
+void broadcast(char *text);
+
+#endif

diff --git a/src/rc/openrc-shutdown.c b/src/rc/openrc-shutdown.c
index b17a63d8..ab2e7469 100644
--- a/src/rc/openrc-shutdown.c
+++ b/src/rc/openrc-shutdown.c
@@ -25,20 +25,24 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/utsname.h>
 
+#include "broadcast.h"
 #include "einfo.h"
 #include "rc.h"
 #include "helpers.h"
+#include "rc-misc.h"
 #include "_usage.h"
 #include "rc-wtmp.h"
 
 const char *applet = NULL;
 const char *extraopts = NULL;
-const char *getoptstring = "dDHKpRrsw" getoptstring_COMMON;
+const char *getoptstring = "cdDfFHKpRrsw" getoptstring_COMMON;
 const struct option longopts[] = {
+	{ "cancel",        no_argument, NULL, 'c'},
 	{ "no-write",        no_argument, NULL, 'd'},
 	{ "dry-run",        no_argument, NULL, 'D'},
 	{ "halt",        no_argument, NULL, 'H'},
@@ -51,6 +55,7 @@ const struct option longopts[] = {
 	longopts_COMMON
 };
 const char * const longopts_help[] = {
+	"cancel a pending shutdown",
 	"do not write wtmp record",
 	"print actions instead of executing them",
 	"halt the system",
@@ -64,8 +69,12 @@ const char * const longopts_help[] = {
 };
 const char *usagestring = NULL;
 const char *exclusive = "Select one of "
-"--halt, --kexec, --poweroff, --reexec, --reboot, --single or --write-only";
+	"--cancel, --halt, --kexec, --poweroff, --reexec, --reboot, --single or \n"
+	"--write-only";
+const char *nologin_file = RC_SYSCONFDIR"/nologin";
+const char *shutdown_pid = "/run/openrc-shutdown.pid";
 
+static bool do_cancel = false;
 static bool do_dryrun = false;
 static bool do_halt = false;
 static bool do_kexec = false;
@@ -76,6 +85,40 @@ static bool do_single = false;
 static bool do_wtmp = true;
 static bool do_wtmp_only = false;
 
+static void cancel_shutdown(void)
+{
+	pid_t pid;
+
+	pid = get_pid(applet, shutdown_pid);
+	if (pid <= 0)
+		eerrorx("%s: Unable to cancel shutdown", applet);
+
+	if (kill(pid, SIGTERM) != -1)
+		einfo("%s: shutdown canceled", applet);
+	else
+		eerrorx("%s: Unable to cancel shutdown", applet);
+}
+
+/*
+ *	Create the nologin file.
+ */
+static void create_nologin(int mins)
+{
+	FILE *fp;
+	time_t t;
+
+	time(&t);
+	t += 60 * mins;
+
+	if ((fp = fopen(nologin_file, "w")) != NULL) {
+  		fprintf(fp, "\rThe system is going down on %s\r\n", ctime(&t));
+  		fclose(fp);
+	}
+}
+
+/*
+ * Send a command to our init
+ */
 static void send_cmd(const char *cmd)
 {
 	FILE *fifo;
@@ -99,16 +142,59 @@ static void send_cmd(const char *cmd)
 	fclose(fifo);
 }
 
+/*
+ * sleep without being interrupted.
+ * The idea for this code came from sysvinit.
+ */
+static void sleep_no_interrupt(int seconds)
+{
+	struct timespec duration;
+	struct timespec remaining;
+
+	duration.tv_sec = seconds;
+	duration.tv_nsec = 0;
+
+	while(nanosleep(&duration, &remaining) < 0 && errno == EINTR)
+		duration = remaining;
+}
+
+static void stop_shutdown(int sig)
+{
+	/* use the sig parameter so the compiler will not complain */
+	if (sig == SIGINT)
+		;
+	unlink(nologin_file);
+	unlink(shutdown_pid);
+einfo("Shutdown canceled");
+exit(0);
+}
+
 int main(int argc, char **argv)
 {
+	char *ch = NULL;
 	int opt;
 	int cmd_count = 0;
+	int hour = 0;
+	int min = 0;
+	int shutdown_delay = 0;
+	struct sigaction sa;
+	struct tm *lt;
+	time_t tv;
+	bool need_warning = false;
+	char *msg = NULL;
+	char *state = NULL;
+	char *time_arg = NULL;
+	FILE *fp;
 
 	applet = basename_c(argv[0]);
 	while ((opt = getopt_long(argc, argv, getoptstring,
 		    longopts, (int *) 0)) != -1)
 	{
 		switch (opt) {
+			case 'c':
+				do_cancel = true;
+			cmd_count++;
+				break;
 			case 'd':
 				do_wtmp = false;
 				break;
@@ -117,14 +203,17 @@ int main(int argc, char **argv)
 			break;
 		case 'H':
 			do_halt = true;
+			xasprintf(&state, "%s", "halt");
 			cmd_count++;
 			break;
 		case 'K':
 			do_kexec = true;
+			xasprintf(&state, "%s", "reboot");
 			cmd_count++;
 			break;
 		case 'p':
 			do_poweroff = true;
+			xasprintf(&state, "%s", "power off");
 			cmd_count++;
 			break;
 		case 'R':
@@ -133,10 +222,12 @@ int main(int argc, char **argv)
 			break;
 		case 'r':
 			do_reboot = true;
+			xasprintf(&state, "%s", "reboot");
 			cmd_count++;
 			break;
 		case 's':
 			do_single = true;
+			xasprintf(&state, "%s", "go down for maintenance");
 			cmd_count++;
 			break;
 		case 'w':
@@ -146,12 +237,88 @@ int main(int argc, char **argv)
 		case_RC_COMMON_GETOPT
 		}
 	}
-	if (geteuid() != 0 && ! do_dryrun)
+	if (geteuid() != 0)
 		eerrorx("%s: you must be root\n", applet);
 	if (cmd_count != 1) {
 		eerror("%s: %s\n", applet, exclusive);
 		usage(EXIT_FAILURE);
 	}
+
+	if (do_cancel) {
+		cancel_shutdown();
+		exit(EXIT_SUCCESS);
+	} else if (do_reexec) {
+		send_cmd("reexec");
+		exit(EXIT_SUCCESS);
+	}
+
+	if (optind >= argc) {
+		eerror("%s: No shutdown time specified", applet);
+		usage(EXIT_FAILURE);
+	}
+	time_arg = argv[optind];
+	if (*time_arg == '+')
+		time_arg++;
+	if (strcasecmp(time_arg, "now") == 0)
+		strcpy(time_arg, "0");
+	for (ch=time_arg; *ch; ch++)
+		if ((*ch < '0' || *ch > '9') && *ch != ':') {
+			eerror("%s: invalid time %s", applet, time_arg);
+			usage(EXIT_FAILURE);
+		}
+	if (strchr(time_arg, ':')) {
+		if ((sscanf(time_arg, "%2d:%2d", &hour, &min) != 2) ||
+				(hour > 23) || (min > 59)) {
+			eerror("%s: invalid time %s", applet, time_arg);
+			usage(EXIT_FAILURE);
+		}
+		time(&tv);
+		lt = localtime(&tv);
+		shutdown_delay = (hour * 60 + min) - (lt->tm_hour * 60 + lt->tm_min);
+		if (shutdown_delay < 0)
+			shutdown_delay += 1440;
+	} else {
+		shutdown_delay = atoi(time_arg);
+	}
+
+	fp = fopen(shutdown_pid, "w");
+	if (!fp)
+		eerrorx("%s: fopen `%s': %s", applet, shutdown_pid, strerror(errno));
+	fprintf(fp, "%d\n", getpid());
+	fclose(fp);
+
+	openlog(applet, LOG_PID, LOG_DAEMON);
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = stop_shutdown;
+	sigemptyset(&sa.sa_mask);
+	sigaction(SIGINT, &sa, NULL);
+	sigaction(SIGTERM, &sa, NULL);
+	while (shutdown_delay > 0) {
+		need_warning = false;
+		if (shutdown_delay > 180)
+			need_warning = (shutdown_delay % 60 == 0);
+		else if (shutdown_delay > 60)
+			need_warning = (shutdown_delay % 30 == 0);
+		else if	(shutdown_delay > 10)
+			need_warning = (shutdown_delay % 15 == 0);
+		else
+			need_warning = true;
+		if (shutdown_delay <= 5)
+			create_nologin(shutdown_delay);
+		if (need_warning) {
+		xasprintf(&msg, "\rThe system will %s in %d minutes\r\n",
+		          state, shutdown_delay);
+			broadcast(msg);
+			free(msg);
+		}
+		sleep_no_interrupt(60);
+		shutdown_delay--;
+	}
+	xasprintf(&msg, "\rThe system will %s now\r\n", state);
+	broadcast(msg);
+	syslog(LOG_NOTICE, "The system will %s now", state);
+	unlink(nologin_file);
+	unlink(shutdown_pid);
 	if (do_halt)
 		send_cmd("halt");
 	else if (do_kexec)
@@ -160,11 +327,9 @@ int main(int argc, char **argv)
 		send_cmd("poweroff");
 	else if (do_reboot)
 		send_cmd("reboot");
-	else if (do_reexec)
-		send_cmd("reexec");
-	else if (do_wtmp_only)
-		log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
 	else if (do_single)
 		send_cmd("single");
+		else if (do_wtmp_only)
+		log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
 	return 0;
 }


^ permalink raw reply related	[flat|nested] 4+ messages in thread
* [gentoo-commits] proj/openrc:master commit in: src/rc/, man/
@ 2018-05-16 18:27 William Hubbs
  0 siblings, 0 replies; 4+ messages in thread
From: William Hubbs @ 2018-05-16 18:27 UTC (permalink / raw
  To: gentoo-commits

commit:     08da36149c0b41c64a09369c3eef5e2f5a6fa39c
Author:     William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Wed May 16 18:25:22 2018 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Wed May 16 18:25:22 2018 +0000
URL:        https://gitweb.gentoo.org/proj/openrc.git/commit/?id=08da3614

rc-service: add --ifstarted and --ifstopped options

 man/rc-service.8    |  8 ++++++++
 src/rc/rc-service.c | 16 +++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/man/rc-service.8 b/man/rc-service.8
index 2834f361..72d5a559 100644
--- a/man/rc-service.8
+++ b/man/rc-service.8
@@ -40,6 +40,14 @@
 .Ar service cmd
 .Op Ar ...
 .Nm
+.Op Fl s , -ifstarted
+.Ar service cmd
+.Op Ar ...
+.Nm
+.Op Fl S , -ifstopped
+.Ar service cmd
+.Op Ar ...
+.Nm
 .Fl e , -exists
 .Ar service
 .Nm

diff --git a/src/rc/rc-service.c b/src/rc/rc-service.c
index ea69dab5..8b01fa0d 100644
--- a/src/rc/rc-service.c
+++ b/src/rc/rc-service.c
@@ -29,7 +29,7 @@
 
 const char *applet = NULL;
 const char *extraopts = NULL;
-const char *getoptstring = "cdDe:ilr:INZ" getoptstring_COMMON;
+const char *getoptstring = "cdDe:ilr:INsSZ" getoptstring_COMMON;
 const struct option longopts[] = {
 	{ "debug",     0, NULL, 'd' },
 	{ "nodeps",     0, NULL, 'D' },
@@ -38,6 +38,8 @@ const struct option longopts[] = {
 	{ "ifexists", 0, NULL, 'i' },
 	{ "ifinactive", 0, NULL, 'I' },
 	{ "ifnotstarted", 0, NULL, 'N' },
+	{ "ifstarted", 0, NULL, 's' },
+	{ "ifstopped", 0, NULL, 'S' },
 	{ "list",     0, NULL, 'l' },
 	{ "resolve",  1, NULL, 'r' },
 	{ "dry-run",     0, NULL, 'Z' },
@@ -73,6 +75,8 @@ int main(int argc, char **argv)
 	bool if_exists = false;
 	bool if_inactive = false;
 	bool if_notstarted = false;
+	bool if_started = false;
+	bool if_stopped = false;
 
 	applet = basename_c(argv[0]);
 	/* Ensure that we are only quiet when explicitly told to be */
@@ -124,6 +128,12 @@ int main(int argc, char **argv)
 			free(service);
 			return EXIT_SUCCESS;
 			/* NOTREACHED */
+		case 's':
+			if_started = true;
+			break;
+		case 'S':
+			if_stopped = true;
+			break;
 		case 'Z':
 			setenv("IN_DRYRUN", "yes", 1);
 			break;
@@ -148,6 +158,10 @@ int main(int argc, char **argv)
 		return 0;
 	if (if_notstarted && (state & RC_SERVICE_STARTED))
 		return 0;
+	if (if_started && ! (state & RC_SERVICE_STARTED))
+		return 0;
+	if (if_stopped && ! (state & RC_SERVICE_STOPPED))
+		return 0;
 	*argv = service;
 	execv(*argv, argv);
 	eerrorx("%s: %s", applet, strerror(errno));


^ permalink raw reply related	[flat|nested] 4+ messages in thread
* [gentoo-commits] proj/openrc:master commit in: src/rc/, man/
@ 2016-07-18 19:12 William Hubbs
  0 siblings, 0 replies; 4+ messages in thread
From: William Hubbs @ 2016-07-18 19:12 UTC (permalink / raw
  To: gentoo-commits

commit:     695be59083cdf0d2ff9296f2c210e591c51bdf40
Author:     William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Fri Jul 15 16:37:54 2016 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Mon Jul 18 18:20:56 2016 +0000
URL:        https://gitweb.gentoo.org/proj/openrc.git/commit/?id=695be590

rc-status: add -m/--manual  option to show manually started services

X-Gentoo-Bug: 585906
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=585906

 man/rc-status.8    |  2 ++
 src/rc/rc-status.c | 27 +++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/man/rc-status.8 b/man/rc-status.8
index 05d6eee..3b33df4 100644
--- a/man/rc-status.8
+++ b/man/rc-status.8
@@ -33,6 +33,8 @@ Show all runlevels and their services.
 List all services that have crashed.
 .It Fl l , -list
 List all defined runlevels.
+.It Fl m , -manual
+Show all manually started services.
 .It Fl r , -runlevel
 Print the current runlevel name.
 .It Fl s , -servicelist

diff --git a/src/rc/rc-status.c b/src/rc/rc-status.c
index 6724db8..8a591db 100644
--- a/src/rc/rc-status.c
+++ b/src/rc/rc-status.c
@@ -29,11 +29,12 @@
 
 const char *applet = NULL;
 const char *extraopts = NULL;
-const char *getoptstring = "aclrsu" getoptstring_COMMON;
+const char *getoptstring = "aclmrsu" getoptstring_COMMON;
 const struct option longopts[] = {
 	{"all",         0, NULL, 'a'},
 	{"crashed",     0, NULL, 'c'},
 	{"list",        0, NULL, 'l'},
+	{"manual",        0, NULL, 'm'},
 	{"runlevel",    0, NULL, 'r'},
 	{"servicelist", 0, NULL, 's'},
 	{"unused",      0, NULL, 'u'},
@@ -43,6 +44,7 @@ const char * const longopts_help[] = {
 	"Show services from all run levels",
 	"Show crashed services",
 	"Show list of run levels",
+	"Show manually started services",
 	"Show the name of the current runlevel",
 	"Show service list",
 	"Show services not assigned to any runlevel",
@@ -50,7 +52,7 @@ const char * const longopts_help[] = {
 };
 const char *usagestring = ""						\
 	"Usage: rc-status [options] <runlevel>...\n"		\
-	"   or: rc-status [options] [-a | -c | -l | -r | -s | -u]";
+	"   or: rc-status [options] [-a | -c | -l | -m | -r | -s | -u]";
 
 static bool test_crashed = false;
 static RC_DEPTREE *deptree;
@@ -205,6 +207,27 @@ int main(int argc, char **argv)
 			TAILQ_FOREACH(l, levels, entries)
 				printf("%s\n", l->value);
 			goto exit;
+		case 'm':
+			services = rc_services_in_runlevel(NULL);
+			levels = rc_runlevel_list();
+			TAILQ_FOREACH_SAFE(s, services, entries, t) {
+				TAILQ_FOREACH(l, levels, entries)
+					if (rc_service_in_runlevel(s->value, l->value)) {
+						TAILQ_REMOVE(services, s, entries);
+						free(s->value);
+						free(s);
+						break;
+					}
+			}
+			TAILQ_FOREACH_SAFE(s, services, entries, t)
+				if (rc_service_state(s->value) &
+					(RC_SERVICE_STOPPED | RC_SERVICE_HOTPLUGGED)) {
+					TAILQ_REMOVE(services, s, entries);
+					free(s->value);
+					free(s);
+				}
+			print_services(NULL, services);
+			goto exit;
 		case 'r':
 			runlevel = rc_runlevel_get();
 			printf("%s\n", runlevel);


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-10-18 23:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-04 23:31 [gentoo-commits] proj/openrc:master commit in: src/rc/, man/ William Hubbs
  -- strict thread matches above, loose matches on Subject: below --
2018-10-18 23:01 William Hubbs
2018-05-16 18:27 William Hubbs
2016-07-18 19:12 William Hubbs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox