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