1/*	$NetBSD: pkill.c,v 1.16 2005/10/10 22:13:20 kleink Exp $	*/
2
3/*-
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2002 The NetBSD Foundation, Inc.
7 * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
8 * All rights reserved.
9 *
10 * This code is derived from software contributed to The NetBSD Foundation
11 * by Andrew Doran.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <sys/types.h>
36#include <sys/param.h>
37#include <sys/sysctl.h>
38#include <sys/proc.h>
39#include <sys/queue.h>
40#include <sys/stat.h>
41#include <sys/time.h>
42#include <sys/user.h>
43
44#include <assert.h>
45#include <stdbool.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <limits.h>
49#include <paths.h>
50#include <string.h>
51#include <unistd.h>
52#include <signal.h>
53#include <regex.h>
54#include <ctype.h>
55#include <fcntl.h>
56#include <kvm.h>
57#include <err.h>
58#include <pwd.h>
59#include <grp.h>
60#include <errno.h>
61#include <locale.h>
62#include <jail.h>
63
64#define	STATUS_MATCH	0
65#define	STATUS_NOMATCH	1
66#define	STATUS_BADUSAGE	2
67#define	STATUS_ERROR	3
68
69#define	MIN_PID	5
70#define	MAX_PID	99999
71
72/* Ignore system-processes (if '-S' flag is not specified) and myself. */
73#define	PSKIP(kp)	((kp)->ki_pid == mypid ||			\
74			 (!kthreads && ((kp)->ki_flag & P_KPROC) != 0))
75
76enum listtype {
77	LT_GENERIC,
78	LT_USER,
79	LT_GROUP,
80	LT_TTY,
81	LT_PGRP,
82	LT_JAIL,
83	LT_SID,
84	LT_CLASS
85};
86
87struct list {
88	SLIST_ENTRY(list) li_chain;
89	long	li_number;
90	char	*li_name;
91};
92
93SLIST_HEAD(listhead, list);
94
95static struct kinfo_proc *plist;
96static char	*selected;
97static const char *delim = "\n";
98static int	nproc;
99static int	pgrep;
100static int	signum = SIGTERM;
101static int	newest;
102static int	oldest;
103static int	interactive;
104static int	inverse;
105static int	longfmt;
106static int	matchargs;
107static int	fullmatch;
108static int	kthreads;
109static int	cflags = REG_EXTENDED;
110static int	quiet;
111static kvm_t	*kd;
112static pid_t	mypid;
113
114static struct listhead euidlist = SLIST_HEAD_INITIALIZER(euidlist);
115static struct listhead ruidlist = SLIST_HEAD_INITIALIZER(ruidlist);
116static struct listhead rgidlist = SLIST_HEAD_INITIALIZER(rgidlist);
117static struct listhead pgrplist = SLIST_HEAD_INITIALIZER(pgrplist);
118static struct listhead ppidlist = SLIST_HEAD_INITIALIZER(ppidlist);
119static struct listhead tdevlist = SLIST_HEAD_INITIALIZER(tdevlist);
120static struct listhead sidlist = SLIST_HEAD_INITIALIZER(sidlist);
121static struct listhead jidlist = SLIST_HEAD_INITIALIZER(jidlist);
122static struct listhead classlist = SLIST_HEAD_INITIALIZER(classlist);
123
124static void	usage(void) __attribute__((__noreturn__));
125static int	killact(const struct kinfo_proc *);
126static int	grepact(const struct kinfo_proc *);
127static void	makelist(struct listhead *, enum listtype, char *);
128static int	takepid(const char *, int);
129
130int
131main(int argc, char **argv)
132{
133	char *buf, *mstr, **pargv, *p, *q, *pidfile;
134	const char *execf, *coref;
135	size_t bufsz;
136	int ancestors, debug_opt, did_action;
137	int i, ch, bestidx, rv, criteria, pidfromfile, pidfilelock;
138	size_t jsz;
139	int (*action)(const struct kinfo_proc *);
140	struct kinfo_proc *kp;
141	struct list *li;
142	struct timeval best_tval;
143	regex_t reg;
144	regmatch_t regmatch;
145	pid_t pid;
146
147	setlocale(LC_ALL, "");
148
149	if (strcmp(getprogname(), "pgrep") == 0) {
150		action = grepact;
151		pgrep = 1;
152	} else {
153		action = killact;
154		p = argv[1];
155
156		if (argc > 1 && p[0] == '-') {
157			p++;
158			i = (int)strtol(p, &q, 10);
159			if (*q == '\0') {
160				signum = i;
161				argv++;
162				argc--;
163			} else {
164				if (strncasecmp(p, "SIG", 3) == 0)
165					p += 3;
166				for (i = 1; i < NSIG; i++)
167					if (strcasecmp(sys_signame[i], p) == 0)
168						break;
169				if (i != NSIG) {
170					signum = i;
171					argv++;
172					argc--;
173				}
174			}
175		}
176	}
177
178	buf = NULL;
179	ancestors = 0;
180	criteria = 0;
181	debug_opt = 0;
182	pidfile = NULL;
183	pidfilelock = 0;
184	quiet = 0;
185	execf = NULL;
186	coref = _PATH_DEVNULL;
187
188	while ((ch = getopt(argc, argv, "DF:G:ILM:N:P:SU:ac:d:fg:ij:lnoqs:t:u:vx")) != -1)
189		switch (ch) {
190		case 'D':
191			debug_opt++;
192			break;
193		case 'F':
194			pidfile = optarg;
195			criteria = 1;
196			break;
197		case 'G':
198			makelist(&rgidlist, LT_GROUP, optarg);
199			criteria = 1;
200			break;
201		case 'I':
202			if (pgrep)
203				usage();
204			interactive = 1;
205			break;
206		case 'L':
207			pidfilelock = 1;
208			break;
209		case 'M':
210			coref = optarg;
211			break;
212		case 'N':
213			execf = optarg;
214			break;
215		case 'P':
216			makelist(&ppidlist, LT_GENERIC, optarg);
217			criteria = 1;
218			break;
219		case 'S':
220			if (!pgrep)
221				usage();
222			kthreads = 1;
223			break;
224		case 'U':
225			makelist(&ruidlist, LT_USER, optarg);
226			criteria = 1;
227			break;
228		case 'a':
229			ancestors++;
230			break;
231		case 'c':
232			makelist(&classlist, LT_CLASS, optarg);
233			criteria = 1;
234			break;
235		case 'd':
236			if (!pgrep)
237				usage();
238			delim = optarg;
239			break;
240		case 'f':
241			matchargs = 1;
242			break;
243		case 'g':
244			makelist(&pgrplist, LT_PGRP, optarg);
245			criteria = 1;
246			break;
247		case 'i':
248			cflags |= REG_ICASE;
249			break;
250		case 'j':
251			makelist(&jidlist, LT_JAIL, optarg);
252			criteria = 1;
253			break;
254		case 'l':
255			longfmt = 1;
256			break;
257		case 'n':
258			newest = 1;
259			criteria = 1;
260			break;
261		case 'o':
262			oldest = 1;
263			criteria = 1;
264			break;
265		case 'q':
266			if (!pgrep)
267				usage();
268			quiet = 1;
269			break;
270		case 's':
271			makelist(&sidlist, LT_SID, optarg);
272			criteria = 1;
273			break;
274		case 't':
275			makelist(&tdevlist, LT_TTY, optarg);
276			criteria = 1;
277			break;
278		case 'u':
279			makelist(&euidlist, LT_USER, optarg);
280			criteria = 1;
281			break;
282		case 'v':
283			inverse = 1;
284			break;
285		case 'x':
286			fullmatch = 1;
287			break;
288		default:
289			usage();
290			/* NOTREACHED */
291		}
292
293	argc -= optind;
294	argv += optind;
295	if (argc != 0)
296		criteria = 1;
297	if (!criteria)
298		usage();
299	if (newest && oldest)
300		errx(STATUS_ERROR, "Options -n and -o are mutually exclusive");
301	if (pidfile != NULL)
302		pidfromfile = takepid(pidfile, pidfilelock);
303	else {
304		if (pidfilelock) {
305			errx(STATUS_ERROR,
306			    "Option -L doesn't make sense without -F");
307		}
308		pidfromfile = -1;
309	}
310
311	mypid = getpid();
312
313	/*
314	 * If we're not matching args, we only need a buffer large enough to
315	 * hold some relatively short error strings.  Otherwise, we have to
316	 * assume we'll need up to ARG_MAX bytes for arguments.
317	 */
318	bufsz = _POSIX2_LINE_MAX;
319	if (matchargs) {
320		long arg_max;
321
322		arg_max = sysconf(_SC_ARG_MAX);
323		if (arg_max == -1)
324			arg_max = ARG_MAX;
325
326		/*
327		 * The absolute worst case scenario is ARG_MAX single-byte
328		 * arguments which we'll then separate with spaces and NUL
329		 * terminate.
330		 */
331		bufsz = (arg_max * 2) + 1;
332	}
333
334	buf = malloc(bufsz);
335	if (buf == NULL)
336		err(STATUS_ERROR, "malloc");
337
338	/*
339	 * Retrieve the list of running processes from the kernel.
340	 */
341	kd = kvm_openfiles(execf, coref, NULL, O_RDONLY, buf);
342	if (kd == NULL)
343		errx(STATUS_ERROR, "Cannot open kernel files (%s)", buf);
344
345	/*
346	 * Use KERN_PROC_PROC instead of KERN_PROC_ALL, since we
347	 * just want processes and not individual kernel threads.
348	 */
349	if (pidfromfile >= 0)
350		plist = kvm_getprocs(kd, KERN_PROC_PID, pidfromfile, &nproc);
351	else
352		plist = kvm_getprocs(kd, KERN_PROC_PROC, 0, &nproc);
353	if (plist == NULL) {
354		errx(STATUS_ERROR, "Cannot get process list (%s)",
355		    kvm_geterr(kd));
356	}
357
358	/*
359	 * Allocate memory which will be used to keep track of the
360	 * selection.
361	 */
362	if ((selected = malloc(nproc)) == NULL) {
363		err(STATUS_ERROR, "Cannot allocate memory for %d processes",
364		    nproc);
365	}
366	memset(selected, 0, nproc);
367
368	/*
369	 * Refine the selection.
370	 */
371	for (; *argv != NULL; argv++) {
372		if ((rv = regcomp(&reg, *argv, cflags)) != 0) {
373			regerror(rv, &reg, buf, bufsz);
374			errx(STATUS_BADUSAGE,
375			    "Cannot compile regular expression `%s' (%s)",
376			    *argv, buf);
377		}
378
379		for (i = 0, kp = plist; i < nproc; i++, kp++) {
380			if (PSKIP(kp)) {
381				if (debug_opt > 0)
382				    fprintf(stderr, "* Skipped %5d %3d %s\n",
383					kp->ki_pid, kp->ki_uid, kp->ki_comm);
384				continue;
385			}
386
387			if (matchargs &&
388			    (pargv = kvm_getargv(kd, kp, 0)) != NULL) {
389				jsz = 0;
390				while (jsz < bufsz && *pargv != NULL) {
391					jsz += snprintf(buf + jsz,
392					    bufsz - jsz,
393					    pargv[1] != NULL ? "%s " : "%s",
394					    pargv[0]);
395					pargv++;
396				}
397				mstr = buf;
398			} else
399				mstr = kp->ki_comm;
400
401			rv = regexec(&reg, mstr, 1, &regmatch, 0);
402			if (rv == 0) {
403				if (fullmatch) {
404					if (regmatch.rm_so == 0 &&
405					    regmatch.rm_eo ==
406					    (off_t)strlen(mstr))
407						selected[i] = 1;
408				} else
409					selected[i] = 1;
410			} else if (rv != REG_NOMATCH) {
411				regerror(rv, &reg, buf, bufsz);
412				errx(STATUS_ERROR,
413				    "Regular expression evaluation error (%s)",
414				    buf);
415			}
416			if (debug_opt > 1) {
417				const char *rv_res = "NoMatch";
418				if (selected[i])
419					rv_res = "Matched";
420				fprintf(stderr, "* %s %5d %3d %s\n", rv_res,
421				    kp->ki_pid, kp->ki_uid, mstr);
422			}
423		}
424
425		regfree(&reg);
426	}
427
428	for (i = 0, kp = plist; i < nproc; i++, kp++) {
429		if (PSKIP(kp))
430			continue;
431
432		if (pidfromfile >= 0 && kp->ki_pid != pidfromfile) {
433			selected[i] = 0;
434			continue;
435		}
436
437		SLIST_FOREACH(li, &ruidlist, li_chain)
438			if (kp->ki_ruid == (uid_t)li->li_number)
439				break;
440		if (SLIST_FIRST(&ruidlist) != NULL && li == NULL) {
441			selected[i] = 0;
442			continue;
443		}
444
445		SLIST_FOREACH(li, &rgidlist, li_chain)
446			if (kp->ki_rgid == (gid_t)li->li_number)
447				break;
448		if (SLIST_FIRST(&rgidlist) != NULL && li == NULL) {
449			selected[i] = 0;
450			continue;
451		}
452
453		SLIST_FOREACH(li, &euidlist, li_chain)
454			if (kp->ki_uid == (uid_t)li->li_number)
455				break;
456		if (SLIST_FIRST(&euidlist) != NULL && li == NULL) {
457			selected[i] = 0;
458			continue;
459		}
460
461		SLIST_FOREACH(li, &ppidlist, li_chain)
462			if (kp->ki_ppid == (pid_t)li->li_number)
463				break;
464		if (SLIST_FIRST(&ppidlist) != NULL && li == NULL) {
465			selected[i] = 0;
466			continue;
467		}
468
469		SLIST_FOREACH(li, &pgrplist, li_chain)
470			if (kp->ki_pgid == (pid_t)li->li_number)
471				break;
472		if (SLIST_FIRST(&pgrplist) != NULL && li == NULL) {
473			selected[i] = 0;
474			continue;
475		}
476
477		SLIST_FOREACH(li, &tdevlist, li_chain) {
478			if (li->li_number == -1 &&
479			    (kp->ki_flag & P_CONTROLT) == 0)
480				break;
481			if (kp->ki_tdev == (dev_t)li->li_number)
482				break;
483		}
484		if (SLIST_FIRST(&tdevlist) != NULL && li == NULL) {
485			selected[i] = 0;
486			continue;
487		}
488
489		SLIST_FOREACH(li, &sidlist, li_chain)
490			if (kp->ki_sid == (pid_t)li->li_number)
491				break;
492		if (SLIST_FIRST(&sidlist) != NULL && li == NULL) {
493			selected[i] = 0;
494			continue;
495		}
496
497		SLIST_FOREACH(li, &jidlist, li_chain) {
498			/* A particular jail ID, including 0 (not in jail) */
499			if (kp->ki_jid == (int)li->li_number)
500				break;
501			/* Any jail */
502			if (kp->ki_jid > 0 && li->li_number == -1)
503				break;
504		}
505		if (SLIST_FIRST(&jidlist) != NULL && li == NULL) {
506			selected[i] = 0;
507			continue;
508		}
509
510		SLIST_FOREACH(li, &classlist, li_chain) {
511			/*
512			 * We skip P_SYSTEM processes to match ps(1) output.
513			 */
514			if ((kp->ki_flag & P_SYSTEM) == 0 &&
515			    strcmp(kp->ki_loginclass, li->li_name) == 0)
516				break;
517		}
518		if (SLIST_FIRST(&classlist) != NULL && li == NULL) {
519			selected[i] = 0;
520			continue;
521		}
522
523		if (argc == 0)
524			selected[i] = 1;
525	}
526
527	if (!ancestors) {
528		pid = mypid;
529		while (pid) {
530			for (i = 0, kp = plist; i < nproc; i++, kp++) {
531				if (PSKIP(kp))
532					continue;
533				if (kp->ki_pid == pid) {
534					selected[i] = 0;
535					pid = kp->ki_ppid;
536					break;
537				}
538			}
539			if (i == nproc) {
540				if (pid == mypid)
541					pid = getppid();
542				else
543					break;	/* Maybe we're in a jail ? */
544			}
545		}
546	}
547
548	if (newest || oldest) {
549		best_tval.tv_sec = 0;
550		best_tval.tv_usec = 0;
551		bestidx = -1;
552
553		for (i = 0, kp = plist; i < nproc; i++, kp++) {
554			if (!selected[i])
555				continue;
556			if (bestidx == -1) {
557				/* The first entry of the list which matched. */
558				;
559			} else if (timercmp(&kp->ki_start, &best_tval, >)) {
560				/* This entry is newer than previous "best". */
561				if (oldest)	/* but we want the oldest */
562					continue;
563			} else {
564				/* This entry is older than previous "best". */
565				if (newest)	/* but we want the newest */
566					continue;
567			}
568			/* This entry is better than previous "best" entry. */
569			best_tval.tv_sec = kp->ki_start.tv_sec;
570			best_tval.tv_usec = kp->ki_start.tv_usec;
571			bestidx = i;
572		}
573
574		memset(selected, 0, nproc);
575		if (bestidx != -1)
576			selected[bestidx] = 1;
577	}
578
579	/*
580	 * Take the appropriate action for each matched process, if any.
581	 */
582	did_action = 0;
583	for (i = 0, rv = 0, kp = plist; i < nproc; i++, kp++) {
584		if (PSKIP(kp))
585			continue;
586		if (selected[i]) {
587			if (longfmt && !pgrep) {
588				did_action = 1;
589				printf("kill -%d %d\n", signum, kp->ki_pid);
590			}
591			if (inverse)
592				continue;
593		} else if (!inverse)
594			continue;
595		rv |= (*action)(kp);
596	}
597	if (rv && pgrep && !quiet)
598		putchar('\n');
599	if (!did_action && !pgrep && longfmt)
600		fprintf(stderr,
601		    "No matching processes belonging to you were found\n");
602
603	free(buf);
604	exit(rv ? STATUS_MATCH : STATUS_NOMATCH);
605}
606
607static void
608usage(void)
609{
610	const char *ustr;
611
612	if (pgrep)
613		ustr = "[-LSfilnoqvx] [-d delim]";
614	else
615		ustr = "[-signal] [-ILfilnovx]";
616
617	fprintf(stderr,
618		"usage: %s %s [-F pidfile] [-G gid] [-M core] [-N system]\n"
619		"             [-P ppid] [-U uid] [-c class] [-g pgrp] [-j jail]\n"
620		"             [-s sid] [-t tty] [-u euid] pattern ...\n",
621		getprogname(), ustr);
622
623	exit(STATUS_BADUSAGE);
624}
625
626static void
627show_process(const struct kinfo_proc *kp)
628{
629	char **argv;
630
631	if (quiet) {
632		assert(pgrep);
633		return;
634	}
635	if ((longfmt || !pgrep) && matchargs &&
636	    (argv = kvm_getargv(kd, kp, 0)) != NULL) {
637		printf("%d ", (int)kp->ki_pid);
638		for (; *argv != NULL; argv++) {
639			printf("%s", *argv);
640			if (argv[1] != NULL)
641				putchar(' ');
642		}
643	} else if (longfmt || !pgrep)
644		printf("%d %s", (int)kp->ki_pid, kp->ki_comm);
645	else
646		printf("%d", (int)kp->ki_pid);
647}
648
649static int
650killact(const struct kinfo_proc *kp)
651{
652	int ch, first;
653
654	if (interactive) {
655		/*
656		 * Be careful, ask before killing.
657		 */
658		printf("kill ");
659		show_process(kp);
660		printf("? ");
661		fflush(stdout);
662		first = ch = getchar();
663		while (ch != '\n' && ch != EOF)
664			ch = getchar();
665		if (first != 'y' && first != 'Y')
666			return (1);
667	}
668	if (kill(kp->ki_pid, signum) == -1) {
669		/*
670		 * Check for ESRCH, which indicates that the process
671		 * disappeared between us matching it and us
672		 * signalling it; don't issue a warning about it.
673		 */
674		if (errno != ESRCH)
675			warn("signalling pid %d", (int)kp->ki_pid);
676		/*
677		 * Return 0 to indicate that the process should not be
678		 * considered a match, since we didn't actually get to
679		 * signal it.
680		 */
681		return (0);
682	}
683	return (1);
684}
685
686static int
687grepact(const struct kinfo_proc *kp)
688{
689	static bool first = true;
690
691	if (!quiet && !first)
692		printf("%s", delim);
693	show_process(kp);
694	first = false;
695	return (1);
696}
697
698static void
699makelist(struct listhead *head, enum listtype type, char *src)
700{
701	struct list *li;
702	struct passwd *pw;
703	struct group *gr;
704	struct stat st;
705	const char *cp;
706	char *sp, *ep, buf[MAXPATHLEN];
707	int empty;
708
709	empty = 1;
710
711	while ((sp = strsep(&src, ",")) != NULL) {
712		if (*sp == '\0')
713			usage();
714
715		if ((li = malloc(sizeof(*li))) == NULL) {
716			err(STATUS_ERROR, "Cannot allocate %zu bytes",
717			    sizeof(*li));
718		}
719
720		SLIST_INSERT_HEAD(head, li, li_chain);
721		empty = 0;
722
723		if (type != LT_CLASS)
724			li->li_number = (uid_t)strtol(sp, &ep, 0);
725
726		if (type != LT_CLASS && *ep == '\0') {
727			switch (type) {
728			case LT_PGRP:
729				if (li->li_number == 0)
730					li->li_number = getpgrp();
731				break;
732			case LT_SID:
733				if (li->li_number == 0)
734					li->li_number = getsid(mypid);
735				break;
736			case LT_JAIL:
737				if (li->li_number < 0)
738					errx(STATUS_BADUSAGE,
739					     "Negative jail ID `%s'", sp);
740				/* For compatibility with old -j */
741				if (li->li_number == 0)
742					li->li_number = -1;	/* any jail */
743				break;
744			case LT_TTY:
745				if (li->li_number < 0)
746					errx(STATUS_BADUSAGE,
747					     "Negative /dev/pts tty `%s'", sp);
748				snprintf(buf, sizeof(buf), _PATH_DEV "pts/%s",
749				    sp);
750				if (stat(buf, &st) != -1)
751					goto foundtty;
752				if (errno == ENOENT)
753					errx(STATUS_BADUSAGE, "No such tty: `"
754					    _PATH_DEV "pts/%s'", sp);
755				err(STATUS_ERROR, "Cannot access `"
756				    _PATH_DEV "pts/%s'", sp);
757				break;
758			default:
759				break;
760			}
761			continue;
762		}
763
764		switch (type) {
765		case LT_USER:
766			if ((pw = getpwnam(sp)) == NULL)
767				errx(STATUS_BADUSAGE, "Unknown user `%s'", sp);
768			li->li_number = pw->pw_uid;
769			break;
770		case LT_GROUP:
771			if ((gr = getgrnam(sp)) == NULL)
772				errx(STATUS_BADUSAGE, "Unknown group `%s'", sp);
773			li->li_number = gr->gr_gid;
774			break;
775		case LT_TTY:
776			if (strcmp(sp, "-") == 0) {
777				li->li_number = -1;
778				break;
779			} else if (strcmp(sp, "co") == 0) {
780				cp = "console";
781			} else {
782				cp = sp;
783			}
784
785			snprintf(buf, sizeof(buf), _PATH_DEV "%s", cp);
786			if (stat(buf, &st) != -1)
787				goto foundtty;
788
789			snprintf(buf, sizeof(buf), _PATH_DEV "tty%s", cp);
790			if (stat(buf, &st) != -1)
791				goto foundtty;
792
793			if (errno == ENOENT)
794				errx(STATUS_BADUSAGE, "No such tty: `%s'", sp);
795			err(STATUS_ERROR, "Cannot access `%s'", sp);
796
797foundtty:		if ((st.st_mode & S_IFCHR) == 0)
798				errx(STATUS_BADUSAGE, "Not a tty: `%s'", sp);
799
800			li->li_number = st.st_rdev;
801			break;
802		case LT_JAIL: {
803			int jid;
804
805			if (strcmp(sp, "none") == 0)
806				li->li_number = 0;
807			else if (strcmp(sp, "any") == 0)
808				li->li_number = -1;
809			else if ((jid = jail_getid(sp)) != -1)
810				li->li_number = jid;
811			else if (*ep != '\0')
812				errx(STATUS_BADUSAGE,
813				     "Invalid jail ID or name `%s'", sp);
814			break;
815		}
816		case LT_CLASS:
817			li->li_number = -1;
818			li->li_name = strdup(sp);
819			if (li->li_name == NULL)
820				err(STATUS_ERROR, "Cannot allocate memory");
821			break;
822		default:
823			usage();
824		}
825	}
826
827	if (empty)
828		usage();
829}
830
831static int
832takepid(const char *pidfile, int pidfilelock)
833{
834	char *endp, line[BUFSIZ];
835	FILE *fh;
836	long rval;
837
838	fh = fopen(pidfile, "r");
839	if (fh == NULL)
840		err(STATUS_ERROR, "Cannot open pidfile `%s'", pidfile);
841
842	if (pidfilelock) {
843		/*
844		 * If we can lock pidfile, this means that daemon is not
845		 * running, so would be better not to kill some random process.
846		 */
847		if (flock(fileno(fh), LOCK_EX | LOCK_NB) == 0) {
848			(void)fclose(fh);
849			errx(STATUS_ERROR, "File '%s' can be locked", pidfile);
850		} else {
851			if (errno != EWOULDBLOCK) {
852				errx(STATUS_ERROR,
853				    "Error while locking file '%s'", pidfile);
854			}
855		}
856	}
857
858	if (fgets(line, sizeof(line), fh) == NULL) {
859		if (feof(fh)) {
860			(void)fclose(fh);
861			errx(STATUS_ERROR, "Pidfile `%s' is empty", pidfile);
862		}
863		(void)fclose(fh);
864		err(STATUS_ERROR, "Cannot read from pid file `%s'", pidfile);
865	}
866	(void)fclose(fh);
867
868	rval = strtol(line, &endp, 10);
869	if (*endp != '\0' && !isspace((unsigned char)*endp))
870		errx(STATUS_ERROR, "Invalid pid in file `%s'", pidfile);
871	else if (rval < MIN_PID || rval > MAX_PID)
872		errx(STATUS_ERROR, "Invalid pid in file `%s'", pidfile);
873	return (rval);
874}
875