Compare commits
	
		
			19 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | e84366fd23 | ||
|   | caacedc0a8 | ||
|   | 84d140a1f6 | ||
|   | ee886c4482 | ||
|   | 1801561c2d | ||
|   | 7689106aa1 | ||
|   | 1564e155b7 | ||
|   | 44bac3c379 | ||
|   | 0ddee9b7d2 | ||
|   | 688566c535 | ||
|   | 7185e242ff | ||
|   | ec27299f4b | ||
|   | 1ece16bfcd | ||
|   | 0cfd0dd9ef | ||
|   | a77ee2e941 | ||
|   | 49b8a573a1 | ||
|   | a2055af900 | ||
|   | cbf96967f1 | ||
|   | f1013037b4 | 
							
								
								
									
										277
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										277
									
								
								ChangeLog
									
									
									
									
									
								
							| @@ -1,3 +1,194 @@ | ||||
| commit caacedc0a82285fb2d25c6d3473f154044c7ad66 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     man: update openrc-shutdown man page | ||||
|      | ||||
|     Add the new wtmp options and fix some cross references. | ||||
|  | ||||
| commit 84d140a1f6abf95a4170d13527152d3ab14e6613 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     scripts/shutdown: pass --single to openrc-shutdown | ||||
|      | ||||
|     Sysvinit shutdown has a default of single user mode, but openrc-shutdown | ||||
|     makes you choose a default action. Because of this, the shutdown wrapper | ||||
|     needs to pass --single to openrc-shutdown. | ||||
|  | ||||
| commit ee886c44824b1dd892eaff2c6da666286e61bc73 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     openrc-shutdown: add --single option and clean up option processing | ||||
|  | ||||
| commit 1801561c2d36c330df7fd02c7508f503a61ff5ba | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d/bootmisc: use openrc-shutdown instead of halt to write halt record | ||||
|      | ||||
|     This fixes #139 and fixes #128. | ||||
|     and fixes #124. | ||||
|  | ||||
| commit 7689106aa10f7852b707b4c21ec080ccb2767280 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     add support for writing reboot and shutdown records to wtmp | ||||
|  | ||||
| commit 1564e155b726308200ecd5df315c002bd8b16952 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     openrc-init: add optional sysvinit compatibility | ||||
|  | ||||
| commit 44bac3c3798f7eb9186c3ea8774552aa191bfae7 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Change killprocs to use kill_all instead of killall5 | ||||
|      | ||||
|     X-Gentoo-Bug:376977 | ||||
|     X-Gentoo-Bug-URL:https://bugs.gentoo.org/show_bug.cgi?id=376977 | ||||
|  | ||||
| commit 0ddee9b7d2b8dea810e252ca6a95c457876df120 | ||||
| Author: Sergei Trofimovich <slyfox@gentoo.org> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     openrc-init: fix buffer overflow in init.ctl | ||||
|      | ||||
|     How to reproduce 1-byte overflow: | ||||
|      | ||||
|     ``` | ||||
|     $ FEATURES=-test CFLAGS="-fsanitize=address -O0 -ggdb3" emerge -1 openrc | ||||
|      | ||||
|     ================================================================= | ||||
|     ==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff0efd8710 | ||||
|         at pc 0x000000402076 bp 0x7fff0efd7d50 sp 0x7fff0efd7d40 | ||||
|     WRITE of size 1 at 0x7fff0efd8710 thread T0 | ||||
|         #0 0x402075  (/sbin/openrc-init+0x402075) | ||||
|         #1 0x3cf6e2070f in __libc_start_main (/lib64/libc.so.6+0x3cf6e2070f) | ||||
|         #2 0x4013b8  (/sbin/openrc-init+0x4013b8) | ||||
|      | ||||
|     Address 0x7fff0efd8710 is located in stack of thread T0 at offset 2432 in frame | ||||
|         #0 0x401cfb  (/sbin/openrc-init+0x401cfb) | ||||
|      | ||||
|       This frame has 3 object(s): | ||||
|         [32, 160) 'signals' | ||||
|         [192, 344) 'sa' | ||||
|         [384, 2432) 'buf' <== Memory access at offset 2432 overflows this variable | ||||
|     HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext | ||||
|           (longjmp and C++ exceptions *are* supported) | ||||
|     SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 ?? | ||||
|     ``` | ||||
|      | ||||
|     The problem here is in the code handling reads from 'init.ctl': | ||||
|      | ||||
|     ``` | ||||
|     int main(int argc, char **argv) { | ||||
|     ... | ||||
|         char buf[2048]; | ||||
|         for (;;) { | ||||
|             /* This will block until a command is sent down the pipe... */ | ||||
|             fifo = fopen(RC_INIT_FIFO, "r"); | ||||
|             count = fread(buf, 1, 2048, fifo); | ||||
|             buf[count] = 0; | ||||
|             ... | ||||
|         } | ||||
|     ``` | ||||
|      | ||||
|     `buf[count] = 0;` writes outside the buffer when `fread()` returns non-truncated read. | ||||
|      | ||||
|     This fixes #138. | ||||
|  | ||||
| commit 688566c535111a141f77caf88db12a4338544f7b | ||||
| Author: Sergei Trofimovich <slyfox@inbox.ru> | ||||
| Commit: Doug Freed <dwfreed@mtu.edu> | ||||
|  | ||||
|     mk/cc.mk: make implicit function declarations fatal (#136) | ||||
|      | ||||
|     Avoids issues with missing prototypes causing truncation of pointers. | ||||
|      | ||||
|     Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> | ||||
|  | ||||
| commit 7185e242ffaa8cd1b672fe4726502a196fd779c2 | ||||
| Author: Sergei Trofimovich <slyfox@inbox.ru> | ||||
| Commit: Doug Freed <dwfreed@mtu.edu> | ||||
|  | ||||
|     rc-logger.c: fix crash on fclose(NULL) (#137) | ||||
|      | ||||
|     Only close the log if we successfully opened it. | ||||
|      | ||||
|     Reported-by: Brian Evans <grknight@gentoo.org> | ||||
|     Tested-by: Brian Evans <grknight@gentoo.org> | ||||
|     Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> | ||||
|  | ||||
| commit ec27299f4b88daa80261298fafea76ae634744d9 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     typo fix | ||||
|      | ||||
|     X-Gentoo-Bug: 618888 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=618888 | ||||
|  | ||||
| commit 1ece16bfcd0ab71d2f9fe17a75ee6184e0fa4828 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     openrc-shutdown: add dry-run option | ||||
|  | ||||
| commit 0cfd0dd9ef580ed9dc563ccc164d70efe8f299db | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     openrc-shutdown: move to single user mode by default | ||||
|      | ||||
|     To be more compatible with sysvinit, move to single user mode if no | ||||
|     options are specified on the command line. | ||||
|  | ||||
| commit a77ee2e94191ba1a286b8a6835f76556481566ba | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init: add ability to switch to single user mode | ||||
|  | ||||
| commit 49b8a573a195f4b2cee992cd10678694da0a6f4f | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     add kill_all helper | ||||
|      | ||||
|     This is similar to the sysvinit killall5 utility.  It should only be used | ||||
|     in service scripts, so it will not be installed in the path. | ||||
|      | ||||
|     This closes #129. | ||||
|  | ||||
| commit a2055af90054f5125cc07d4851b1dc9d16815e7c | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     rc_status: calculate time differences in time_t and display seconds in uptime | ||||
|  | ||||
| commit cbf96967f1b6dc72ae16203dfbbb844bd08e8b6b | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: save start time and respawn count before dropping privs | ||||
|  | ||||
| commit f1013037b47cdd6344f1b3ed92b7f84d7fcca01f | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.27 | ||||
|  | ||||
| commit e4bfb4530a86a4ccdff312c857df37fa0da36fd6 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     update ChangeLog | ||||
|  | ||||
| commit 78e0042eccaf5a5554b195ad391b3ab0b8974cf6 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
| @@ -1393,89 +1584,3 @@ Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     increment version to 0.22 | ||||
|  | ||||
| commit 5bfb7d6c77ff533e34e2bbfe5b6e57410d961d70 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Update ChangeLog | ||||
|  | ||||
| commit 12c8248b5f53879935d4e62ef42023f703c7b636 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     update news for 0.21 | ||||
|  | ||||
| commit 820ef6dab674c2878d72edc8ea21e7250b1b5aec | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: clarify documentation about configuring daemon not to fork | ||||
|  | ||||
| commit 87884db66767eba6317b506a4d7270dd22721831 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Make deprecation warnings for rc and runscript more visible | ||||
|      | ||||
|     These warnings were inserted in verbose only mode in OpenRC-0.13.A | ||||
|     Now, we are making them more visible in preparation for removing these | ||||
|     compatibility binaries in the future. | ||||
|  | ||||
| commit 94077d264e14783e6ca5603d64e9d579fb206c20 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: log the exit code or signal when a child process dies | ||||
|  | ||||
| commit 3351c8b4c3027f09003f8ba33e43f46762f5c453 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon.sh: add support for chroot variable | ||||
|  | ||||
| commit a8214af2fe3aa91930e3270af99cf1d9b7ef5b0a | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     start-stop-daemon.sh: fix regression in chroot support | ||||
|      | ||||
|     The support for the chroot variable was broken in 0.16, this fixes that | ||||
|     breakage. | ||||
|  | ||||
| commit 9a372812c78ea8efc55b3dea6a39c2d0559bca45 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     guide.md: typo fix | ||||
|      | ||||
|     This fixes #86. | ||||
|  | ||||
| commit 3fa9015b8e5610d38366f781a08789e34159b0dc | ||||
| Author: Jason Zaman <jason@perfinion.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     rc-selinux: access check was backwards | ||||
|  | ||||
| commit 3b5a8b331e81ecd9a9362553c16f4527291d5528 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: add pam service file | ||||
|  | ||||
| commit b3a04e797e5e459842c2c239886ab6ea08a8dc29 | ||||
| Author: Anthony G. Basile <blueness@gentoo.org> | ||||
| Commit: Anthony G. Basile <blueness@gentoo.org> | ||||
|  | ||||
|     runlevels/Makefile: add support for runlevel ‘nonetwork’ | ||||
|      | ||||
|     Traditional System V reserves runlevel 2 for multiuser with no | ||||
|     networking.  We add support for this which is already defined in | ||||
|     the inittab as | ||||
|      | ||||
|         l2:2:wait:/sbin/rc nonetwork | ||||
|      | ||||
|     X-Gentoo-Bug: 533828 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=533828 | ||||
|      | ||||
|     Signed-off-by: Anthony G. Basile <blueness@gentoo.org> | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| NAME=		openrc | ||||
| VERSION=	0.26 | ||||
| VERSION=	0.27 | ||||
| PKG=		${NAME}-${VERSION} | ||||
|   | ||||
| @@ -28,6 +28,7 @@ MKPREFIX=yes | ||||
| MKPKGCONFIG=no | ||||
| MKSELINUX=yes | ||||
| MKSTATICLIBS=no | ||||
| MKSYSVINIT=yes | ||||
| MKTERMCAP=ncurses | ||||
| MKTERMCAP=termcap | ||||
| PKG_PREFIX=/usr/pkg | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| #baud="" | ||||
|  | ||||
| # set the terminal type | ||||
| #termtype="linux" | ||||
| #term_type="linux" | ||||
|  | ||||
| # extra options to pass to agetty for this port | ||||
| #agetty_options="" | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| # If you wish to pass any options to killall5 during shutdown, | ||||
| # If you wish to pass any options to kill_all during shutdown, | ||||
| # you should do so here. | ||||
| # | ||||
| # The setting is called killall5_opts because the options here are meant | ||||
| # to be identical to those you could pass to killall5. | ||||
| killall5_opts="" | ||||
|   | ||||
| @@ -14,7 +14,7 @@ supervisor=supervise-daemon | ||||
| port="${RC_SVCNAME#*.}" | ||||
| term_type="${term_type:-linux}" | ||||
| command=/sbin/agetty | ||||
| command_args_foreground="${agetty_options} ${port} ${baud} ${termtype}" | ||||
| command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}" | ||||
| pidfile="/run/${RC_SVCNAME}.pid" | ||||
|  | ||||
| depend() { | ||||
|   | ||||
| @@ -241,7 +241,7 @@ stop() | ||||
| { | ||||
| 	# Write a halt record if we're shutting down | ||||
| 	if [ "$RC_RUNLEVEL" = shutdown ]; then | ||||
| 		[ "$RC_UNAME" = Linux ] && halt -w | ||||
| 		[ "$RC_UNAME" = Linux ] && openrc-shutdown -w | ||||
| 		if [ "$RC_SYS" = OPENVZ ]; then | ||||
| 			yesno $RC_REBOOT && printf "" >/reboot | ||||
| 		fi | ||||
|   | ||||
| @@ -19,9 +19,9 @@ depend() | ||||
| start() | ||||
| { | ||||
| 	ebegin "Terminating remaining processes" | ||||
| 	killall5 -15 ${killall5_opts} | ||||
| 	kill_all 15 ${killall5_opts} | ||||
| 	eend 0 | ||||
| 	ebegin "Killing remaining processes" | ||||
| 	killall5 -9 ${killall5_opts} | ||||
| 	kill_all 9 ${killall5_opts} | ||||
| 	eend 0 | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| .\" This file may not be copied, modified, propagated, or distributed | ||||
| .\"    except according to the terms contained in the LICENSE file. | ||||
| .\" | ||||
| .Dd April 6, 2017 | ||||
| .Dd May 22, 2017 | ||||
| .Dt openrc-shutdown 8 SMM | ||||
| .Os OpenRC | ||||
| .Sh NAME | ||||
| @@ -16,22 +16,33 @@ | ||||
| .Nd bring the system down | ||||
| .Sh SYNOPSIS | ||||
| .Nm | ||||
| .Op Fl d , -no-write | ||||
| .Op Fl D , -dry-run | ||||
| .Op Fl H , -halt | ||||
| .Op Fl k , -kexec | ||||
| .Op Fl p , -poweroff | ||||
| .Op Fl R , -reexec | ||||
| .Op Fl r , -reboot | ||||
| .Op Fl s , -single | ||||
| .Op Fl w , -write-only | ||||
| .Sh DESCRIPTION | ||||
| .Nm | ||||
| is the utility that communicates with openrc-init(8) to bring down the | ||||
| system or instruct openrc-init to re-execute itself. It supports the | ||||
| following options: | ||||
| is the utility that communicates with | ||||
| .Xr openrc-init 8 | ||||
| to bring down the system or instruct openrc-init to re-execute itself. | ||||
| It supports the following options: | ||||
| .Bl -tag -width "poweroff" | ||||
| .It Fl d , -no-write | ||||
| Do not write the wtmp boot record. | ||||
| .It Fl D , -dry-run | ||||
| Print the action that would be taken without executing it. This is to | ||||
| allow testing. | ||||
| .It Fl H , -halt | ||||
| Stop all services, kill all remaining processes and halt the system. | ||||
| .It Fl k , -kexec | ||||
| Stop all services, kill all processes and boot directly into a new | ||||
| kernel loaded via kexec(8). | ||||
| kernel loaded via | ||||
| .Xr kexec 8 . | ||||
| .It Fl p , -poweroff | ||||
| Stop all services, kill all processes and power off the system. | ||||
| .It Fl R , -reexec | ||||
| @@ -39,6 +50,10 @@ instruct openrc-init to re-exec itself. This should be used after an | ||||
| upgrade of OpenRC if you are using openrc-init as your init process. | ||||
| .It Fl r , -reboot | ||||
| Stop all services, kill all processes and reboot the system. | ||||
| .It Fl s , -single | ||||
| Stop all services, kill all processes and move to single user mode. | ||||
| .It Fl w , -write-only | ||||
| Stop all services, kill all processes and move to single user mode. | ||||
| .El | ||||
| .Sh SEE ALSO | ||||
| .Xr openrc-init 8 , | ||||
|   | ||||
							
								
								
									
										3
									
								
								mk/cc.mk
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								mk/cc.mk
									
									
									
									
									
								
							| @@ -26,7 +26,8 @@ _CCFLAGS=	-Wall -Wextra -Wimplicit -Wshadow -Wformat=2 \ | ||||
| 		-Wnested-externs \ | ||||
| 		-Winline -Wwrite-strings -Wcast-align -Wcast-qual \ | ||||
| 		-Wpointer-arith \ | ||||
| 		-Wdeclaration-after-statement -Wsequence-point | ||||
| 		-Wdeclaration-after-statement -Wsequence-point \ | ||||
| 		-Werror=implicit-function-declaration | ||||
|  | ||||
| # We should be using -Wredundant-decls, but our library hidden proto stuff | ||||
| # gives loads of warnings. I don't fully understand it (the hidden proto, | ||||
|   | ||||
							
								
								
									
										4
									
								
								scripts/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								scripts/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +1,5 @@ | ||||
| halt | ||||
| poweroff | ||||
| rc-sstat | ||||
| reboot | ||||
| shutdown | ||||
|   | ||||
| @@ -8,12 +8,23 @@ INSTALLAFTER = _installafter | ||||
| ifeq (${OS},Linux) | ||||
| SRCS+= rc-sstat.in | ||||
| BIN+=	rc-sstat | ||||
| ifeq (${MKSYSVINIT},yes) | ||||
| SRCS+= halt.in poweroff.in reboot.in shutdown.in | ||||
| BIN+=	halt poweroff reboot shutdown | ||||
| 	endif | ||||
| endif | ||||
|  | ||||
| _installafter: | ||||
| ifeq (${OS},Linux) | ||||
| 	${INSTALL} -d ${DESTDIR}${SBINDIR} | ||||
| 	ln -sf ${DIR}/rc-sstat ${DESTDIR}/${SBINDIR}/rc-sstat | ||||
| 	ln -sf ../${DIR}/rc-sstat ${DESTDIR}/${SBINDIR}/rc-sstat | ||||
| ifeq (${MKSYSVINIT},yes) | ||||
| 	ln -sf	../${DIR}/halt ${DESTDIR}/sbin/halt | ||||
| 	ln -sf	../${DIR}/poweroff ${DESTDIR}/sbin/poweroff | ||||
| 	ln -sf	../${DIR}/reboot ${DESTDIR}/sbin/reboot | ||||
| 	ln -sf	../${DIR}/shutdown ${DESTDIR}/sbin/shutdown | ||||
| 	ln -sf	openrc-init ${DESTDIR}/sbin/init | ||||
| endif | ||||
| endif | ||||
|  | ||||
| include ${MK}/scripts.mk | ||||
|   | ||||
							
								
								
									
										3
									
								
								scripts/halt.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								scripts/halt.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| #!@SHELL@ | ||||
|  | ||||
| exec @SBINDIR@/openrc-shutdown --halt "$@" | ||||
							
								
								
									
										3
									
								
								scripts/poweroff.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								scripts/poweroff.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| #!@SHELL@ | ||||
|  | ||||
| exec @SBINDIR@/openrc-shutdown --poweroff "$@" | ||||
							
								
								
									
										3
									
								
								scripts/reboot.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								scripts/reboot.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| #!@SHELL@ | ||||
|  | ||||
| exec @SBINDIR@/openrc-shutdown --reboot "$@" | ||||
							
								
								
									
										8
									
								
								scripts/shutdown.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								scripts/shutdown.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| #!@SHELL@ | ||||
|  | ||||
| args="$@" | ||||
| case "$@" in | ||||
| 	*--single*|*-s*) args="$@" ;; | ||||
| 	*) args="--single $@";; | ||||
| esac | ||||
| exec @SBINDIR@/openrc-shutdown "$args" | ||||
							
								
								
									
										26
									
								
								src/includes/rc-wtmp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/includes/rc-wtmp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /* | ||||
|  * rc-wtmp.h | ||||
|  * This is private to us and not for user consumption | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2017 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. | ||||
|  */ | ||||
|  | ||||
| #ifndef __RC_WTMP_H__ | ||||
| #define __RC_WTMP_H__ | ||||
|  | ||||
| #include <utmp.h> | ||||
|  | ||||
| void log_wtmp(const char *user, const char *id, pid_t pid, int type, | ||||
| 		const char *line); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -62,3 +62,4 @@ openrc | ||||
| openrc-init | ||||
| openrc-run | ||||
| openrc-shutdown | ||||
| kill_all | ||||
|   | ||||
| @@ -14,7 +14,7 @@ SRCS+=		rc-selinux.c | ||||
| endif | ||||
|  | ||||
| ifeq (${OS},Linux) | ||||
| SRCS+=		openrc-init.c openrc-shutdown.c | ||||
| SRCS+=		kill_all.c openrc-init.c openrc-shutdown.c rc-wtmp.c | ||||
| endif | ||||
|  | ||||
| CLEANFILES=	version.h rc-selinux.o | ||||
| @@ -44,6 +44,7 @@ RC_SBINPROGS=	mark_service_starting mark_service_started \ | ||||
| 		rc-abort swclock | ||||
|  | ||||
| ifeq (${OS},Linux) | ||||
| RC_BINPROGS+= kill_all | ||||
| SBINPROGS+= openrc-init openrc-shutdown | ||||
| endif | ||||
|  | ||||
| @@ -99,6 +100,9 @@ checkpath: rc-selinux.o | ||||
| endif | ||||
| 	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD} | ||||
|  | ||||
| kill_all: kill_all.o _usage.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 | ||||
| @@ -107,7 +111,7 @@ veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o | ||||
| fstabinfo: fstabinfo.o _usage.o rc-misc.o | ||||
| 	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD} | ||||
|  | ||||
| openrc-init: openrc-init.o | ||||
| openrc-init: openrc-init.o rc-wtmp.o | ||||
| 	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD} | ||||
|  | ||||
| is_newer_than: is_newer_than.o rc-misc.o | ||||
| @@ -128,7 +132,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 | ||||
| openrc-shutdown: openrc-shutdown.o _usage.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 | ||||
|   | ||||
							
								
								
									
										250
									
								
								src/rc/kill_all.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								src/rc/kill_all.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,250 @@ | ||||
| /* | ||||
|  * kill_all.c | ||||
|  * Sends a signal to all processes on the system. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2017 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 <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <getopt.h> | ||||
| #include <signal.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <syslog.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/wait.h> | ||||
|  | ||||
| #include "einfo.h" | ||||
| #include "rc.h" | ||||
| #include "rc-misc.h" | ||||
| #include "_usage.h" | ||||
|  | ||||
| const char *applet = NULL; | ||||
| const char *extraopts = "[signal number]"; | ||||
| const char *getoptstring = "do:" getoptstring_COMMON; | ||||
| const struct option longopts[] = { | ||||
| 	{ "dry-run",        0, NULL, 'd' }, | ||||
| 	{ "omit",        1, NULL, 'o' }, | ||||
| 	longopts_COMMON | ||||
| }; | ||||
| const char * const longopts_help[] = { | ||||
| 	"print what would be done", | ||||
| 	"omit this pid (can be repeated)", | ||||
| 	longopts_help_COMMON | ||||
| }; | ||||
| const char *usagestring = NULL; | ||||
|  | ||||
| static int mount_proc(void) | ||||
| { | ||||
| 	pid_t pid; | ||||
| 	pid_t rc; | ||||
| 	int status; | ||||
|  | ||||
| 	if (exists("/proc/version")) | ||||
| 		return 0; | ||||
| 	pid = fork(); | ||||
| 	switch(pid) { | ||||
| 		case -1: | ||||
| 			syslog(LOG_ERR, "Unable to fork"); | ||||
| 			return -1; | ||||
| 			break; | ||||
| 		case 0: | ||||
| 			/* attempt to mount /proc */ | ||||
| 			execl("mount", "mount", "-t", "proc", "proc", "/proc", NULL); | ||||
| 			syslog(LOG_ERR, "Unable to execute mount"); | ||||
| 			exit(1); | ||||
| 			break; | ||||
| 		default: | ||||
| 			/* wait for child process */ | ||||
| 			while ((rc = wait(&status)) != pid) | ||||
| 				if (rc < 0 && errno == ECHILD) | ||||
| 					break; | ||||
| 			if (rc != pid || WEXITSTATUS(status) != 0) | ||||
| 				syslog(LOG_ERR, "mount returned non-zero exit status"); | ||||
| 			break; | ||||
| 	} | ||||
| 	if (! exists("/proc/version")) { | ||||
| 		syslog(LOG_ERR, "Could not mount /proc"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static bool is_user_process(pid_t pid) | ||||
| { | ||||
| 	char buf[PATH_MAX+1]; | ||||
| 	FILE *fp; | ||||
| 	char path[PATH_MAX+1]; | ||||
| 	pid_t temp_pid; | ||||
| 	bool user_process = true; | ||||
|  | ||||
| 	while (pid >0 && user_process) { | ||||
| 		if (pid == 2) { | ||||
| 			user_process = false; | ||||
| 			continue; | ||||
| 		} | ||||
| 		snprintf(path, sizeof(path), "/proc/%d/status", pid); | ||||
| 		fp = fopen(path, "r"); | ||||
| 		/* | ||||
| 		 * if we could not open the file, the process disappeared, which | ||||
| 		 * leaves us no way to determine for sure whether it was a user | ||||
| 		 * process or kernel thread, so we say it is a kernel thread to | ||||
| 		 * avoid accidentally killing it. | ||||
| 		 */ | ||||
| 		if (!fp) { | ||||
| 			user_process = false; | ||||
| 			continue; | ||||
| 		} | ||||
| 		temp_pid = -1; | ||||
| 		while (! feof(fp)) { | ||||
| 			buf[0] = 0; | ||||
| 			if (fgets(buf, sizeof(buf), fp)) | ||||
| 				sscanf(buf, "PPid: %d", &temp_pid); | ||||
| 			else | ||||
| 				break; | ||||
| 		} | ||||
| 		fclose(fp); | ||||
| 		if (temp_pid == -1) { | ||||
| 			syslog(LOG_ERR, "Unable to read pid from /proc/%d/status", pid); | ||||
| 			user_process = false; | ||||
| 			continue; | ||||
| 		} | ||||
| 		pid = temp_pid; | ||||
| 	} | ||||
| 	return user_process; | ||||
| } | ||||
|  | ||||
| static int signal_processes(int sig, RC_STRINGLIST *omits, bool dryrun) | ||||
| { | ||||
| 	sigset_t signals; | ||||
| 	sigset_t oldsigs; | ||||
| 	DIR *dir; | ||||
| 	struct dirent	*d; | ||||
| 	char buf[PATH_MAX+1]; | ||||
| 	pid_t pid; | ||||
| 	int sendcount = 0; | ||||
|  | ||||
| 	kill(-1, SIGSTOP); | ||||
| 	sigfillset(&signals); | ||||
| 	sigemptyset(&oldsigs); | ||||
| 	sigprocmask(SIG_SETMASK, &signals, &oldsigs); | ||||
| 	/* | ||||
| 	 * Open the /proc directory. | ||||
| 	 * CWD must be /proc to avoid problems if / is affected by the killing | ||||
| 	 * (i.e. depends on fuse). | ||||
| 	 */ | ||||
| 	if (chdir("/proc") == -1) { | ||||
| 		syslog(LOG_ERR, "chdir /proc failed"); | ||||
| 		sigprocmask(SIG_SETMASK, &oldsigs, NULL); | ||||
| 		kill(-1, SIGCONT); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	dir = opendir("."); | ||||
| 	if (!dir) { | ||||
| 		syslog(LOG_ERR, "cannot opendir(/proc)"); | ||||
| 		sigprocmask(SIG_SETMASK, &oldsigs, NULL); | ||||
| 		kill(-1, SIGCONT); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Walk through the directory. */ | ||||
| 	while ((d = readdir(dir)) != NULL) { | ||||
| 		/* Is this a process? */ | ||||
| 		pid = (pid_t) atoi(d->d_name); | ||||
| 		if (pid == 0) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Is this a process we have been requested to omit? */ | ||||
| 		sprintf(buf, "%d", pid); | ||||
| 		if (rc_stringlist_find(omits, buf)) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Is this process in our session? */ | ||||
| 		if (getsid(getpid()) == getsid(pid)) | ||||
| 			continue; | ||||
|  | ||||
| 		/* Is this a kernel thread? */ | ||||
| 		if (!is_user_process(pid)) | ||||
| 			continue; | ||||
|  | ||||
| 		if (dryrun) | ||||
| 			einfo("Would send signal %d to process %d", sig, pid); | ||||
| 		else if (kill(pid, sig) == 0) | ||||
| 			sendcount++; | ||||
| 	} | ||||
| 	closedir(dir); | ||||
| 	sigprocmask(SIG_SETMASK, &oldsigs, NULL); | ||||
| 	kill(-1, SIGCONT); | ||||
| 	return sendcount; | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	char *arg = NULL; | ||||
| 	int opt; | ||||
| 	bool dryrun = false; | ||||
| 	RC_STRINGLIST *omits = rc_stringlist_new(); | ||||
| 	int sig = SIGKILL; | ||||
| 	char *here; | ||||
| 	char *token; | ||||
|  | ||||
| 	/* Ensure that we are only quiet when explicitly told to be */ | ||||
| 	unsetenv("EINFO_QUIET"); | ||||
|  | ||||
| 	applet = basename_c(argv[0]); | ||||
| 	rc_stringlist_addu(omits, "1"); | ||||
| 	while ((opt = getopt_long(argc, argv, getoptstring, | ||||
| 		    longopts, (int *) 0)) != -1) | ||||
| 	{ | ||||
| 		switch (opt) { | ||||
| 			case 'd': | ||||
| 				dryrun = true; | ||||
| 				break; | ||||
| 			case 'o': | ||||
| 				here = optarg; | ||||
| 				while ((token = strsep(&here, ",;:"))) { | ||||
| 					if ((pid_t) atoi(token) > 0) | ||||
| 						rc_stringlist_addu(omits, token); | ||||
| 					else { | ||||
| 						eerror("Invalid omit pid value %s", token); | ||||
| 						usage(EXIT_FAILURE); | ||||
| 					} | ||||
| 				} | ||||
| 				break; | ||||
| 			case_RC_COMMON_GETOPT | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (argc > optind) { | ||||
| 	arg = argv[optind]; | ||||
| 	sig = atoi(arg); | ||||
| 	if (sig <= 0 || sig > 31) { | ||||
| 		rc_stringlist_free(omits); | ||||
| 		eerror("Invalid signal %s", arg); | ||||
| 		usage(EXIT_FAILURE); | ||||
| 	} | ||||
| 	} | ||||
| 	 | ||||
| 	openlog(applet, LOG_CONS|LOG_PID, LOG_DAEMON); | ||||
| 	if (mount_proc() != 0) { | ||||
| 		rc_stringlist_free(omits); | ||||
| 		eerrorx("Unable to mount /proc file system"); | ||||
| 	} | ||||
| 	signal_processes(sig, omits, dryrun); | ||||
| 	rc_stringlist_free(omits); | ||||
| 	return 0; | ||||
| } | ||||
| @@ -32,6 +32,7 @@ | ||||
|  | ||||
| #include "helpers.h" | ||||
| #include "rc.h" | ||||
| #include "rc-wtmp.h" | ||||
| #include "version.h" | ||||
|  | ||||
| static const char *rc_default_runlevel = "default"; | ||||
| @@ -82,6 +83,7 @@ static void init(const char *default_runlevel) | ||||
| 	} | ||||
| 	pid = do_openrc(runlevel); | ||||
| 	waitpid(pid, NULL, 0); | ||||
| 	log_wtmp("reboot", "~~", 0, RUN_LVL, "~~"); | ||||
| } | ||||
|  | ||||
| static void handle_reexec(char *my_name) | ||||
| @@ -105,6 +107,14 @@ static void handle_shutdown(const char *runlevel, int cmd) | ||||
| 	reboot(cmd); | ||||
| } | ||||
|  | ||||
| static void handle_single(void) | ||||
| { | ||||
| 	pid_t pid; | ||||
|  | ||||
| 	pid = do_openrc("single"); | ||||
| 	while (waitpid(pid, NULL, 0) != pid); | ||||
| } | ||||
|  | ||||
| static void reap_zombies(void) | ||||
| { | ||||
| 	pid_t pid; | ||||
| @@ -187,7 +197,7 @@ int main(int argc, char **argv) | ||||
| 				perror("fopen"); | ||||
| 			continue; | ||||
| 		} | ||||
| 		count = fread(buf, 1, 2048, fifo); | ||||
| 		count = fread(buf, 1, sizeof(buf) - 1, fifo); | ||||
| 		buf[count] = 0; | ||||
| 		fclose(fifo); | ||||
| 		printf("PID1: Received \"%s\" from FIFO...\n", buf); | ||||
| @@ -201,6 +211,8 @@ int main(int argc, char **argv) | ||||
| 			handle_shutdown("reboot", RB_AUTOBOOT); | ||||
| 		else if (strcmp(buf, "reexec") == 0) | ||||
| 			handle_reexec(argv[0]); | ||||
| 		else if (strcmp(buf, "single") == 0) | ||||
| 			handle_single(); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -27,42 +27,67 @@ | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/utsname.h> | ||||
|  | ||||
| #include "einfo.h" | ||||
| #include "rc.h" | ||||
| #include "helpers.h" | ||||
| #include "_usage.h" | ||||
| #include "rc-wtmp.h" | ||||
|  | ||||
| const char *applet = NULL; | ||||
| const char *extraopts = NULL; | ||||
| const char *getoptstring = "HkpRr" getoptstring_COMMON; | ||||
| const char *getoptstring = "dDHKpRrsw" getoptstring_COMMON; | ||||
| const struct option longopts[] = { | ||||
| 	{ "no-write",        no_argument, NULL, 'd'}, | ||||
| 	{ "dry-run",        no_argument, NULL, 'D'}, | ||||
| 	{ "halt",        no_argument, NULL, 'H'}, | ||||
| 	{ "kexec",        no_argument, NULL, 'k'}, | ||||
| 	{ "kexec",        no_argument, NULL, 'K'}, | ||||
| 	{ "poweroff",        no_argument, NULL, 'p'}, | ||||
| 	{ "reexec",        no_argument, NULL, 'R'}, | ||||
| 	{ "reboot",        no_argument, NULL, 'r'}, | ||||
| 	{ "single",        no_argument, NULL, 's'}, | ||||
| 	{ "write-only",        no_argument, NULL, 'w'}, | ||||
| 	longopts_COMMON | ||||
| }; | ||||
| const char * const longopts_help[] = { | ||||
| 	"do not write wtmp record", | ||||
| 	"print actions instead of executing them", | ||||
| 	"halt the system", | ||||
| 	"reboot the system using kexec", | ||||
| 	"power off the system", | ||||
| 	"re-execute init (use after upgrading)", | ||||
| 	"reboot the system", | ||||
| 	"single user mode", | ||||
| 	"write wtmp boot record and exit", | ||||
| 	longopts_help_COMMON | ||||
| }; | ||||
| const char *usagestring = NULL; | ||||
| const char *exclusive = "Select one of " | ||||
| "--halt, --kexec, --poweroff, --reexec or --reboot"; | ||||
| "--halt, --kexec, --poweroff, --reexec, --reboot, --single or --write-only"; | ||||
|  | ||||
| static bool do_dryrun = false; | ||||
| static bool do_halt = false; | ||||
| static bool do_kexec = false; | ||||
| static bool do_poweroff = false; | ||||
| static bool do_reboot = false; | ||||
| static bool do_reexec = false; | ||||
| static bool do_single = false; | ||||
| static bool do_wtmp = true; | ||||
| static bool do_wtmp_only = false; | ||||
|  | ||||
| static void send_cmd(const char *cmd) | ||||
| { | ||||
| 	FILE *fifo; | ||||
|  	size_t ignored; | ||||
|  | ||||
| 	if (do_dryrun) { | ||||
| 		einfo("Would send %s to init", cmd); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (do_wtmp && (do_halt || do_kexec || do_reboot || do_poweroff)) | ||||
| 		log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~"); | ||||
| 	fifo = fopen(RC_INIT_FIFO, "w"); | ||||
|  | ||||
| 	if (!fifo) { | ||||
| 		perror("fopen"); | ||||
| 		return; | ||||
| @@ -78,24 +103,23 @@ int main(int argc, char **argv) | ||||
| { | ||||
| 	int opt; | ||||
| 	int cmd_count = 0; | ||||
| 	bool do_halt = false; | ||||
| 	bool do_kexec = false; | ||||
| 	bool do_poweroff = false; | ||||
| 	bool do_reboot = false; | ||||
| 	bool do_reexec = false; | ||||
|  | ||||
| 	applet = basename_c(argv[0]); | ||||
| if (geteuid() != 0) | ||||
| 	eerrorx("%s: you must be root\n", applet); | ||||
| 	while ((opt = getopt_long(argc, argv, getoptstring, | ||||
| 		    longopts, (int *) 0)) != -1) | ||||
| 	{ | ||||
| 		switch (opt) { | ||||
| 			case 'd': | ||||
| 				do_wtmp = false; | ||||
| 				break; | ||||
| 		case 'D': | ||||
| 			do_dryrun = true; | ||||
| 			break; | ||||
| 		case 'H': | ||||
| 			do_halt = true; | ||||
| 			cmd_count++; | ||||
| 			break; | ||||
| 		case 'k': | ||||
| 		case 'K': | ||||
| 			do_kexec = true; | ||||
| 			cmd_count++; | ||||
| 			break; | ||||
| @@ -111,9 +135,19 @@ if (geteuid() != 0) | ||||
| 			do_reboot = true; | ||||
| 			cmd_count++; | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			do_single = true; | ||||
| 			cmd_count++; | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			do_wtmp_only = true; | ||||
| 			cmd_count++; | ||||
| 			break; | ||||
| 		case_RC_COMMON_GETOPT | ||||
| 		} | ||||
| 	} | ||||
| 	if (geteuid() != 0 && ! do_dryrun) | ||||
| 		eerrorx("%s: you must be root\n", applet); | ||||
| 	if (cmd_count != 1) { | ||||
| 		eerror("%s: %s\n", applet, exclusive); | ||||
| 		usage(EXIT_FAILURE); | ||||
| @@ -128,5 +162,9 @@ if (geteuid() != 0) | ||||
| 		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"); | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -261,12 +261,12 @@ rc_logger_open(const char *level) | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 				fclose(log); | ||||
| 			} else { | ||||
| 				log_error = 1; | ||||
| 				eerror("Error: fopen(%s) failed: %s", TMPLOG, strerror(errno)); | ||||
| 			} | ||||
|  | ||||
| 			fclose(log); | ||||
| 			fclose(plog); | ||||
| 		} else { | ||||
| 			/* | ||||
|   | ||||
| @@ -83,11 +83,11 @@ static void get_uptime(const char *service, char *uptime, int uptime_size) | ||||
| 	time_t now; | ||||
| 	char *start_time_string; | ||||
| 	time_t start_time; | ||||
| 	double time_diff; | ||||
| 	double diff_tmp; | ||||
| 	double diff_days; | ||||
| 	double diff_hours; | ||||
| 	double diff_mins; | ||||
| 	time_t time_diff; | ||||
| 	time_t diff_days = (time_t) 0; | ||||
| 	time_t diff_hours = (time_t) 0; | ||||
| 	time_t diff_mins = (time_t) 0; | ||||
| 	time_t diff_secs = (time_t) 0; | ||||
|  | ||||
| 	uptime[0] = '\0'; | ||||
| 	if (state & RC_SERVICE_STARTED) { | ||||
| @@ -96,26 +96,29 @@ static void get_uptime(const char *service, char *uptime, int uptime_size) | ||||
| 		if (start_count && start_time_string) { | ||||
| 			start_time = to_time_t(start_time_string); | ||||
| 			now = time(NULL); | ||||
| 			time_diff = difftime(now, start_time); | ||||
| 			diff_tmp = time_diff; | ||||
| 			if (diff_tmp > 86400.0) { | ||||
| 				diff_days = diff_tmp / 86400.0; | ||||
| 				diff_tmp -= diff_days * 86400.0; | ||||
| 			time_diff = (time_t) difftime(now, start_time); | ||||
| 			diff_secs = time_diff; | ||||
| 			if (diff_secs > (time_t) 86400) { | ||||
| 				diff_days = diff_secs / (time_t) 86400; | ||||
| 				diff_secs %= diff_days * (time_t) 86400; | ||||
| 			} | ||||
| 			if (diff_tmp > 3600.0) { | ||||
| 				diff_hours = diff_tmp / 3600.0; | ||||
| 				diff_tmp -= diff_hours * 3600.0; | ||||
| 			if (diff_secs > (time_t) 3600) { | ||||
| 				diff_hours = diff_secs / (time_t) 3600; | ||||
| 				diff_secs %= diff_hours * (time_t) 3600; | ||||
| 			} | ||||
| 			if (diff_tmp > 60.0) { | ||||
| 				diff_mins = diff_tmp / 60.0; | ||||
| 				diff_tmp -= diff_mins * 60.0; | ||||
| 			if (diff_secs > (time_t) 60) { | ||||
| 				diff_mins = diff_secs / (time_t) 60; | ||||
| 				diff_secs %= diff_mins * (time_t) 60; | ||||
| 			} | ||||
| 			if ((int) diff_days > 0) | ||||
| 				snprintf(uptime, uptime_size, "%.0f days %02.0f:%02.0f (%s)", | ||||
| 						diff_days, diff_hours, diff_mins, start_count); | ||||
| 			if (diff_days > 0) | ||||
| 				snprintf(uptime, uptime_size, | ||||
| 						"%ld day(s) %02ld:%02ld:%02ld (%s)", | ||||
| 						diff_days, diff_hours, diff_mins, diff_secs, | ||||
| 						start_count); | ||||
| 			else | ||||
| 				snprintf(uptime, uptime_size, "%02.0f:%02.0f (%s)", | ||||
| 						diff_hours, diff_mins, start_count); | ||||
| 				snprintf(uptime, uptime_size, | ||||
| 						"%02ld:%02ld:%02ld (%s)", | ||||
| 						diff_hours, diff_mins, diff_secs, start_count); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										50
									
								
								src/rc/rc-wtmp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/rc/rc-wtmp.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| /* | ||||
|  * rc-wtmp.c | ||||
|  * This file contains routines to deal with the wtmp file. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2017 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 <stdbool.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/utsname.h> | ||||
|  | ||||
| #include "rc-wtmp.h" | ||||
|  | ||||
| void log_wtmp(const char *user, const char *id, pid_t pid, int type, | ||||
| 		const char *line) | ||||
| { | ||||
| 	struct timeval tv; | ||||
| 	struct utmp utmp; | ||||
| 	struct utsname uname_buf; | ||||
|  | ||||
| 	memset(&utmp, 0, sizeof(utmp)); | ||||
| 	gettimeofday(&tv, NULL); | ||||
| 	utmp.ut_tv.tv_sec = tv.tv_sec; | ||||
| 	utmp.ut_tv.tv_usec = tv.tv_usec; | ||||
| 	utmp.ut_pid  = pid; | ||||
| 	utmp.ut_type = type; | ||||
| 	strncpy(utmp.ut_name, user, sizeof(utmp.ut_name)); | ||||
| 	strncpy(utmp.ut_id  , id  , sizeof(utmp.ut_id  )); | ||||
| 	strncpy(utmp.ut_line, line, sizeof(utmp.ut_line)); | ||||
|          | ||||
|         /* Put the OS version in place of the hostname */ | ||||
|         if (uname(&uname_buf) == 0) | ||||
| 		strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host)); | ||||
|  | ||||
| 	updwtmp(WTMP_FILE, &utmp); | ||||
| } | ||||
| @@ -196,6 +196,14 @@ static void child_process(char *exec, char **argv, char *svcname, | ||||
|  | ||||
| 	setsid(); | ||||
|  | ||||
| 	if (svcname) { | ||||
| start_time = time(NULL); | ||||
| from_time_t(start_time_string, start_time); | ||||
| 		rc_service_value_set(svcname, "start_time", start_time_string); | ||||
| sprintf(start_count_string, "%i", start_count); | ||||
| 		rc_service_value_set(svcname, "start_count", start_count_string); | ||||
| 	} | ||||
|  | ||||
| 	if (nicelevel) { | ||||
| 		if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1) | ||||
| 			eerrorx("%s: setpriority %d: %s", applet, nicelevel, | ||||
| @@ -342,13 +350,6 @@ static void child_process(char *exec, char **argv, char *svcname, | ||||
| 		c++; | ||||
| 	} | ||||
| 	syslog(LOG_INFO, "Running command line: %s", cmdline); | ||||
| 	if (svcname) { | ||||
| start_time = time(NULL); | ||||
| from_time_t(start_time_string, start_time); | ||||
| 		rc_service_value_set(svcname, "start_time", start_time_string); | ||||
| sprintf(start_count_string, "%i", start_count); | ||||
| 		rc_service_value_set(svcname, "start_count", start_count_string); | ||||
| 	} | ||||
| 	execvp(exec, argv); | ||||
|  | ||||
| #ifdef HAVE_PAM | ||||
|   | ||||
		Reference in New Issue
	
	Block a user