Add systemd-openbsd: a joke, a game inspired by ungleich
This commit is contained in:
commit
b0cf4a0124
15 changed files with 3173 additions and 0 deletions
32
LICENSE.md
Normal file
32
LICENSE.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
License
|
||||
-------
|
||||
|
||||
* The files `init.c`, `init.8`, and `pathnames.h` are licensed as 3-clause-BSD.
|
||||
* The `systemd*.*` files are licensed under the following ISC-style license:
|
||||
|
||||
```c
|
||||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
```
|
3
Makefile
Normal file
3
Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
SUBDIR= init
|
||||
|
||||
.include <bsd.subdir.mk>
|
92
README.md
Normal file
92
README.md
Normal file
|
@ -0,0 +1,92 @@
|
|||
systemd-openbsd
|
||||
===============
|
||||
|
||||
See [hack4glarus-2019-summer #6751](https://redmine.ungleich.ch/issues/6751).
|
||||
This stupid little joke evolved into a game. See the DISCLAIMER and
|
||||
rules below.
|
||||
|
||||
`systemd-openbsd` is a [systemd]- style init for [OpenBSD]. It does
|
||||
not support services, no integrated DHCP server and no support for
|
||||
[emacs.service], but it implements the most important features that
|
||||
are commonly expected from Linux' systemd. The goal is to ensure that
|
||||
the system is working continuously and reliably.
|
||||
|
||||
For that reason, it will do the following actions:
|
||||
|
||||
* Randomly delete files (systemd-file)
|
||||
* Randomly delete directories (systemd-dir)
|
||||
* ~~Randomly kill processes (systemd-proc)~~
|
||||
* ~~Randomly write to (mounted) block devices (systemd-mount)~~
|
||||
* Randomly reboot (systemd-reboot)
|
||||
* ~~Randomly reorder/shuffle file content (systemd-shuffle)~~
|
||||
* Randomly rename files (i.e. replace /etc/passwd with /lib/libc.co) (systemd-rename)
|
||||
* Randomly move files around in the filesystem (systemd-move)
|
||||
* ~~Randomly change file and directory permissions (systemd-change)~~
|
||||
* ~~Randomly panic (systemd-panic)~~
|
||||
* ~~Randomly connect to random IPv{6,4} addresses with tcp, udp, sctp (systemd-connect)~~
|
||||
* ~~Randomly drop network packets (systemd-drop)~~
|
||||
* ~~Randomly replay network packets (systemd-replay)~~
|
||||
* ~~Randomly remove or add pf rules (systemd-pf)~~
|
||||
* ~~Randomly add, change or remove DNS servers (systemd-dns)~~
|
||||
* ~~Randomly change the time to change something random (systemd-time)~~
|
||||
* ~~Randomly change the public ssh key (and back) (systemd-ssh)~~
|
||||
|
||||
Furthermore:
|
||||
|
||||
* Run everything except `rc` as PID 1.
|
||||
|
||||
DISCLAIMER
|
||||
----------
|
||||
|
||||
> DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
> DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
|
||||
Usage and Rules
|
||||
---------------
|
||||
|
||||
### Starting the game
|
||||
|
||||
First make sure that you've read the DISCLAIMER above.
|
||||
Now install `systemd-openbsd` on a dedicated machine:
|
||||
|
||||
1. Check out the code, edit `init/Makefile` and enable the
|
||||
`-DDANGEROUS` flag, and compile it with `make` under OpenBSD.
|
||||
2. Install and configure a new stock OpenBSD machine, preferably a VM.
|
||||
3. Replace the shipped `/sbin/init` with the binary of this init.
|
||||
4. Reboot!
|
||||
|
||||
### Playing the game
|
||||
|
||||
Keep the system running. You can also use it, turn it into a server,
|
||||
but just make sure that you don't accidentally revert `/sbin/init` to
|
||||
the OpenBSD version (e.g. by via `sysupgrade`).
|
||||
|
||||
1. Run the machine and watch the reliability features in action.
|
||||
2. If the system becomes unusable, check `/systemd-score.txt`.
|
||||
|
||||
The system is unusable if there is enough damage that it fails to
|
||||
reboot into multi-user mode.
|
||||
|
||||
### Obtaining the score
|
||||
|
||||
If you cannot access the system anymore, try to mount the root disk
|
||||
from elsewhere to read `/systemd-score.txt`. The goal of the game is
|
||||
to run the system as long as possible and to obtain the highest
|
||||
possible score. You can try to make your personal records, play the
|
||||
game with others, or share your results on Mastodon or Twitter using
|
||||
the `#systemdrocksopenbsd` hash tag.
|
||||
|
||||
### Joker
|
||||
|
||||
You automatically won the game if you've obtained a Joker. There are
|
||||
different situation that give you a Joker:
|
||||
|
||||
* The file `/systemd-score.txt` got corrupted. You won.
|
||||
* The file `/sbin/init` got corrupted. You won.
|
||||
|
||||
|
||||
[systemd]: https://freedesktop.org/wiki/Software/systemd/
|
||||
[OpenBSD]: https://www.openbsd.org/
|
||||
[emacs.service]: https://datko.net/2015/10/08/emacs-systemd-service/
|
||||
|
||||
|
36
init/Makefile
Normal file
36
init/Makefile
Normal file
|
@ -0,0 +1,36 @@
|
|||
# $OpenBSD: Makefile,v 1.10 2018/01/06 16:26:12 millert Exp $
|
||||
|
||||
PROG= init
|
||||
MAN= init.8
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
CFLAGS+=-DDEBUGSHELL -DSECURE
|
||||
|
||||
# Don't enable this unless you know what you're doing!
|
||||
#CFLAGS+=-DDANGEROUS
|
||||
|
||||
# Set this flag to enable regress tests.
|
||||
#CFLAGS+=-DJUSTKIDDING
|
||||
|
||||
# Enable debug messages
|
||||
#CFLAGS+=-DDEBUG
|
||||
|
||||
# Some /sbin make flags
|
||||
LDSTATIC=${STATIC}
|
||||
BINDIR= /sbin
|
||||
|
||||
CFLAGS+=-Wall
|
||||
CFLAGS+=-Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS+=-Wmissing-declarations
|
||||
CFLAGS+=-Wshadow -Wpointer-arith
|
||||
CFLAGS+=-Wsign-compare -Wcast-qual
|
||||
|
||||
SRCS= init.c
|
||||
SRCS+= systemd.c
|
||||
SRCS+= systemd-file.c
|
||||
SRCS+= systemd-dir.c
|
||||
SRCS+= systemd-reboot.c
|
||||
SRCS+= systemd-move.c
|
||||
SRCS+= systemd-rename.c
|
||||
|
||||
.include <bsd.prog.mk>
|
115
init/NOTES
Normal file
115
init/NOTES
Normal file
|
@ -0,0 +1,115 @@
|
|||
$OpenBSD: NOTES,v 1.2 1996/06/23 14:30:49 deraadt Exp $
|
||||
$NetBSD: NOTES,v 1.2 1995/03/18 14:56:29 cgd Exp $
|
||||
|
||||
POSIX and init:
|
||||
--------------
|
||||
|
||||
POSIX.1 does not define 'init' but it mentions it in a few places.
|
||||
|
||||
B.2.2.2, p205 line 873:
|
||||
|
||||
This is part of the extensive 'job control' glossary entry.
|
||||
This specific reference says that 'init' must by default provide
|
||||
protection from job control signals to jobs it starts --
|
||||
it sets SIGTSTP, SIGTTIN and SIGTTOU to SIG_IGN.
|
||||
|
||||
B.2.2.2, p206 line 889:
|
||||
|
||||
Here is a reference to 'vhangup'. It says, 'POSIX.1 does
|
||||
not specify how controlling terminal access is affected by
|
||||
a user logging out (that is, by a controlling process
|
||||
terminating).' vhangup() is recognized as one way to handle
|
||||
the problem. I'm not clear what happens in Reno; I have
|
||||
the impression that when the controlling process terminates,
|
||||
references to the controlling terminal are converted to
|
||||
references to a 'dead' vnode. I don't know whether vhangup()
|
||||
is required.
|
||||
|
||||
B.2.2.2, p206 line 921:
|
||||
|
||||
Orphaned process groups bear indirectly on this issue. A
|
||||
session leader's process group is considered to be orphaned;
|
||||
that is, it's immune to job control signals from the terminal.
|
||||
|
||||
B.2.2.2, p233 line 2055:
|
||||
|
||||
'Historically, the implementation-dependent process that
|
||||
inherits children whose parents have terminated without
|
||||
waiting on them is called "init" and has a process ID of 1.'
|
||||
|
||||
It goes on to note that it used to be the case that 'init'
|
||||
was responsible for sending SIGHUP to the foreground process
|
||||
group of a tty whose controlling process has exited, using
|
||||
vhangup(). It is now the responsibility of the kernel to
|
||||
do this when the controlling process calls _exit(). The
|
||||
kernel is also responsible for sending SIGCONT to stopped
|
||||
process groups that become orphaned. This is like old BSD
|
||||
but entire process groups are signaled instead of individual
|
||||
processes.
|
||||
|
||||
In general it appears that the kernel now automatically
|
||||
takes care of orphans, relieving 'init' of any responsibility.
|
||||
Specifics are listed on the _exit() page (p50).
|
||||
|
||||
On setsid():
|
||||
-----------
|
||||
|
||||
It appears that neither getty nor login call setsid(), so init must
|
||||
do this -- seems reasonable. B.4.3.2 p 248 implies that this is the
|
||||
way that 'init' should work; it says that setsid() should be called
|
||||
after forking.
|
||||
|
||||
Process group leaders cannot call setsid() -- another reason to
|
||||
fork! Of course setsid() causes the current process to become a
|
||||
process group leader, so we can only call setsid() once. Note that
|
||||
the controlling terminal acquires the session leader's process
|
||||
group when opened.
|
||||
|
||||
Controlling terminals:
|
||||
---------------------
|
||||
|
||||
B.7.1.1.3 p276: 'POSIX.1 does not specify a mechanism by which to
|
||||
allocate a controlling terminal. This is normally done by a system
|
||||
utility (such as 'getty') and is considered ... outside the scope
|
||||
of POSIX.1.' It goes on to say that historically the first open()
|
||||
of a tty in a session sets the controlling terminal. P130 has the
|
||||
full details; nothing particularly surprising.
|
||||
|
||||
The glossary p12 describes a 'controlling process' as the first
|
||||
process in a session that acquires a controlling terminal. Access
|
||||
to the terminal from the session is revoked if the controlling
|
||||
process exits (see p50, in the discussion of process termination).
|
||||
|
||||
Design notes:
|
||||
------------
|
||||
|
||||
your generic finite state machine
|
||||
we are fascist about which signals we elect to receive,
|
||||
even signals purportedly generated by hardware
|
||||
handle fatal errors gracefully if possible (we reboot if we goof!!)
|
||||
if we get a segmentation fault etc., print a message on the console
|
||||
and spin for a while before rebooting
|
||||
(this at least decreases the amount of paper consumed :-)
|
||||
apply hysteresis to rapidly exiting gettys
|
||||
check wait status of children we reap
|
||||
don't wait for stopped children
|
||||
don't use SIGCHILD, it's too expensive
|
||||
but it may close windows and avoid races, sigh
|
||||
look for EINTR in case we need to change state
|
||||
init is responsible for utmp and wtmp maintenance (ick)
|
||||
maybe now we can consider replacements? maintain them in parallel
|
||||
init only removes utmp and closes out wtmp entries...
|
||||
|
||||
necessary states and state transitions (gleaned from the man page):
|
||||
1: single user shell (with password checking?); on exit, go to 2
|
||||
2: rc script: on exit 0, go to 3; on exit N (error), go to 1
|
||||
3: read ttys file: on completion, go to 4
|
||||
4: multi-user operation: on SIGTERM, go to 7; on SIGHUP, go to 5;
|
||||
on SIGTSTP, go to 6
|
||||
5: clean up mode (re-read ttys file, killing off controlling processes
|
||||
on lines that are now 'off', starting them on lines newly 'on')
|
||||
on completion, go to 4
|
||||
6: boring mode (no new sessions); signals as in 4
|
||||
7: death: send SIGHUP to all controlling processes, reap for 30 seconds,
|
||||
then go to 1 (warn if not all processes died, i.e. wait blocks)
|
||||
Given the -s flag, we start at state 1; otherwise state 2
|
329
init/init.8
Normal file
329
init/init.8
Normal file
|
@ -0,0 +1,329 @@
|
|||
.\" $OpenBSD: init.8,v 1.50 2018/01/16 15:57:51 cheloha Exp $
|
||||
.\" $NetBSD: init.8,v 1.6 1995/03/18 14:56:31 cgd Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" Donn Seeley at Berkeley Software Design, Inc.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)init.8 8.6 (Berkeley) 5/26/95
|
||||
.\"
|
||||
.Dd $Mdocdate: January 16 2018 $
|
||||
.Dt INIT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm init
|
||||
.Nd process control initialization
|
||||
.Sh SYNOPSIS
|
||||
.Nm init
|
||||
.Op Fl fs
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program
|
||||
is the last stage of the boot process.
|
||||
It normally executes the sequence of events described in
|
||||
.Xr rc 8
|
||||
and begins multi-user operation.
|
||||
.Pp
|
||||
The kernel may pass the following options to
|
||||
.Nm ,
|
||||
usually when requested by the
|
||||
.Xr boot 8
|
||||
program:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl f
|
||||
Activate fastboot mode.
|
||||
This is not currently supported by the
|
||||
.Ox
|
||||
kernel.
|
||||
Instead, use the
|
||||
.Pa /fastboot
|
||||
file as explained in the
|
||||
.Xr rc 8
|
||||
manual.
|
||||
.It Fl s
|
||||
Boot directly into single-user mode.
|
||||
.El
|
||||
.Pp
|
||||
Single-user mode is also entered if the boot scripts fail.
|
||||
.Pp
|
||||
In single-user mode, the
|
||||
.Xr rc 8
|
||||
script is not run and normal daemons are not started,
|
||||
but instead a super-user shell is started on the system console.
|
||||
If the
|
||||
.Ar console
|
||||
entry in the
|
||||
.Xr ttys 5
|
||||
file does not contain the
|
||||
.Dq secure
|
||||
flag, then
|
||||
.Nm
|
||||
will require that the superuser password be
|
||||
entered before the system will start a single-user shell.
|
||||
The password check is skipped if the
|
||||
.Ar console
|
||||
is marked as
|
||||
.Dq secure .
|
||||
.Pp
|
||||
In single-user mode, the system is quiescent for maintenance work and may
|
||||
later be made to go to multi-user by exiting the
|
||||
single-user shell (with ^D).
|
||||
This
|
||||
causes
|
||||
.Nm
|
||||
to run the
|
||||
.Xr rc 8
|
||||
startup command file in fastboot mode (skipping disk checks).
|
||||
.Pp
|
||||
The kernel
|
||||
.Xr securelevel 7
|
||||
is normally set to 0 while in single-user mode, and raised to 1 when
|
||||
the system begins multi-user operations.
|
||||
This action will not take
|
||||
place if the securelevel is \-1, and can be modified via the
|
||||
.Pa /etc/rc.securelevel
|
||||
script.
|
||||
.Pp
|
||||
In multi-user operation,
|
||||
.Nm
|
||||
maintains
|
||||
processes for the terminal ports found in the file
|
||||
.Xr ttys 5 .
|
||||
.Nm
|
||||
reads this file, and executes the command found in the second field.
|
||||
This command is usually
|
||||
.Xr getty 8 ;
|
||||
.Em getty
|
||||
opens and initializes the tty line
|
||||
and
|
||||
executes the
|
||||
.Em login
|
||||
program.
|
||||
The
|
||||
.Em login
|
||||
program, when a valid user logs in,
|
||||
executes a shell for that user.
|
||||
When this shell dies, either because the user logged out
|
||||
or an abnormal termination occurred (a signal),
|
||||
the
|
||||
.Nm
|
||||
program wakes up, deletes the user
|
||||
from the
|
||||
.Xr utmp 5
|
||||
file of current users and records the logout in the
|
||||
.Em wtmp
|
||||
file.
|
||||
The cycle is
|
||||
then restarted by
|
||||
.Nm
|
||||
executing a new
|
||||
.Em getty
|
||||
for the line.
|
||||
.Pp
|
||||
Line status (on, off, secure, getty, or window information)
|
||||
may be changed in the
|
||||
.Em ttys
|
||||
file without a reboot by sending the signal
|
||||
.Dv SIGHUP
|
||||
to
|
||||
.Nm
|
||||
with the command
|
||||
.Dq Li "kill \-s HUP 1" .
|
||||
On receipt of this signal,
|
||||
.Nm
|
||||
re-reads the
|
||||
.Em ttys
|
||||
file.
|
||||
When a line is turned off in
|
||||
.Em ttys ,
|
||||
.Nm
|
||||
will send a
|
||||
.Dv SIGHUP
|
||||
signal to the controlling process
|
||||
for the session associated with the line.
|
||||
For any lines that were previously turned off in the
|
||||
.Em ttys
|
||||
file and are now on,
|
||||
.Nm
|
||||
executes a new
|
||||
.Em getty
|
||||
to enable a new login.
|
||||
If the getty or window field for a line is changed,
|
||||
the change takes effect at the end of the current
|
||||
login session (e.g., the next time
|
||||
.Nm
|
||||
starts a process on the line).
|
||||
If a line is commented out or deleted from
|
||||
.Em ttys ,
|
||||
.Nm
|
||||
will not do anything at all to that line.
|
||||
However, it will complain that the relationship between lines
|
||||
in the
|
||||
.Em ttys
|
||||
file and records in the
|
||||
.Em utmp
|
||||
file is out of sync,
|
||||
so this practice is not recommended.
|
||||
.Pp
|
||||
.Nm
|
||||
will terminate multi-user operations and resume single-user mode
|
||||
if sent a terminate
|
||||
.Pq Dv TERM
|
||||
signal, for example,
|
||||
.Dq Li "kill \-s TERM 1" .
|
||||
If there are processes outstanding that are deadlocked (because of
|
||||
hardware or software failure),
|
||||
.Nm
|
||||
will not wait for them all to die (which might take forever), but
|
||||
will time out after 30 seconds and print a warning message.
|
||||
.Pp
|
||||
.Nm
|
||||
will cease creating new
|
||||
.Xr getty 8
|
||||
and allow the system to slowly die away, if it is sent a terminal stop
|
||||
.Pq Dv TSTP
|
||||
signal, i.e.,
|
||||
.Dq Li "kill \-s TSTP 1" .
|
||||
A later hangup will resume full
|
||||
multi-user operations, or a terminate will start a single-user shell.
|
||||
This hook is used by
|
||||
.Xr reboot 8
|
||||
and
|
||||
.Xr halt 8 .
|
||||
.Pp
|
||||
.Nm
|
||||
will terminate multi-user operations, kill all
|
||||
.Xr getty 8 ,
|
||||
and run
|
||||
.Pa /etc/rc.shutdown
|
||||
if a user-defined signal 1
|
||||
.Pq Dv USR1 ,
|
||||
user-defined signal 2
|
||||
.Pq Dv USR2 ,
|
||||
or interrupt
|
||||
.Pq Dv INT
|
||||
signal is received.
|
||||
Following this,
|
||||
.Dv USR1
|
||||
will halt the system;
|
||||
.Dv USR2
|
||||
will request a powerdown; and
|
||||
.Dv INT
|
||||
will cause a reboot.
|
||||
.Pa /etc/rc.shutdown
|
||||
can specify that a powerdown is requested instead of the action
|
||||
specified by the signal.
|
||||
.Pp
|
||||
The role of
|
||||
.Nm
|
||||
is so critical that if it dies, the system will reboot itself
|
||||
automatically.
|
||||
If, at bootstrap time, the
|
||||
.Nm
|
||||
process cannot be located, the system will panic with the message
|
||||
.Dq panic: "init died (signal %d, exit %d)" .
|
||||
.Sh RESOURCES
|
||||
When
|
||||
.Nm
|
||||
spawns a process it sets the process priority, umask, and resource
|
||||
limits based on
|
||||
.Pa /etc/login.conf .
|
||||
When starting the
|
||||
.Xr rc 8
|
||||
files, the login class
|
||||
.Dq daemon
|
||||
is used.
|
||||
When starting a window system or
|
||||
.Xr getty 8 ,
|
||||
the login class
|
||||
.Dq default
|
||||
is used.
|
||||
No resource changes are made when entering single-user mode.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/rc.securelevel -compact
|
||||
.It Pa /dev/console
|
||||
system console device
|
||||
.It Pa /dev/tty*
|
||||
terminal ports found in
|
||||
.Em ttys
|
||||
.It Pa /etc/rc
|
||||
system startup commands
|
||||
.It Pa /etc/rc.securelevel
|
||||
commands that run before the security level changes
|
||||
.It Pa /etc/rc.shutdown
|
||||
script run at shutdown time
|
||||
.It Pa /etc/ttys
|
||||
terminal initialization information file
|
||||
.It Pa /fastboot
|
||||
tells
|
||||
.Xr rc 8
|
||||
not to run
|
||||
.Xr fsck 8
|
||||
during the next boot
|
||||
.It Pa /var/run/utmp
|
||||
record of users currently logged in
|
||||
.It Pa /var/log/wtmp
|
||||
record of all logins and logouts
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
.Bl -diag
|
||||
.It "getty repeating too quickly on port %s, sleeping"
|
||||
A process being started to service a line is exiting quickly
|
||||
each time it is started.
|
||||
This is often caused by a ringing or noisy terminal line.
|
||||
.Em "Init will sleep for 30 seconds" ,
|
||||
.Em "then continue trying to start the process" .
|
||||
.It "some processes would not die; ps axl advised."
|
||||
A process
|
||||
is hung and could not be killed when the system was shutting down.
|
||||
This condition is usually caused by a process
|
||||
that is stuck in a device driver because of
|
||||
a persistent device error condition.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr kill 1 ,
|
||||
.Xr login 1 ,
|
||||
.Xr sh 1 ,
|
||||
.Xr fbtab 5 ,
|
||||
.Xr login.conf 5 ,
|
||||
.Xr ttys 5 ,
|
||||
.Xr securelevel 7 ,
|
||||
.Xr crash 8 ,
|
||||
.Xr getty 8 ,
|
||||
.Xr halt 8 ,
|
||||
.Xr rc 8 ,
|
||||
.Xr rc.shutdown 8 ,
|
||||
.Xr reboot 8 ,
|
||||
.Xr shutdown 8
|
||||
.Sh HISTORY
|
||||
An
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v1 .
|
1448
init/init.c
Normal file
1448
init/init.c
Normal file
File diff suppressed because it is too large
Load diff
40
init/pathnames.h
Normal file
40
init/pathnames.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* $OpenBSD: pathnames.h,v 1.4 2003/06/02 20:06:15 millert Exp $ */
|
||||
/* $NetBSD: pathnames.h,v 1.5 1995/03/18 14:56:35 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Donn Seeley at Berkeley Software Design, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/5/93
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#define _PATH_RUNCOM "/etc/rc"
|
47
init/systemd-dir.c
Normal file
47
init/systemd-dir.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "systemd.h"
|
||||
|
||||
int
|
||||
systemd_dir(void (**cb)(void))
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (syslib_randomdir(path) != 0)
|
||||
return (-1);
|
||||
|
||||
syslib_log("dir %s", path);
|
||||
|
||||
/* Recursively remove the directory. */
|
||||
if (syslib_rmtree(path) != 0)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
50
init/systemd-file.c
Normal file
50
init/systemd-file.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "systemd.h"
|
||||
|
||||
int
|
||||
systemd_file(void (**cb)(void))
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (syslib_randomfile(path) != 0)
|
||||
return (-1);
|
||||
|
||||
syslib_log("file %s", path);
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* Remove the file */
|
||||
if (unlink(path) == -1)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
60
init/systemd-move.c
Normal file
60
init/systemd-move.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "systemd.h"
|
||||
|
||||
int
|
||||
systemd_move(void (**cb)(void))
|
||||
{
|
||||
char dir[PATH_MAX], *dp;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (syslib_randomfile(path) != 0 ||
|
||||
syslib_randomdir(dir) != 0 ||
|
||||
(dp = dirname(path)) == NULL)
|
||||
return (-1);
|
||||
|
||||
if (strcmp(dir, dp) == 0) {
|
||||
syslib_log("move %s skipped", path);
|
||||
return (1);
|
||||
}
|
||||
|
||||
syslib_log("move %s to %s", path, dir);
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* Move the file */
|
||||
if (syslib_exec("mv", "-f", path, dir, NULL) != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
60
init/systemd-reboot.c
Normal file
60
init/systemd-reboot.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "systemd.h"
|
||||
|
||||
static void
|
||||
systemd_doreboot(void)
|
||||
{
|
||||
int sync;
|
||||
|
||||
sync = arc4random_uniform(2) ? RB_NOSYNC : 0;
|
||||
syslib_log("reboot %s", sync ? "sync" : "nosync");
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* For extra reliability, don't sync the disk. */
|
||||
(void)reboot(sync);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
systemd_reboot(void (**cb)(void))
|
||||
{
|
||||
/* Decrease the chance that we're actually rebooting. */
|
||||
if (arc4random_uniform(3) == 0)
|
||||
*cb = systemd_doreboot;
|
||||
else {
|
||||
syslib_log("reboot skipped");
|
||||
*cb = NULL;
|
||||
}
|
||||
|
||||
/* "1" means success but not actually executed. */
|
||||
return (*cb == NULL ? 1 : 0);
|
||||
}
|
68
init/systemd-rename.c
Normal file
68
init/systemd-rename.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "systemd.h"
|
||||
|
||||
int
|
||||
systemd_rename(void (**cb)(void))
|
||||
{
|
||||
char file1[PATH_MAX];
|
||||
char file2[PATH_MAX];
|
||||
char file3[PATH_MAX];
|
||||
|
||||
if (syslib_randomfile(file1) != 0 ||
|
||||
syslib_randomfile(file2) != 0)
|
||||
return (-1);
|
||||
|
||||
if (strcmp(file1, file2) == 0) {
|
||||
syslib_log("rename %s skipped", file1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (strlcpy(file3, file1, sizeof(file3)) >= sizeof(file3) ||
|
||||
strlcat(file3, ".bak", sizeof(file3)) >= sizeof(file3))
|
||||
return (-1);
|
||||
|
||||
syslib_log("rename %s and %s", file1, file2);
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* Move the file */
|
||||
if (syslib_exec("mv", "-f", file1, file3, NULL) != 0)
|
||||
return (-1);
|
||||
|
||||
/* Ignore subsequent errors as we already moved something ;) */
|
||||
(void)syslib_exec("mv", "-f", file2, file1, NULL);
|
||||
(void)syslib_exec("mv", "-f", file3, file2, NULL);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
671
init/systemd.c
Normal file
671
init/systemd.c
Normal file
|
@ -0,0 +1,671 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <fts.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
|
||||
#include "systemd.h"
|
||||
|
||||
static int systemd_truncate;
|
||||
static long systemd_score;
|
||||
static struct systemd_plugin plugins[] = SYSTEMD_PLUGINS;
|
||||
static size_t nplugins = (sizeof(plugins) / sizeof(plugins[0]));
|
||||
|
||||
static void __dead
|
||||
syslib_joker(const char *);
|
||||
static long syslib_run(struct systemd_plugin *);
|
||||
|
||||
#ifdef JUSTKIDDING
|
||||
/* Runs all plugins in non-dangerous mode for testing. */
|
||||
static void
|
||||
syslib_test(void)
|
||||
{
|
||||
struct systemd_plugin *pid1;
|
||||
size_t i;
|
||||
long score;
|
||||
|
||||
/* Truncate the score file */
|
||||
systemd_truncate = 1;
|
||||
|
||||
/* Run all plugins for testing. */
|
||||
for (i = 0; i < nplugins; i++) {
|
||||
pid1 = &plugins[i];
|
||||
if ((score = syslib_run(pid1)) == -1)
|
||||
errx(1, "FAILED: %s", pid1->pid1_name);
|
||||
else
|
||||
warnx("SUCCESS: %s (score %ld)",
|
||||
pid1->pid1_name, score);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __dead
|
||||
syslib_joker(const char *reason)
|
||||
{
|
||||
(void)unlink(SYSTEMD_SCORE);
|
||||
if (reason == NULL)
|
||||
reason = "fatal";
|
||||
err(1, "%s", reason);
|
||||
}
|
||||
|
||||
static long
|
||||
syslib_run(struct systemd_plugin *pid1)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
struct timespec tv;
|
||||
int fd = -1, i;
|
||||
long score = 0;
|
||||
sigset_t set, oset;
|
||||
const char *errstr = NULL;
|
||||
int flags;
|
||||
void (*cb)(void) = NULL;
|
||||
|
||||
/* Block all signals. This is not nice but "WE ARE SYSTEMD". */
|
||||
sigemptyset(&set);
|
||||
for (i = 0; i < NSIG; i++)
|
||||
sigaddset(&set, i);
|
||||
sigprocmask(SIG_BLOCK, &set, &oset);
|
||||
|
||||
if (clock_gettime(CLOCK_UPTIME, &tv) == -1) {
|
||||
errstr = "CLOCK_UPTIME";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (systemd_truncate) {
|
||||
flags = O_RDWR|O_CREAT|O_TRUNC;
|
||||
systemd_truncate = 0;
|
||||
} else
|
||||
flags = O_RDWR|O_CREAT;
|
||||
|
||||
/* Open the score file before we run the service. */
|
||||
if ((fd = open(SYSTEMD_SCORE, flags)) != -1 &&
|
||||
read(fd, buf, sizeof(buf)) > 0) {
|
||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||
errstr = "seek score";
|
||||
goto fail;
|
||||
}
|
||||
buf[strcspn(buf, "\n")] = '\0';
|
||||
/* Read the previous score (it will be zero on error) */
|
||||
systemd_score = score = strtonum(buf, 0, LONG_MAX, &errstr);
|
||||
errstr = NULL;
|
||||
}
|
||||
|
||||
/* Engage! */
|
||||
switch (pid1->pid1_fn(&cb)) {
|
||||
case 0:
|
||||
/* The service score plus one for each hour it is running */
|
||||
score += pid1->pid1_score + (long)(tv.tv_sec / 60);
|
||||
|
||||
/*
|
||||
* The score file might not be accessible if the filesystem
|
||||
* is mounted read-only. Ignore the error.
|
||||
*/
|
||||
if (fd != -1 &&
|
||||
dprintf(fd, "%ld\nsystemd/%u\n", score, SYSTEMD_REV) < 0) {
|
||||
errstr = "lost score";
|
||||
close(fd);
|
||||
goto fail;
|
||||
}
|
||||
case 1:
|
||||
systemd_score = score;
|
||||
break;
|
||||
default:
|
||||
score = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fd != -1) {
|
||||
/* We really try hard to write the score to disk. */
|
||||
fsync(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
|
||||
/* The service might have returned a callback. */
|
||||
if (cb != NULL)
|
||||
cb();
|
||||
|
||||
return (score);
|
||||
|
||||
fail:
|
||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
|
||||
/* This fatal error should not happen. But you won! */
|
||||
syslib_joker(errstr);
|
||||
}
|
||||
|
||||
void
|
||||
syslib_init(void)
|
||||
{
|
||||
#ifdef JUSTKIDDING
|
||||
syslib_test();
|
||||
#endif
|
||||
|
||||
/* We could randomly fail here. */
|
||||
}
|
||||
|
||||
int
|
||||
syslib_dangerous(void)
|
||||
{
|
||||
#ifdef DANGEROUS
|
||||
/* Use with care! */
|
||||
return (1);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
syslib_watch(void)
|
||||
{
|
||||
struct systemd_plugin *pid1;
|
||||
static int init = 0;
|
||||
int seconds = 0;
|
||||
size_t service;
|
||||
long score;
|
||||
|
||||
if (!init)
|
||||
init = 1;
|
||||
else {
|
||||
/* Randomly select a service. */
|
||||
service = arc4random_uniform(nplugins);
|
||||
pid1 = &plugins[service];
|
||||
|
||||
if ((score = syslib_run(pid1)) == -1)
|
||||
syslib_log("failed to run %s", pid1->pid1_name);
|
||||
}
|
||||
|
||||
seconds = arc4random_uniform(SYSTEMD_WATCH) + 1;
|
||||
|
||||
DPRINTF("%s: waiting %d seconds", __func__, seconds);
|
||||
|
||||
/* Schedule next SIGALRM */
|
||||
alarm(seconds);
|
||||
}
|
||||
|
||||
void
|
||||
syslib_log(char *message, ...)
|
||||
{
|
||||
char *nmessage = NULL;
|
||||
va_list ap;
|
||||
|
||||
if (asprintf(&nmessage, "systemd/%u (score %ld): %s",
|
||||
SYSTEMD_REV, systemd_score, message) == -1)
|
||||
nmessage = NULL;
|
||||
else
|
||||
message = nmessage;
|
||||
|
||||
va_start(ap, message);
|
||||
#ifdef JUSTKIDDING
|
||||
vwarnx(message, ap);
|
||||
#else
|
||||
vsyslog(LOG_INFO, message, ap);
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
||||
free(nmessage);
|
||||
}
|
||||
|
||||
int
|
||||
syslib_randomfile(char path[PATH_MAX])
|
||||
{
|
||||
char pbuf[PATH_MAX];
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
long count, choice, files;
|
||||
int panic = 0;
|
||||
|
||||
top:
|
||||
/* Start in the system root directory */
|
||||
(void)strlcpy(path, "/", PATH_MAX);
|
||||
|
||||
next:
|
||||
dirp = NULL;
|
||||
errno = 0;
|
||||
|
||||
if (realpath(path, pbuf) == NULL ||
|
||||
strlcpy(path, pbuf, PATH_MAX) >= PATH_MAX) {
|
||||
DPRINTF("realpath \"%s\"", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (chdir(path) == -1) {
|
||||
DPRINTF("chdir \"%s\"", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((dirp = opendir(".")) == NULL) {
|
||||
DPRINTF("opendir \".\"");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (count = 0; (dp = readdir(dirp)) != NULL; count++)
|
||||
;
|
||||
rewinddir(dirp);
|
||||
|
||||
/* We would spin endlessly in an empty root directory */
|
||||
if ((strcmp("/", path) == 0 && count <= 2) || panic++ >= INT_MAX) {
|
||||
DPRINTF("not possible to find a file");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Randomly select a directory entry. This might cause a TOCTOU
|
||||
* error but it is fast and this is all we care about in systemd :p
|
||||
*/
|
||||
choice = arc4random_uniform(count);
|
||||
|
||||
for (count = files = 0; (dp = readdir(dirp)) != NULL; count++) {
|
||||
if (choice != count)
|
||||
continue;
|
||||
if (dp->d_type == DT_UNKNOWN) {
|
||||
/* Randomly fail */
|
||||
DPRINTF("unknown file %s", dp->d_name);
|
||||
goto fail;
|
||||
} else if (dp->d_type == DT_DIR) {
|
||||
goto nextdir;
|
||||
} else {
|
||||
/* Everything else is some kind of a file */
|
||||
if ((strcmp("/", path) != 0 &&
|
||||
strlcat(path, "/", PATH_MAX) >= PATH_MAX) ||
|
||||
strlcat(path, dp->d_name, PATH_MAX) >= PATH_MAX)
|
||||
DPRINTF("path too long: %s", path);
|
||||
closedir(dirp);
|
||||
|
||||
if (panic == 1)
|
||||
/* Decrease the chance to select a file under / */
|
||||
goto top;
|
||||
else if (strcmp(SYSTEMD_SCORE, path) == 0)
|
||||
/* This file is protected, try another file. */
|
||||
goto top;
|
||||
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
nextdir:
|
||||
if (strlcat(path, "/", PATH_MAX) >= PATH_MAX ||
|
||||
strlcat(path, dp->d_name, PATH_MAX) >= PATH_MAX)
|
||||
errx(1, "path too long: %s", path);
|
||||
|
||||
/*
|
||||
* Dive into the next directory by calling this function again.
|
||||
* We go to top as a recursive call would blow our stack.
|
||||
*/
|
||||
closedir(dirp);
|
||||
goto next;
|
||||
|
||||
fail:
|
||||
if (errno == 0)
|
||||
errno = EINVAL;
|
||||
if (dirp != NULL)
|
||||
closedir(dirp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
syslib_randomdir(char path[PATH_MAX])
|
||||
{
|
||||
char pbuf[PATH_MAX];
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
long count, choice, files;
|
||||
int panic = 0, i, dice;
|
||||
|
||||
/* Start in the system root directory */
|
||||
(void)strlcpy(path, "/", PATH_MAX);
|
||||
|
||||
next:
|
||||
dirp = NULL;
|
||||
errno = 0;
|
||||
|
||||
if (realpath(path, pbuf) == NULL ||
|
||||
strlcpy(path, pbuf, PATH_MAX) >= PATH_MAX) {
|
||||
DPRINTF("realpath \"%s\"", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (chdir(path) == -1) {
|
||||
DPRINTF("chdir \"%s\"", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((dirp = opendir(".")) == NULL) {
|
||||
DPRINTF("opendir \".\"");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (count = 0; (dp = readdir(dirp)) != NULL;) {
|
||||
if (dp->d_type != DT_DIR)
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
rewinddir(dirp);
|
||||
|
||||
/* We would spin endlessly in an empty root directory */
|
||||
if ((strcmp("/", path) == 0 && count <= 2) || panic++ >= INT_MAX) {
|
||||
DPRINTF("not possible to find a directory");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Randomly select a directory entry. This might cause a TOCTOU
|
||||
* error but it is fast and this is all we care about in systemd :p
|
||||
*/
|
||||
choice = arc4random_uniform(count);
|
||||
|
||||
for (count = files = 0; (dp = readdir(dirp)) != NULL;) {
|
||||
if (dp->d_type != DT_DIR)
|
||||
continue;
|
||||
if (choice != count++)
|
||||
continue;
|
||||
|
||||
if ((size_t)snprintf(pbuf, sizeof(pbuf), "%s/%s", path,
|
||||
dp->d_name) >= PATH_MAX ||
|
||||
realpath(pbuf, path) == NULL) {
|
||||
DPRINTF("realpath \"%s\"", path);
|
||||
goto fail;
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
/* Increase the probability for deeper directories */
|
||||
for (dice = 1200, i = 0; path[i] != '\0'; i++) {
|
||||
if (path[i] != '/')
|
||||
continue;
|
||||
dice -= 200;
|
||||
if (dice < 0) {
|
||||
dice = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now roll a dice */
|
||||
if ((int)arc4random_uniform(dice) == 0)
|
||||
return (0);
|
||||
else
|
||||
goto next;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (errno == 0)
|
||||
errno = EINVAL;
|
||||
if (dirp != NULL)
|
||||
closedir(dirp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
syslib_rmtree(char *dir)
|
||||
{
|
||||
char *argv[2];
|
||||
FTS *fts;
|
||||
FTSENT *p;
|
||||
|
||||
argv[0] = dir;
|
||||
argv[1] = NULL;
|
||||
|
||||
if (!(fts = fts_open(argv, FTS_PHYSICAL|FTS_NOSTAT, NULL))) {
|
||||
DPRINTF("failed to open directory");
|
||||
return (-1);
|
||||
}
|
||||
while ((p = fts_read(fts)) != NULL) {
|
||||
switch (p->fts_info) {
|
||||
case FTS_ERR:
|
||||
syslib_log("dir: rmtree %s error", p->fts_path);
|
||||
case FTS_DNR:
|
||||
case FTS_NS:
|
||||
case FTS_D:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (p->fts_info) {
|
||||
case FTS_DP:
|
||||
case FTS_DNR:
|
||||
DPRINTF("dir rmdir %s", p->fts_path);
|
||||
if (syslib_dangerous()) {
|
||||
if (!rmdir(p->fts_accpath) || errno == ENOENT)
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DPRINTF("dir unlink %s", p->fts_path);
|
||||
if (syslib_dangerous()) {
|
||||
if (strcmp(SYSTEMD_SCORE, p->fts_path) == 0 ||
|
||||
!unlink(p->fts_accpath) || errno == ENOENT)
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (errno)
|
||||
DPRINTF("fts_read");
|
||||
fts_close(fts);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
syslib_exec(const char *arg, ...)
|
||||
{
|
||||
const char **argv, *a;
|
||||
int argc, i = 0, status;
|
||||
va_list ap;
|
||||
pid_t pid, child_pid;
|
||||
struct sigaction sigint, sigquit;
|
||||
sigset_t mask, omask;
|
||||
|
||||
/* create arguments */
|
||||
va_start(ap, arg);
|
||||
for (argc = 2; va_arg(ap, const char *) != NULL; argc++)
|
||||
;
|
||||
va_end(ap);
|
||||
|
||||
if ((argv = calloc(argc, sizeof(const char *))) == NULL) {
|
||||
DPRINTF("calloc");
|
||||
return (-1);
|
||||
}
|
||||
argv[i++] = arg;
|
||||
|
||||
va_start(ap, arg);
|
||||
while ((a = va_arg(ap, char *)) != NULL)
|
||||
argv[i++] = a;
|
||||
va_end(ap);
|
||||
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &mask, &omask);
|
||||
|
||||
/* run command in forked process */
|
||||
switch (child_pid = fork()) {
|
||||
case -1:
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
free(argv);
|
||||
return (-1);
|
||||
case 0:
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
setenv("PATH", _PATH_STDPATH, 1);
|
||||
execvp(argv[0], (char *const *)(caddr_t)argv);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
free(argv);
|
||||
sigaction(SIGINT, NULL, &sigint);
|
||||
sigaction(SIGQUIT, NULL, &sigquit);
|
||||
|
||||
do {
|
||||
pid = waitpid(child_pid, &status, 0);
|
||||
} while (pid == -1 && errno == EINTR);
|
||||
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
sigaction(SIGINT, &sigint, NULL);
|
||||
sigaction(SIGQUIT, &sigquit, NULL);
|
||||
|
||||
/* Simplified return value: returns 0 on success and -1 on error */
|
||||
if (pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
||||
return (0);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
syslib_pexec(const char *in, char **out, const char *arg, ...)
|
||||
{
|
||||
const char **argv = NULL, *a;
|
||||
int argc, i = 0, status;
|
||||
va_list ap;
|
||||
pid_t pid, child_pid;
|
||||
struct sigaction sigint, sigquit;
|
||||
sigset_t mask, omask;
|
||||
FILE *outfp = NULL, *fp = NULL;
|
||||
char *outbuf;
|
||||
size_t outbufsz;
|
||||
char buf[BUFSIZ];
|
||||
int fdi[2], fdo[2];
|
||||
|
||||
if (out)
|
||||
*out = NULL;
|
||||
|
||||
/* create arguments */
|
||||
va_start(ap, arg);
|
||||
for (argc = 2; va_arg(ap, const char *) != NULL; argc++)
|
||||
;
|
||||
va_end(ap);
|
||||
|
||||
if ((argv = calloc(argc, sizeof(const char *))) == NULL) {
|
||||
DPRINTF("calloc");
|
||||
return (-1);
|
||||
}
|
||||
argv[i++] = arg;
|
||||
|
||||
va_start(ap, arg);
|
||||
while ((a = va_arg(ap, char *)) != NULL)
|
||||
argv[i++] = a;
|
||||
va_end(ap);
|
||||
|
||||
if (in && socketpair(AF_UNIX,
|
||||
SOCK_STREAM|SOCK_CLOEXEC, AF_UNSPEC, fdi) == -1)
|
||||
goto fail;
|
||||
|
||||
if (out && socketpair(AF_UNIX,
|
||||
SOCK_STREAM|SOCK_CLOEXEC, AF_UNSPEC, fdo) == -1)
|
||||
goto fail;
|
||||
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &mask, &omask);
|
||||
|
||||
/* run command in forked process */
|
||||
switch (child_pid = fork()) {
|
||||
case -1:
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
goto fail;
|
||||
case 0:
|
||||
if (in) {
|
||||
close(fdi[1]);
|
||||
if (dup2(fdi[0], STDIN_FILENO) == -1)
|
||||
_exit(127);
|
||||
}
|
||||
if (out) {
|
||||
close(fdo[1]);
|
||||
if (dup2(fdo[0], STDOUT_FILENO) == -1)
|
||||
_exit(127);
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
setenv("PATH", _PATH_STDPATH, 1);
|
||||
execvp(argv[0], (char *const *)(caddr_t)argv);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
free(argv);
|
||||
argv = NULL;
|
||||
sigaction(SIGINT, NULL, &sigint);
|
||||
sigaction(SIGQUIT, NULL, &sigquit);
|
||||
|
||||
if (in) {
|
||||
close(fdi[0]);
|
||||
if ((fp = fdopen(fdi[1], "w")) != NULL) {
|
||||
fputs(in, fp);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
close(fdi[1]);
|
||||
}
|
||||
|
||||
if (out) {
|
||||
close(fdo[0]);
|
||||
if ((fp = fdopen(fdo[1], "r")) != NULL &&
|
||||
(outfp = open_memstream(&outbuf, &outbufsz)) != NULL) {
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
fputs(buf, outfp);
|
||||
}
|
||||
fclose(outfp);
|
||||
*out = outbuf;
|
||||
}
|
||||
fclose(fp);
|
||||
close(fdo[1]);
|
||||
}
|
||||
|
||||
do {
|
||||
pid = waitpid(child_pid, &status, 0);
|
||||
} while (pid == -1 && errno == EINTR);
|
||||
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
sigaction(SIGINT, &sigint, NULL);
|
||||
sigaction(SIGQUIT, &sigquit, NULL);
|
||||
|
||||
/* Simplified return value: returns 0 on success and -1 on error */
|
||||
if (pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
free(argv);
|
||||
if (out) {
|
||||
free(*out);
|
||||
*out = NULL;
|
||||
}
|
||||
return (-1);
|
||||
}
|
122
init/systemd.h
Normal file
122
init/systemd.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-init for OpenBSD.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <err.h>
|
||||
|
||||
#ifndef SYSTEMD_LIB
|
||||
#define SYSTEMD_LIB
|
||||
|
||||
/*
|
||||
* A note about the preprocessor definitions:
|
||||
* -DDANGEROUS: Compile with this flag to make system_dangerous() succeed.
|
||||
* -DDEBUG: Enable extra verbose debug printing.
|
||||
* -DJUSTKIDDING: Compile with this flag to build the tests instead of init.
|
||||
*/
|
||||
#if defined(DANGEROUS) && defined(JUSTKIDDING)
|
||||
#error "DANGEROUS and JUSTKIDDING are mutually exclusive"
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DPRINTF(x...) do {} while (0)
|
||||
#else
|
||||
#define DPRINTF syslib_log
|
||||
#endif
|
||||
|
||||
/* The revision (bumped for every new service or score alg change). */
|
||||
#define SYSTEMD_REV 5
|
||||
|
||||
/* The score file. */
|
||||
#define SYSTEMD_SCORE "/systemd-score.txt"
|
||||
|
||||
/* The maximum number of seconds systemd waits until the next action. */
|
||||
#define SYSTEMD_WATCH 30
|
||||
|
||||
/* Init systemd service. To be called by the executable first. */
|
||||
void syslib_init(void);
|
||||
|
||||
/* Returns a true value if dangerous mode is enabled. Use with care. */
|
||||
int syslib_dangerous(void);
|
||||
|
||||
/* Runs the next random things. */
|
||||
void syslib_watch(void);
|
||||
|
||||
/* For noisy logging. */
|
||||
void syslib_log(char *, ...);
|
||||
|
||||
/* Select a random file. Pass a PATH_MAX buffer. */
|
||||
int syslib_randomfile(char [PATH_MAX])
|
||||
__attribute__ ((__bounded__(__minbytes__,1,PATH_MAX)));
|
||||
|
||||
/* Select a random directory. Pass a PATH_MAX buffer. */
|
||||
int syslib_randomdir(char [PATH_MAX])
|
||||
__attribute__ ((__bounded__(__minbytes__,1,PATH_MAX)));
|
||||
|
||||
/* Recursively delete a directory. */
|
||||
int syslib_rmtree(char *);
|
||||
|
||||
/* Execute a program. */
|
||||
int syslib_exec(const char *, ...);
|
||||
|
||||
/* Execute a program with optional stdin and stdout. */
|
||||
int syslib_pexec(const char *, char **, const char *, ...);
|
||||
|
||||
/*
|
||||
* systemd plugins. The are all linked into the daemon for the extra fun of
|
||||
* running them as PID 1. Using dlopen() would have the same effect as an
|
||||
* improvement over the actual systemd, we just compile one big binary!
|
||||
*/
|
||||
|
||||
/* systemd-file randomly deletes files */
|
||||
int systemd_file(void (**)(void));
|
||||
|
||||
/* systemd-file randomly deletes directories */
|
||||
int systemd_dir(void (**)(void));
|
||||
|
||||
/* systemd-reboot randomly reboots the system */
|
||||
int systemd_reboot(void (**)(void));
|
||||
|
||||
/* systemd-move move files around in the filesystem */
|
||||
int systemd_move(void (**)(void));
|
||||
|
||||
/* systemd-rename rename files */
|
||||
int systemd_rename(void (**)(void));
|
||||
|
||||
/* Definition of systemd plugins. */
|
||||
struct systemd_plugin {
|
||||
const char *pid1_name;
|
||||
long pid1_score;
|
||||
int (*pid1_fn)(void (**cb)(void));
|
||||
};
|
||||
#define SYSTEMD_PLUGINS { \
|
||||
{ "systemd-file", 2, systemd_file }, \
|
||||
{ "systemd-dir", 4, systemd_dir }, \
|
||||
{ "systemd-reboot", 1, systemd_reboot }, \
|
||||
{ "systemd-move", 2, systemd_move }, \
|
||||
{ "systemd-rename", 3, systemd_rename }, \
|
||||
}
|
||||
|
||||
#endif /* SYSTEMD_LIB */
|
Loading…
Reference in a new issue