[net.sources] Zonk - send a signal to all of a user's processes

kwlalonde@watmath.UUCP (Ken Lalonde) (09/05/85)

Zonk is particularly useful in stamping out runaway processes.
Here is the source for the system call and user program, and man pages.
We added the system code to the end of sys/kern_exit.c; you'll
have to modify other files to support the new call (sys/init_sysent.c,
sys/syscalls.c under 4.2).  We use system call #154.

: This is a shar archive.	Extract with sh, not csh.
: The rest of this file will extract:
: sys_zonk.c zonk.1 zonk.2 zonk.c
echo Extracting sys_zonk.c
sed 's/^X//' > sys_zonk.c << 'e-o-f'
X/*
X *  Zonk system call - apply a signal to every process owned by a user.
X *  Typically used as zonk(uid,SIGKILL) to kill student runaway jobs.
X *  A count of the affected processes is returned.
X *  If passed signal zero, no signal is sent; only the count is returned.
X */
X
Xzonk()
X{
X	struct a {
X		int	uid;
X		int	sig;
X	} *uap = (struct a *)u.u_ap;
X	register int sig = uap->sig;
X	register int count, uid = uap->uid;
X	register struct proc *p;
X
X	if (uid != u.u_uid && !suser())
X		return;
X	if (uid == 0 && sig || (unsigned)sig >= NSIG) {
X		u.u_error = EINVAL;
X		return;
X	}
X	for (count = 0, p = proc; p < procNPROC; p++)
X		if (p->p_uid == uid) {
X			count++;
X			if (sig)
X				psignal(p, sig);
X		}
X	u.u_r.r_val1 = count;
X}
e-o-f
echo Extracting zonk.1
sed 's/^X//' > zonk.1 << 'e-o-f'
X.TH ZONK 1 "U of W"
X.SH NAME
Xzonk \- Kill all processes owned by a user fast
X.SH SYNOPSIS
X.nf
X.B
Xzonk [ \-sig ] name
X.B
Xzonk [ \-sig ] \-u uid
X.fi
X.SH DESCRIPTION
X.I Zonk
Xsends a signal to all processes owned by
Xuser \fIname\fP.
XThe signal sent is SIGKILL (kill utterly); this can be changed by
Xsupplying the desired signal in the style of
X.IR kill (1).
XIn the second form, the signal is sent
Xto all processes with the given effective \fIuid\fP.
XIf no arguments are given, the invoking user is zonked.
X.PP
XThe purpose of this process is to help confused operating system students
Xwho leave all kinds of processes running get rid quickly of ALL processes
Xwhich they have anything to do with; and to do this while the system
Xis incredibly slow.
XAlso to help consultants get rid of confused users who are clogging up
Xthe system.
X.SH "SEE ALSO"
Xkill(1), zonk(2).
X.SH BUGS
XThis gets rid of everything.  Perhaps it should only do it for things
Xon a given terminal, or not the controlling shell.
e-o-f
echo Extracting zonk.2
sed 's/^X//' > zonk.2 << 'e-o-f'
X.TH ZONK 2 "UW"
X.SH NAME
Xzonk \- send a signal to all processes owned by a user
X.SH SYNOPSIS
X.SB
X.SF int zonk uid signal
Xint uid, signal;
X.SE
X.SH DESCRIPTION
X.I Zonk
Xsends the signal
X.I signal
Xto all processes in the system with effective uid equal to
X.IR uid .
XThis call is very indiscriminatory; it even sends the signal to itself.
X.PP
XThe
X.I uid
Xmust be the effective uid of the invoking process,
Xor the invoking process must have an effective uid of the Super User.
X.I Zonk
Xexplicitly checks for a
X.I uid
Xof zero and disallows such a call.
X.SH "RETURN VALUE
XUpon successful completion, a count of the number of affected
Xprocesses is returned.
XOtherwise, a value of \-1 is returned and
X.I errno
Xis set to indicate the error.
X.PP
XA signal number of zero may be used to count processes in the system
Xowned by the given
X.I uid
Xwithout sending them any signal.
X.SH "ERRORS
X.I Zonk
Xwill fail and no signal will be sent if any of the following
Xoccur:
X.TP 15
X[EPERM]
XThe sending process is not the super-user and its effective
Xuser id is not the same as \fIuid\fP.
X.TP 15
X[EINVAL]
X.I Uid
Xis equal to zero, or
X.I signal
Xis not between 0 and 31 inclusive.
X.SH "SEE ALSO"
Xkill(2), signal(2), zonk(1).
X.SH BUGS
XThis should artificially increase the priority of all killed processes,
Xjust in case the system is terribly clogged and needs proc slots
Xbut there is so much happening that it doesn't get around to them for a while.
X.PP
XThis is a Waterloo-specific system call designed originally to send
XSIGKILL to processes so that a student could be sure to kill off all
Xrunaway processes.
XThat problem should be addressed more directly.
e-o-f
echo Extracting zonk.c
sed 's/^X//' > zonk.c << 'e-o-f'
X/*
X *  Zonk - send a signal to all of a user's processes.
X */
X
X#include <sys/types.h>
X#include <sys/signal.h>
X#include <stdio.h>
X#include <pwd.h>
X
Xmain(argc, argv)
X	char **argv;
X{
X	int uid = -1;
X	int sig = -1;
X	int i, zot;
X	struct passwd *pw;
X
X	for (i = 1; i < argc; i++) {
X		if (argv[i][0] == '-') switch (argv[i][1]) {
X
X		case 'u':	/* -u uid */
X			if (uid >= 0 || ++i == argc) {
X			usage:
X				fprintf(stderr, "Usage: zonk [-SIGNAL] [name|-u uid]\n"),
X				exit(1);
X			}
X			uid = atoi(argv[i]);
X			continue;
X
X		default:	/* signal of the form -SIGNAL or -n */
X			if (sig >= 0)
X				goto usage;
X			sig = getsig(&argv[i][1]);
X			if ((unsigned)sig >= NSIG)
X				goto usage;
X			continue;
X		}
X		/* login name */
X		if (uid >= 0)
X			goto usage;
X		pw = getpwnam(argv[i]);
X		if (pw == NULL) {
X			fprintf(stderr, "zonk: No such person: %s\n", argv[i]);
X			exit(1);
X		}
X		uid = pw->pw_uid;
X	}
X	if (uid < 0)
X		uid = getuid();
X	if (sig < 0)
X		sig = SIGKILL;
X	
X	/*
X	 * If uid looks like a system process, ask user to verify.
X	 */
X	if (uid <= 15) {
X		printf("uid = %d (%s) -- sure you want to zonk? [ny] ",
X			uid, (pw = getpwuid(uid)) == 0? "?": pw->pw_name);
X		if ((getchar()|' ') != ('y'|' '))
X			exit(1);
X	}
X	
X	/* printf("zonk(%d, %d)\n", uid,sig);exit();*/
X
X	if ((zot=zonk(uid,sig)) < 0)
X		perror("zonk");
X	else
X		printf("Zonked processes for uid %d = %d\n", uid, zot );
X	exit(zot <= 0);
X}
X
Xchar *sigs[] = { 0,
X"HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", "EMT", "FPE",	/* 1-8 */
X"KILL", "BUS", "SEGV", "SYS", "PIPE", "ALRM", "TERM", 0,	/* 9-16 */
X"STOP", "TSTP", "CONT", "CHLD", "TTIN", "TTOU", "TINT", "XCPU",	/* 17-24 */
X"XFSZ", 0, 0, 0, 0, 0, 0, 0,					/* 25-31 */
X};
X	int
Xgetsig(name)
X	char *name;
X{
X	int i;
X
X	if (*name >= '0' && *name <= '9')
X		return atoi(name);
X	for (i = 1; i < NSIG; i++)
X		if (sigs[i] && strcmp(sigs[i], name) == 0)
X			return i;
X	return -1;
X}
e-o-f
exit 0

	Ken Lalonde	ihnp4!watmath!kwlalonde
	U of Waterloo