]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - bin/pkill/pkill.c
libarchive: merge from vendor branch
[FreeBSD/FreeBSD.git] / bin / pkill / pkill.c
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/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 }