1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/task.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/contract.h> 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <signal.h> 36*7c478bd9Sstevel@tonic-gate #include <unistd.h> 37*7c478bd9Sstevel@tonic-gate #include <dirent.h> 38*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 39*7c478bd9Sstevel@tonic-gate #include <string.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include <libintl.h> 42*7c478bd9Sstevel@tonic-gate #include <locale.h> 43*7c478bd9Sstevel@tonic-gate #include <stdio.h> 44*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 45*7c478bd9Sstevel@tonic-gate #include <ctype.h> 46*7c478bd9Sstevel@tonic-gate #include <wchar.h> 47*7c478bd9Sstevel@tonic-gate #include <limits.h> 48*7c478bd9Sstevel@tonic-gate #include <libuutil.h> 49*7c478bd9Sstevel@tonic-gate #include <libcontract_priv.h> 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #include <procfs.h> 52*7c478bd9Sstevel@tonic-gate #include <project.h> 53*7c478bd9Sstevel@tonic-gate #include <pwd.h> 54*7c478bd9Sstevel@tonic-gate #include <grp.h> 55*7c478bd9Sstevel@tonic-gate #include <zone.h> 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #include "psexp.h" 58*7c478bd9Sstevel@tonic-gate #include "pgrep.h" 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN 61*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 62*7c478bd9Sstevel@tonic-gate #endif 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate #define OPT_SETB 0x0001 /* Set the bits specified by o_bits */ 65*7c478bd9Sstevel@tonic-gate #define OPT_CLRB 0x0002 /* Clear the bits specified by o_bits */ 66*7c478bd9Sstevel@tonic-gate #define OPT_FUNC 0x0004 /* Call the function specified by o_func */ 67*7c478bd9Sstevel@tonic-gate #define OPT_STR 0x0008 /* Set the string specified by o_ptr */ 68*7c478bd9Sstevel@tonic-gate #define OPT_CRIT 0x0010 /* Option is part of selection criteria */ 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate #define F_LONG_FMT 0x0001 /* Match against long format cmd */ 71*7c478bd9Sstevel@tonic-gate #define F_NEWEST 0x0002 /* Match only newest pid */ 72*7c478bd9Sstevel@tonic-gate #define F_REVERSE 0x0004 /* Reverse matching criteria */ 73*7c478bd9Sstevel@tonic-gate #define F_EXACT_MATCH 0x0008 /* Require exact match */ 74*7c478bd9Sstevel@tonic-gate #define F_HAVE_CRIT 0x0010 /* Criteria specified */ 75*7c478bd9Sstevel@tonic-gate #define F_OUTPUT 0x0020 /* Some output has been printed */ 76*7c478bd9Sstevel@tonic-gate #define F_KILL 0x0040 /* Pkill semantics active (vs pgrep) */ 77*7c478bd9Sstevel@tonic-gate #define F_LONG_OUT 0x0080 /* Long output format (pgrep -l) */ 78*7c478bd9Sstevel@tonic-gate #define F_OLDEST 0x0100 /* Match only oldest pid */ 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate static int opt_euid(char, char *); 81*7c478bd9Sstevel@tonic-gate static int opt_uid(char, char *); 82*7c478bd9Sstevel@tonic-gate static int opt_gid(char, char *); 83*7c478bd9Sstevel@tonic-gate static int opt_ppid(char, char *); 84*7c478bd9Sstevel@tonic-gate static int opt_pgrp(char, char *); 85*7c478bd9Sstevel@tonic-gate static int opt_sid(char, char *); 86*7c478bd9Sstevel@tonic-gate static int opt_term(char, char *); 87*7c478bd9Sstevel@tonic-gate static int opt_projid(char, char *); 88*7c478bd9Sstevel@tonic-gate static int opt_taskid(char, char *); 89*7c478bd9Sstevel@tonic-gate static int opt_zoneid(char, char *); 90*7c478bd9Sstevel@tonic-gate static int opt_ctid(char, char *); 91*7c478bd9Sstevel@tonic-gate static int opt_V(char, char *); 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate static const char *g_procdir = "/proc"; /* Default procfs mount point */ 94*7c478bd9Sstevel@tonic-gate static const char *g_delim = "\n"; /* Default output delimiter */ 95*7c478bd9Sstevel@tonic-gate static const char *g_pname; /* Program name for error messages */ 96*7c478bd9Sstevel@tonic-gate static ushort_t g_flags; /* Miscellaneous flags */ 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate static optdesc_t g_optdtab[] = { 99*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'A' */ 100*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'B' */ 101*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'C' */ 102*7c478bd9Sstevel@tonic-gate { OPT_STR, 0, 0, &g_procdir }, /* -D procfsdir */ 103*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'E' */ 104*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'F' */ 105*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_gid, 0 }, /* -G gid */ 106*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'H' */ 107*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'I' */ 108*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_projid, 0 }, /* -J projid */ 109*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'K' */ 110*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'L' */ 111*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'M' */ 112*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'N' */ 113*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'O' */ 114*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_ppid, 0 }, /* -P ppid */ 115*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'Q' */ 116*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'R' */ 117*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'S' */ 118*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_taskid, 0 }, /* -T taskid */ 119*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_uid, 0 }, /* -U uid */ 120*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_V, 0 }, /* -V */ 121*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'W' */ 122*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'X' */ 123*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'Y' */ 124*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'Z' */ 125*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '[' */ 126*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '\\' */ 127*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* ']' */ 128*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '^' */ 129*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '_' */ 130*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '`' */ 131*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'a' */ 132*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'b' */ 133*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_ctid, 0 }, /* -c ctid */ 134*7c478bd9Sstevel@tonic-gate { OPT_STR, 0, 0, &g_delim }, /* -d delim */ 135*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'e' */ 136*7c478bd9Sstevel@tonic-gate { OPT_SETB, F_LONG_FMT, 0, &g_flags }, /* -f */ 137*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_pgrp, 0 }, /* -g pgrp */ 138*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'h' */ 139*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'i' */ 140*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'j' */ 141*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'k' */ 142*7c478bd9Sstevel@tonic-gate { OPT_SETB, F_LONG_OUT, 0, &g_flags }, /* 'l' */ 143*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'm' */ 144*7c478bd9Sstevel@tonic-gate { OPT_SETB, F_NEWEST, 0, &g_flags }, /* -n */ 145*7c478bd9Sstevel@tonic-gate { OPT_SETB, F_OLDEST, 0, &g_flags }, /* -o */ 146*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'p' */ 147*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'q' */ 148*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'r' */ 149*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_sid, 0 }, /* -s sid */ 150*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_term, 0 }, /* -t term */ 151*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_euid, 0 }, /* -u euid */ 152*7c478bd9Sstevel@tonic-gate { OPT_SETB, F_REVERSE, 0, &g_flags }, /* -v */ 153*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'w' */ 154*7c478bd9Sstevel@tonic-gate { OPT_SETB, F_EXACT_MATCH, 0, &g_flags }, /* -x */ 155*7c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'y' */ 156*7c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_zoneid, 0 } /* -z zoneid */ 157*7c478bd9Sstevel@tonic-gate }; 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate static const char PGREP_USAGE[] = "\ 160*7c478bd9Sstevel@tonic-gate Usage: %s [-flnovx] [-d delim] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\ 161*7c478bd9Sstevel@tonic-gate [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\ 162*7c478bd9Sstevel@tonic-gate [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n"; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate static const char PKILL_USAGE[] = "\ 165*7c478bd9Sstevel@tonic-gate Usage: %s [-signal] [-fnovx] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\ 166*7c478bd9Sstevel@tonic-gate [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\ 167*7c478bd9Sstevel@tonic-gate [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n"; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate static const char PGREP_OPTS[] = "flnovVxc:d:D:u:U:G:P:g:s:t:z:J:T:"; 170*7c478bd9Sstevel@tonic-gate static const char PKILL_OPTS[] = "fnovVxc:D:u:U:G:P:g:s:t:z:J:T:"; 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate static const char LSEP[] = ",\t "; /* Argument list delimiter chars */ 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate static psexp_t g_psexp; /* Process matching expression */ 175*7c478bd9Sstevel@tonic-gate static pid_t g_pid; /* Current pid */ 176*7c478bd9Sstevel@tonic-gate static int g_signal = SIGTERM; /* Signal to send */ 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate static void 179*7c478bd9Sstevel@tonic-gate print_proc(psinfo_t *psinfo) 180*7c478bd9Sstevel@tonic-gate { 181*7c478bd9Sstevel@tonic-gate if (g_flags & F_OUTPUT) 182*7c478bd9Sstevel@tonic-gate (void) printf("%s%d", g_delim, (int)psinfo->pr_pid); 183*7c478bd9Sstevel@tonic-gate else { 184*7c478bd9Sstevel@tonic-gate (void) printf("%d", (int)psinfo->pr_pid); 185*7c478bd9Sstevel@tonic-gate g_flags |= F_OUTPUT; 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate static char * 190*7c478bd9Sstevel@tonic-gate mbstrip(char *buf, size_t nbytes) 191*7c478bd9Sstevel@tonic-gate { 192*7c478bd9Sstevel@tonic-gate wchar_t wc; 193*7c478bd9Sstevel@tonic-gate char *p; 194*7c478bd9Sstevel@tonic-gate int n; 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate buf[nbytes - 1] = '\0'; 197*7c478bd9Sstevel@tonic-gate p = buf; 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate while (*p != '\0') { 200*7c478bd9Sstevel@tonic-gate n = mbtowc(&wc, p, MB_LEN_MAX); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate if (n < 0 || !iswprint(wc)) { 203*7c478bd9Sstevel@tonic-gate if (n < 0) 204*7c478bd9Sstevel@tonic-gate n = sizeof (char); 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate if (nbytes <= n) { 207*7c478bd9Sstevel@tonic-gate *p = '\0'; 208*7c478bd9Sstevel@tonic-gate break; 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate (void) memmove(p, p + n, nbytes - n); 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate } else { 214*7c478bd9Sstevel@tonic-gate nbytes -= n; 215*7c478bd9Sstevel@tonic-gate p += n; 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate return (buf); 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate static void 223*7c478bd9Sstevel@tonic-gate print_proc_long(psinfo_t *psinfo) 224*7c478bd9Sstevel@tonic-gate { 225*7c478bd9Sstevel@tonic-gate char *name; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate if (g_flags & F_LONG_FMT) 228*7c478bd9Sstevel@tonic-gate name = mbstrip(psinfo->pr_psargs, PRARGSZ); 229*7c478bd9Sstevel@tonic-gate else 230*7c478bd9Sstevel@tonic-gate name = psinfo->pr_fname; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (g_flags & F_OUTPUT) 233*7c478bd9Sstevel@tonic-gate (void) printf("%s%5d %s", g_delim, (int)psinfo->pr_pid, name); 234*7c478bd9Sstevel@tonic-gate else { 235*7c478bd9Sstevel@tonic-gate (void) printf("%5d %s", (int)psinfo->pr_pid, name); 236*7c478bd9Sstevel@tonic-gate g_flags |= F_OUTPUT; 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate static void 241*7c478bd9Sstevel@tonic-gate kill_proc(psinfo_t *psinfo) 242*7c478bd9Sstevel@tonic-gate { 243*7c478bd9Sstevel@tonic-gate if (psinfo->pr_pid > 0 && kill(psinfo->pr_pid, g_signal) == -1) 244*7c478bd9Sstevel@tonic-gate uu_warn(gettext("Failed to signal pid %d"), 245*7c478bd9Sstevel@tonic-gate (int)psinfo->pr_pid); 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate static DIR * 249*7c478bd9Sstevel@tonic-gate open_proc_dir(const char *dirpath) 250*7c478bd9Sstevel@tonic-gate { 251*7c478bd9Sstevel@tonic-gate struct stat buf; 252*7c478bd9Sstevel@tonic-gate DIR *dirp; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate if ((dirp = opendir(dirpath)) == NULL) { 255*7c478bd9Sstevel@tonic-gate uu_warn(gettext("Failed to open %s"), dirpath); 256*7c478bd9Sstevel@tonic-gate return (NULL); 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate if (fstat(dirp->dd_fd, &buf) == -1) { 260*7c478bd9Sstevel@tonic-gate uu_warn(gettext("Failed to stat %s"), dirpath); 261*7c478bd9Sstevel@tonic-gate (void) closedir(dirp); 262*7c478bd9Sstevel@tonic-gate return (NULL); 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if (strcmp(buf.st_fstype, "proc") != 0) { 266*7c478bd9Sstevel@tonic-gate uu_warn(gettext("%s is not a procfs mount point\n"), dirpath); 267*7c478bd9Sstevel@tonic-gate (void) closedir(dirp); 268*7c478bd9Sstevel@tonic-gate return (NULL); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate return (dirp); 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate #define NEWER(ps1, ps2) \ 275*7c478bd9Sstevel@tonic-gate ((ps1.pr_start.tv_sec > ps2.pr_start.tv_sec) || \ 276*7c478bd9Sstevel@tonic-gate (ps1.pr_start.tv_sec == ps2.pr_start.tv_sec && \ 277*7c478bd9Sstevel@tonic-gate ps1.pr_start.tv_nsec > ps2.pr_start.tv_nsec)) 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate static int 280*7c478bd9Sstevel@tonic-gate scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp, 281*7c478bd9Sstevel@tonic-gate void (*funcp)(psinfo_t *)) 282*7c478bd9Sstevel@tonic-gate { 283*7c478bd9Sstevel@tonic-gate char procpath[MAXPATHLEN]; 284*7c478bd9Sstevel@tonic-gate psinfo_t ps, ops; 285*7c478bd9Sstevel@tonic-gate dirent_t *dent; 286*7c478bd9Sstevel@tonic-gate int procfd; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate int reverse = (g_flags & F_REVERSE) ? 1 : 0; 289*7c478bd9Sstevel@tonic-gate int ovalid = 0, nmatches = 0, flags = 0; 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate if (g_flags & F_LONG_FMT) 292*7c478bd9Sstevel@tonic-gate flags |= PSEXP_PSARGS; 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate if (g_flags & F_EXACT_MATCH) 295*7c478bd9Sstevel@tonic-gate flags |= PSEXP_EXACT; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate while ((dent = readdir(dirp)) != NULL) { 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate if (dent->d_name[0] == '.') 300*7c478bd9Sstevel@tonic-gate continue; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate (void) snprintf(procpath, sizeof (procpath), "%s/%s/psinfo", 303*7c478bd9Sstevel@tonic-gate dirpath, dent->d_name); 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate if ((procfd = open(procpath, O_RDONLY)) == -1) 306*7c478bd9Sstevel@tonic-gate continue; 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate if ((read(procfd, &ps, sizeof (ps)) == sizeof (psinfo_t)) && 309*7c478bd9Sstevel@tonic-gate (ps.pr_nlwp != 0) && (ps.pr_pid != g_pid) && 310*7c478bd9Sstevel@tonic-gate (psexp_match(psexp, &ps, flags) ^ reverse)) { 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate if (g_flags & F_NEWEST) { 313*7c478bd9Sstevel@tonic-gate /* LINTED - opsinfo use ok */ 314*7c478bd9Sstevel@tonic-gate if (!ovalid || NEWER(ps, ops)) { 315*7c478bd9Sstevel@tonic-gate (void) memcpy(&ops, &ps, 316*7c478bd9Sstevel@tonic-gate sizeof (psinfo_t)); 317*7c478bd9Sstevel@tonic-gate ovalid = 1; 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate } else if (g_flags & F_OLDEST) { 320*7c478bd9Sstevel@tonic-gate if (!ovalid || NEWER(ops, ps)) { 321*7c478bd9Sstevel@tonic-gate (void) memcpy(&ops, &ps, 322*7c478bd9Sstevel@tonic-gate sizeof (psinfo_t)); 323*7c478bd9Sstevel@tonic-gate ovalid = 1; 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate } else { 326*7c478bd9Sstevel@tonic-gate (*funcp)(&ps); 327*7c478bd9Sstevel@tonic-gate nmatches++; 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate (void) close(procfd); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate if ((g_flags & (F_NEWEST | F_OLDEST)) && ovalid) { 335*7c478bd9Sstevel@tonic-gate (*funcp)(&ops); 336*7c478bd9Sstevel@tonic-gate nmatches++; 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate return (nmatches); 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate static int 343*7c478bd9Sstevel@tonic-gate parse_ids(idtab_t *idt, char *arg, int base, int opt, idkey_t zero) 344*7c478bd9Sstevel@tonic-gate { 345*7c478bd9Sstevel@tonic-gate char *ptr, *next; 346*7c478bd9Sstevel@tonic-gate idkey_t id; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 349*7c478bd9Sstevel@tonic-gate if ((id = (idkey_t)strtoul(ptr, &next, base)) != 0) 350*7c478bd9Sstevel@tonic-gate idtab_append(idt, id); 351*7c478bd9Sstevel@tonic-gate else 352*7c478bd9Sstevel@tonic-gate idtab_append(idt, zero); 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate if (next == ptr || *next != 0) { 355*7c478bd9Sstevel@tonic-gate uu_warn("invalid argument for option '%c' -- %s\n", 356*7c478bd9Sstevel@tonic-gate opt, ptr); 357*7c478bd9Sstevel@tonic-gate return (-1); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate return (0); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate static int 365*7c478bd9Sstevel@tonic-gate parse_uids(idtab_t *idt, char *arg) 366*7c478bd9Sstevel@tonic-gate { 367*7c478bd9Sstevel@tonic-gate char *ptr, *next; 368*7c478bd9Sstevel@tonic-gate struct passwd *pwent; 369*7c478bd9Sstevel@tonic-gate idkey_t id; 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 372*7c478bd9Sstevel@tonic-gate if (isdigit(ptr[0])) { 373*7c478bd9Sstevel@tonic-gate id = strtol(ptr, &next, 10); 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate if (next != ptr && *next == '\0') { 376*7c478bd9Sstevel@tonic-gate idtab_append(idt, id); 377*7c478bd9Sstevel@tonic-gate continue; 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate if ((pwent = getpwnam(ptr)) != NULL) 382*7c478bd9Sstevel@tonic-gate idtab_append(idt, pwent->pw_uid); 383*7c478bd9Sstevel@tonic-gate else 384*7c478bd9Sstevel@tonic-gate goto err; 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate return (0); 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate err: 390*7c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid user name -- %s\n"), ptr); 391*7c478bd9Sstevel@tonic-gate return (-1); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate static int 395*7c478bd9Sstevel@tonic-gate parse_gids(idtab_t *idt, char *arg) 396*7c478bd9Sstevel@tonic-gate { 397*7c478bd9Sstevel@tonic-gate char *ptr, *next; 398*7c478bd9Sstevel@tonic-gate struct group *grent; 399*7c478bd9Sstevel@tonic-gate idkey_t id; 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 402*7c478bd9Sstevel@tonic-gate if (isdigit(ptr[0])) { 403*7c478bd9Sstevel@tonic-gate id = strtol(ptr, &next, 10); 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate if (next != ptr && *next == '\0') { 406*7c478bd9Sstevel@tonic-gate idtab_append(idt, id); 407*7c478bd9Sstevel@tonic-gate continue; 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate if ((grent = getgrnam(ptr)) != NULL) 412*7c478bd9Sstevel@tonic-gate idtab_append(idt, grent->gr_gid); 413*7c478bd9Sstevel@tonic-gate else 414*7c478bd9Sstevel@tonic-gate goto err; 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate return (0); 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate err: 420*7c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid group name -- %s\n"), ptr); 421*7c478bd9Sstevel@tonic-gate return (-1); 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate static int 425*7c478bd9Sstevel@tonic-gate parse_ttys(idtab_t *idt, char *arg) 426*7c478bd9Sstevel@tonic-gate { 427*7c478bd9Sstevel@tonic-gate char devpath[MAXPATHLEN]; 428*7c478bd9Sstevel@tonic-gate struct stat buf; 429*7c478bd9Sstevel@tonic-gate char *ptr; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate int seen_console = 0; /* Flag so we only stat syscon and systty once */ 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 434*7c478bd9Sstevel@tonic-gate if (strcmp(ptr, "none") == 0) { 435*7c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)PRNODEV); 436*7c478bd9Sstevel@tonic-gate continue; 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate if (strcmp(ptr, "console") == 0) { 440*7c478bd9Sstevel@tonic-gate if (seen_console) 441*7c478bd9Sstevel@tonic-gate continue; 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate if (stat("/dev/syscon", &buf) == 0) 444*7c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)buf.st_rdev); 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate if (stat("/dev/systty", &buf) == 0) 447*7c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)buf.st_rdev); 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate seen_console++; 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate (void) snprintf(devpath, MAXPATHLEN - 1, "/dev/%s", ptr); 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate if (stat(devpath, &buf) == -1) 455*7c478bd9Sstevel@tonic-gate goto err; 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)buf.st_rdev); 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate return (0); 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate err: 463*7c478bd9Sstevel@tonic-gate uu_warn(gettext("unknown terminal name -- %s\n"), ptr); 464*7c478bd9Sstevel@tonic-gate return (-1); 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate static int 468*7c478bd9Sstevel@tonic-gate parse_projects(idtab_t *idt, char *arg) 469*7c478bd9Sstevel@tonic-gate { 470*7c478bd9Sstevel@tonic-gate char *ptr, *next; 471*7c478bd9Sstevel@tonic-gate projid_t projid; 472*7c478bd9Sstevel@tonic-gate idkey_t id; 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 475*7c478bd9Sstevel@tonic-gate if (isdigit(ptr[0])) { 476*7c478bd9Sstevel@tonic-gate id = strtol(ptr, &next, 10); 477*7c478bd9Sstevel@tonic-gate 478*7c478bd9Sstevel@tonic-gate if (next != ptr && *next == '\0') { 479*7c478bd9Sstevel@tonic-gate idtab_append(idt, id); 480*7c478bd9Sstevel@tonic-gate continue; 481*7c478bd9Sstevel@tonic-gate } 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(ptr)) != -1) 485*7c478bd9Sstevel@tonic-gate idtab_append(idt, projid); 486*7c478bd9Sstevel@tonic-gate else 487*7c478bd9Sstevel@tonic-gate goto err; 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate return (0); 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate err: 493*7c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid project name -- %s\n"), ptr); 494*7c478bd9Sstevel@tonic-gate return (-1); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate static int 498*7c478bd9Sstevel@tonic-gate parse_zones(idtab_t *idt, char *arg) 499*7c478bd9Sstevel@tonic-gate { 500*7c478bd9Sstevel@tonic-gate char *ptr; 501*7c478bd9Sstevel@tonic-gate zoneid_t id; 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 504*7c478bd9Sstevel@tonic-gate if (zone_get_id(ptr, &id) != 0) { 505*7c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid zone name -- %s\n"), ptr); 506*7c478bd9Sstevel@tonic-gate return (-1); 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate idtab_append(idt, id); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate return (0); 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 515*7c478bd9Sstevel@tonic-gate static int 516*7c478bd9Sstevel@tonic-gate opt_euid(char c, char *arg) 517*7c478bd9Sstevel@tonic-gate { 518*7c478bd9Sstevel@tonic-gate return (parse_uids(&g_psexp.ps_euids, arg)); 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 522*7c478bd9Sstevel@tonic-gate static int 523*7c478bd9Sstevel@tonic-gate opt_uid(char c, char *arg) 524*7c478bd9Sstevel@tonic-gate { 525*7c478bd9Sstevel@tonic-gate return (parse_uids(&g_psexp.ps_ruids, arg)); 526*7c478bd9Sstevel@tonic-gate } 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 529*7c478bd9Sstevel@tonic-gate static int 530*7c478bd9Sstevel@tonic-gate opt_gid(char c, char *arg) 531*7c478bd9Sstevel@tonic-gate { 532*7c478bd9Sstevel@tonic-gate return (parse_gids(&g_psexp.ps_rgids, arg)); 533*7c478bd9Sstevel@tonic-gate } 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate static int 536*7c478bd9Sstevel@tonic-gate opt_ppid(char c, char *arg) 537*7c478bd9Sstevel@tonic-gate { 538*7c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_ppids, arg, 10, c, 0)); 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate static int 542*7c478bd9Sstevel@tonic-gate opt_pgrp(char c, char *arg) 543*7c478bd9Sstevel@tonic-gate { 544*7c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_pgids, arg, 10, c, getpgrp())); 545*7c478bd9Sstevel@tonic-gate } 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate static int 548*7c478bd9Sstevel@tonic-gate opt_sid(char c, char *arg) 549*7c478bd9Sstevel@tonic-gate { 550*7c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_sids, arg, 10, c, getsid(0))); 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 554*7c478bd9Sstevel@tonic-gate static int 555*7c478bd9Sstevel@tonic-gate opt_term(char c, char *arg) 556*7c478bd9Sstevel@tonic-gate { 557*7c478bd9Sstevel@tonic-gate return (parse_ttys(&g_psexp.ps_ttys, arg)); 558*7c478bd9Sstevel@tonic-gate } 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 561*7c478bd9Sstevel@tonic-gate static int 562*7c478bd9Sstevel@tonic-gate opt_projid(char c, char *arg) 563*7c478bd9Sstevel@tonic-gate { 564*7c478bd9Sstevel@tonic-gate return (parse_projects(&g_psexp.ps_projids, arg)); 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate static int 568*7c478bd9Sstevel@tonic-gate opt_taskid(char c, char *arg) 569*7c478bd9Sstevel@tonic-gate { 570*7c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_taskids, arg, 10, c, gettaskid())); 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 574*7c478bd9Sstevel@tonic-gate static int 575*7c478bd9Sstevel@tonic-gate opt_zoneid(char c, char *arg) 576*7c478bd9Sstevel@tonic-gate { 577*7c478bd9Sstevel@tonic-gate return (parse_zones(&g_psexp.ps_zoneids, arg)); 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate static int 581*7c478bd9Sstevel@tonic-gate opt_ctid(char c, char *arg) 582*7c478bd9Sstevel@tonic-gate { 583*7c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_ctids, arg, 10, c, getctid())); 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 587*7c478bd9Sstevel@tonic-gate static int 588*7c478bd9Sstevel@tonic-gate opt_V(char c, char *arg) 589*7c478bd9Sstevel@tonic-gate { 590*7c478bd9Sstevel@tonic-gate idtab_append(&g_psexp.ps_ruids, 0); 591*7c478bd9Sstevel@tonic-gate g_flags |= F_EXACT_MATCH; 592*7c478bd9Sstevel@tonic-gate g_psexp.ps_pat = "vold"; 593*7c478bd9Sstevel@tonic-gate return (0); 594*7c478bd9Sstevel@tonic-gate } 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate static void 597*7c478bd9Sstevel@tonic-gate print_usage(FILE *stream) 598*7c478bd9Sstevel@tonic-gate { 599*7c478bd9Sstevel@tonic-gate if (g_flags & F_KILL) 600*7c478bd9Sstevel@tonic-gate (void) fprintf(stream, gettext(PKILL_USAGE), g_pname); 601*7c478bd9Sstevel@tonic-gate else 602*7c478bd9Sstevel@tonic-gate (void) fprintf(stream, gettext(PGREP_USAGE), g_pname); 603*7c478bd9Sstevel@tonic-gate } 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate int 606*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 607*7c478bd9Sstevel@tonic-gate { 608*7c478bd9Sstevel@tonic-gate void (*funcp)(psinfo_t *); 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate const char *optstr; 611*7c478bd9Sstevel@tonic-gate optdesc_t *optd; 612*7c478bd9Sstevel@tonic-gate int nmatches, c; 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate DIR *dirp; 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 617*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate UU_EXIT_FATAL = E_ERROR; 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate g_pname = uu_setpname(argv[0]); 622*7c478bd9Sstevel@tonic-gate g_pid = getpid(); 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate psexp_create(&g_psexp); 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate if (strcmp(g_pname, "pkill") == 0) { 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate if (argc > 1 && argv[1][0] == '-' && 629*7c478bd9Sstevel@tonic-gate str2sig(&argv[1][1], &g_signal) == 0) { 630*7c478bd9Sstevel@tonic-gate argv[1] = argv[0]; 631*7c478bd9Sstevel@tonic-gate argv++; 632*7c478bd9Sstevel@tonic-gate argc--; 633*7c478bd9Sstevel@tonic-gate } 634*7c478bd9Sstevel@tonic-gate 635*7c478bd9Sstevel@tonic-gate optstr = PKILL_OPTS; 636*7c478bd9Sstevel@tonic-gate g_flags |= F_KILL; 637*7c478bd9Sstevel@tonic-gate } else 638*7c478bd9Sstevel@tonic-gate optstr = PGREP_OPTS; 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate opterr = 0; 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate while (optind < argc) { 643*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, optstr)) != (int)EOF) { 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate if (c == '?' || g_optdtab[c - 'A'].o_opts == 0) { 646*7c478bd9Sstevel@tonic-gate if (optopt != '?') { 647*7c478bd9Sstevel@tonic-gate uu_warn( 648*7c478bd9Sstevel@tonic-gate gettext("illegal option -- %c\n"), 649*7c478bd9Sstevel@tonic-gate optopt); 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate print_usage(stderr); 653*7c478bd9Sstevel@tonic-gate return (E_USAGE); 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate optd = &g_optdtab[c - 'A']; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_SETB) 659*7c478bd9Sstevel@tonic-gate *((ushort_t *)optd->o_ptr) |= optd->o_bits; 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_CLRB) 662*7c478bd9Sstevel@tonic-gate *((ushort_t *)optd->o_ptr) &= ~optd->o_bits; 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_STR) 665*7c478bd9Sstevel@tonic-gate *((char **)optd->o_ptr) = optarg; 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_CRIT) 668*7c478bd9Sstevel@tonic-gate g_flags |= F_HAVE_CRIT; 669*7c478bd9Sstevel@tonic-gate 670*7c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_FUNC) { 671*7c478bd9Sstevel@tonic-gate if (optd->o_func(c, optarg) == -1) 672*7c478bd9Sstevel@tonic-gate return (E_USAGE); 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate if (optind < argc) { 677*7c478bd9Sstevel@tonic-gate if (g_psexp.ps_pat != NULL) { 678*7c478bd9Sstevel@tonic-gate uu_warn(gettext("illegal argument -- %s\n"), 679*7c478bd9Sstevel@tonic-gate argv[optind]); 680*7c478bd9Sstevel@tonic-gate print_usage(stderr); 681*7c478bd9Sstevel@tonic-gate return (E_USAGE); 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate g_psexp.ps_pat = argv[optind++]; 685*7c478bd9Sstevel@tonic-gate g_flags |= F_HAVE_CRIT; 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate if ((g_flags & F_NEWEST) && (g_flags & F_OLDEST)) { 690*7c478bd9Sstevel@tonic-gate uu_warn(gettext("-n and -o are mutually exclusive\n")); 691*7c478bd9Sstevel@tonic-gate print_usage(stderr); 692*7c478bd9Sstevel@tonic-gate return (E_USAGE); 693*7c478bd9Sstevel@tonic-gate } 694*7c478bd9Sstevel@tonic-gate 695*7c478bd9Sstevel@tonic-gate if ((g_flags & F_HAVE_CRIT) == 0) { 696*7c478bd9Sstevel@tonic-gate uu_warn(gettext("No matching criteria specified\n")); 697*7c478bd9Sstevel@tonic-gate print_usage(stderr); 698*7c478bd9Sstevel@tonic-gate return (E_USAGE); 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate if (psexp_compile(&g_psexp) == -1) { 702*7c478bd9Sstevel@tonic-gate psexp_destroy(&g_psexp); 703*7c478bd9Sstevel@tonic-gate return (E_USAGE); 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate if ((dirp = open_proc_dir(g_procdir)) == NULL) 707*7c478bd9Sstevel@tonic-gate return (E_ERROR); 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate if (g_flags & F_KILL) 710*7c478bd9Sstevel@tonic-gate funcp = kill_proc; 711*7c478bd9Sstevel@tonic-gate else if (g_flags & F_LONG_OUT) 712*7c478bd9Sstevel@tonic-gate funcp = print_proc_long; 713*7c478bd9Sstevel@tonic-gate else 714*7c478bd9Sstevel@tonic-gate funcp = print_proc; 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate nmatches = scan_proc_dir(g_procdir, dirp, &g_psexp, funcp); 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate if (g_flags & F_OUTPUT) 719*7c478bd9Sstevel@tonic-gate (void) fputc('\n', stdout); 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate psexp_destroy(&g_psexp); 722*7c478bd9Sstevel@tonic-gate return (nmatches ? E_MATCH : E_NOMATCH); 723*7c478bd9Sstevel@tonic-gate } 724