17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 518c2aff7Sartem * Common Development and Distribution License (the "License"). 618c2aff7Sartem * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2218c2aff7Sartem * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 25*e8d80663SEric Schrock /* Copyright (c) 2012 by Delphix. All rights reserved */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <sys/types.h> 287c478bd9Sstevel@tonic-gate #include <sys/stat.h> 297c478bd9Sstevel@tonic-gate #include <sys/param.h> 307c478bd9Sstevel@tonic-gate #include <sys/task.h> 317c478bd9Sstevel@tonic-gate #include <sys/contract.h> 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <signal.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <dirent.h> 367c478bd9Sstevel@tonic-gate #include <stdlib.h> 377c478bd9Sstevel@tonic-gate #include <string.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #include <libintl.h> 407c478bd9Sstevel@tonic-gate #include <locale.h> 417c478bd9Sstevel@tonic-gate #include <stdio.h> 427c478bd9Sstevel@tonic-gate #include <fcntl.h> 437c478bd9Sstevel@tonic-gate #include <ctype.h> 447c478bd9Sstevel@tonic-gate #include <wchar.h> 457c478bd9Sstevel@tonic-gate #include <limits.h> 467c478bd9Sstevel@tonic-gate #include <libuutil.h> 477c478bd9Sstevel@tonic-gate #include <libcontract_priv.h> 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #include <procfs.h> 507c478bd9Sstevel@tonic-gate #include <project.h> 517c478bd9Sstevel@tonic-gate #include <pwd.h> 527c478bd9Sstevel@tonic-gate #include <grp.h> 537c478bd9Sstevel@tonic-gate #include <zone.h> 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate #include "psexp.h" 567c478bd9Sstevel@tonic-gate #include "pgrep.h" 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN 597c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 607c478bd9Sstevel@tonic-gate #endif 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate #define OPT_SETB 0x0001 /* Set the bits specified by o_bits */ 637c478bd9Sstevel@tonic-gate #define OPT_CLRB 0x0002 /* Clear the bits specified by o_bits */ 647c478bd9Sstevel@tonic-gate #define OPT_FUNC 0x0004 /* Call the function specified by o_func */ 657c478bd9Sstevel@tonic-gate #define OPT_STR 0x0008 /* Set the string specified by o_ptr */ 667c478bd9Sstevel@tonic-gate #define OPT_CRIT 0x0010 /* Option is part of selection criteria */ 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate #define F_LONG_FMT 0x0001 /* Match against long format cmd */ 697c478bd9Sstevel@tonic-gate #define F_NEWEST 0x0002 /* Match only newest pid */ 707c478bd9Sstevel@tonic-gate #define F_REVERSE 0x0004 /* Reverse matching criteria */ 717c478bd9Sstevel@tonic-gate #define F_EXACT_MATCH 0x0008 /* Require exact match */ 727c478bd9Sstevel@tonic-gate #define F_HAVE_CRIT 0x0010 /* Criteria specified */ 737c478bd9Sstevel@tonic-gate #define F_OUTPUT 0x0020 /* Some output has been printed */ 747c478bd9Sstevel@tonic-gate #define F_KILL 0x0040 /* Pkill semantics active (vs pgrep) */ 757c478bd9Sstevel@tonic-gate #define F_LONG_OUT 0x0080 /* Long output format (pgrep -l) */ 767c478bd9Sstevel@tonic-gate #define F_OLDEST 0x0100 /* Match only oldest pid */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate static int opt_euid(char, char *); 797c478bd9Sstevel@tonic-gate static int opt_uid(char, char *); 807c478bd9Sstevel@tonic-gate static int opt_gid(char, char *); 817c478bd9Sstevel@tonic-gate static int opt_ppid(char, char *); 827c478bd9Sstevel@tonic-gate static int opt_pgrp(char, char *); 837c478bd9Sstevel@tonic-gate static int opt_sid(char, char *); 847c478bd9Sstevel@tonic-gate static int opt_term(char, char *); 857c478bd9Sstevel@tonic-gate static int opt_projid(char, char *); 867c478bd9Sstevel@tonic-gate static int opt_taskid(char, char *); 877c478bd9Sstevel@tonic-gate static int opt_zoneid(char, char *); 887c478bd9Sstevel@tonic-gate static int opt_ctid(char, char *); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate static const char *g_procdir = "/proc"; /* Default procfs mount point */ 917c478bd9Sstevel@tonic-gate static const char *g_delim = "\n"; /* Default output delimiter */ 927c478bd9Sstevel@tonic-gate static const char *g_pname; /* Program name for error messages */ 937c478bd9Sstevel@tonic-gate static ushort_t g_flags; /* Miscellaneous flags */ 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate static optdesc_t g_optdtab[] = { 967c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'A' */ 977c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'B' */ 987c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'C' */ 997c478bd9Sstevel@tonic-gate { OPT_STR, 0, 0, &g_procdir }, /* -D procfsdir */ 1007c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'E' */ 1017c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'F' */ 1027c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_gid, 0 }, /* -G gid */ 1037c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'H' */ 1047c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'I' */ 1057c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_projid, 0 }, /* -J projid */ 1067c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'K' */ 1077c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'L' */ 1087c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'M' */ 1097c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'N' */ 1107c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'O' */ 1117c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_ppid, 0 }, /* -P ppid */ 1127c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'Q' */ 1137c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'R' */ 1147c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'S' */ 1157c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_taskid, 0 }, /* -T taskid */ 1167c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_uid, 0 }, /* -U uid */ 11718c2aff7Sartem { 0, 0, 0, 0 }, /* 'V' */ 1187c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'W' */ 1197c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'X' */ 1207c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'Y' */ 1217c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'Z' */ 1227c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '[' */ 1237c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '\\' */ 1247c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* ']' */ 1257c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '^' */ 1267c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '_' */ 1277c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* '`' */ 1287c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'a' */ 1297c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'b' */ 1307c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_ctid, 0 }, /* -c ctid */ 1317c478bd9Sstevel@tonic-gate { OPT_STR, 0, 0, &g_delim }, /* -d delim */ 1327c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'e' */ 1337c478bd9Sstevel@tonic-gate { OPT_SETB, F_LONG_FMT, 0, &g_flags }, /* -f */ 1347c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_pgrp, 0 }, /* -g pgrp */ 1357c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'h' */ 1367c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'i' */ 1377c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'j' */ 1387c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'k' */ 1397c478bd9Sstevel@tonic-gate { OPT_SETB, F_LONG_OUT, 0, &g_flags }, /* 'l' */ 1407c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'm' */ 1417c478bd9Sstevel@tonic-gate { OPT_SETB, F_NEWEST, 0, &g_flags }, /* -n */ 1427c478bd9Sstevel@tonic-gate { OPT_SETB, F_OLDEST, 0, &g_flags }, /* -o */ 1437c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'p' */ 1447c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'q' */ 1457c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'r' */ 1467c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_sid, 0 }, /* -s sid */ 1477c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_term, 0 }, /* -t term */ 1487c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_euid, 0 }, /* -u euid */ 1497c478bd9Sstevel@tonic-gate { OPT_SETB, F_REVERSE, 0, &g_flags }, /* -v */ 1507c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'w' */ 1517c478bd9Sstevel@tonic-gate { OPT_SETB, F_EXACT_MATCH, 0, &g_flags }, /* -x */ 1527c478bd9Sstevel@tonic-gate { 0, 0, 0, 0 }, /* 'y' */ 1537c478bd9Sstevel@tonic-gate { OPT_FUNC | OPT_CRIT, 0, opt_zoneid, 0 } /* -z zoneid */ 1547c478bd9Sstevel@tonic-gate }; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate static const char PGREP_USAGE[] = "\ 1577c478bd9Sstevel@tonic-gate Usage: %s [-flnovx] [-d delim] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\ 1587c478bd9Sstevel@tonic-gate [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\ 1597c478bd9Sstevel@tonic-gate [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n"; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate static const char PKILL_USAGE[] = "\ 1627c478bd9Sstevel@tonic-gate Usage: %s [-signal] [-fnovx] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\ 1637c478bd9Sstevel@tonic-gate [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\ 1647c478bd9Sstevel@tonic-gate [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n"; 1657c478bd9Sstevel@tonic-gate 166*e8d80663SEric Schrock static const char PGREP_OPTS[] = ":flnovxc:d:D:u:U:G:P:g:s:t:z:J:T:"; 167*e8d80663SEric Schrock static const char PKILL_OPTS[] = ":fnovxc:D:u:U:G:P:g:s:t:z:J:T:"; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate static const char LSEP[] = ",\t "; /* Argument list delimiter chars */ 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate static psexp_t g_psexp; /* Process matching expression */ 1727c478bd9Sstevel@tonic-gate static pid_t g_pid; /* Current pid */ 1737c478bd9Sstevel@tonic-gate static int g_signal = SIGTERM; /* Signal to send */ 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate static void 1767c478bd9Sstevel@tonic-gate print_proc(psinfo_t *psinfo) 1777c478bd9Sstevel@tonic-gate { 1787c478bd9Sstevel@tonic-gate if (g_flags & F_OUTPUT) 1797c478bd9Sstevel@tonic-gate (void) printf("%s%d", g_delim, (int)psinfo->pr_pid); 1807c478bd9Sstevel@tonic-gate else { 1817c478bd9Sstevel@tonic-gate (void) printf("%d", (int)psinfo->pr_pid); 1827c478bd9Sstevel@tonic-gate g_flags |= F_OUTPUT; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate static char * 1877c478bd9Sstevel@tonic-gate mbstrip(char *buf, size_t nbytes) 1887c478bd9Sstevel@tonic-gate { 1897c478bd9Sstevel@tonic-gate wchar_t wc; 1907c478bd9Sstevel@tonic-gate char *p; 1917c478bd9Sstevel@tonic-gate int n; 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate buf[nbytes - 1] = '\0'; 1947c478bd9Sstevel@tonic-gate p = buf; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate while (*p != '\0') { 1977c478bd9Sstevel@tonic-gate n = mbtowc(&wc, p, MB_LEN_MAX); 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate if (n < 0 || !iswprint(wc)) { 2007c478bd9Sstevel@tonic-gate if (n < 0) 2017c478bd9Sstevel@tonic-gate n = sizeof (char); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate if (nbytes <= n) { 2047c478bd9Sstevel@tonic-gate *p = '\0'; 2057c478bd9Sstevel@tonic-gate break; 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate (void) memmove(p, p + n, nbytes - n); 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate } else { 2117c478bd9Sstevel@tonic-gate nbytes -= n; 2127c478bd9Sstevel@tonic-gate p += n; 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate return (buf); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate static void 2207c478bd9Sstevel@tonic-gate print_proc_long(psinfo_t *psinfo) 2217c478bd9Sstevel@tonic-gate { 2227c478bd9Sstevel@tonic-gate char *name; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if (g_flags & F_LONG_FMT) 2257c478bd9Sstevel@tonic-gate name = mbstrip(psinfo->pr_psargs, PRARGSZ); 2267c478bd9Sstevel@tonic-gate else 2277c478bd9Sstevel@tonic-gate name = psinfo->pr_fname; 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate if (g_flags & F_OUTPUT) 2307c478bd9Sstevel@tonic-gate (void) printf("%s%5d %s", g_delim, (int)psinfo->pr_pid, name); 2317c478bd9Sstevel@tonic-gate else { 2327c478bd9Sstevel@tonic-gate (void) printf("%5d %s", (int)psinfo->pr_pid, name); 2337c478bd9Sstevel@tonic-gate g_flags |= F_OUTPUT; 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate static void 2387c478bd9Sstevel@tonic-gate kill_proc(psinfo_t *psinfo) 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate if (psinfo->pr_pid > 0 && kill(psinfo->pr_pid, g_signal) == -1) 2417c478bd9Sstevel@tonic-gate uu_warn(gettext("Failed to signal pid %d"), 2427c478bd9Sstevel@tonic-gate (int)psinfo->pr_pid); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate static DIR * 2467c478bd9Sstevel@tonic-gate open_proc_dir(const char *dirpath) 2477c478bd9Sstevel@tonic-gate { 2487c478bd9Sstevel@tonic-gate struct stat buf; 2497c478bd9Sstevel@tonic-gate DIR *dirp; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate if ((dirp = opendir(dirpath)) == NULL) { 2527c478bd9Sstevel@tonic-gate uu_warn(gettext("Failed to open %s"), dirpath); 2537c478bd9Sstevel@tonic-gate return (NULL); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate if (fstat(dirp->dd_fd, &buf) == -1) { 2577c478bd9Sstevel@tonic-gate uu_warn(gettext("Failed to stat %s"), dirpath); 2587c478bd9Sstevel@tonic-gate (void) closedir(dirp); 2597c478bd9Sstevel@tonic-gate return (NULL); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate if (strcmp(buf.st_fstype, "proc") != 0) { 2637c478bd9Sstevel@tonic-gate uu_warn(gettext("%s is not a procfs mount point\n"), dirpath); 2647c478bd9Sstevel@tonic-gate (void) closedir(dirp); 2657c478bd9Sstevel@tonic-gate return (NULL); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate return (dirp); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate #define NEWER(ps1, ps2) \ 2727c478bd9Sstevel@tonic-gate ((ps1.pr_start.tv_sec > ps2.pr_start.tv_sec) || \ 2737c478bd9Sstevel@tonic-gate (ps1.pr_start.tv_sec == ps2.pr_start.tv_sec && \ 2747c478bd9Sstevel@tonic-gate ps1.pr_start.tv_nsec > ps2.pr_start.tv_nsec)) 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate static int 2777c478bd9Sstevel@tonic-gate scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp, 2787c478bd9Sstevel@tonic-gate void (*funcp)(psinfo_t *)) 2797c478bd9Sstevel@tonic-gate { 2807c478bd9Sstevel@tonic-gate char procpath[MAXPATHLEN]; 2817c478bd9Sstevel@tonic-gate psinfo_t ps, ops; 2827c478bd9Sstevel@tonic-gate dirent_t *dent; 2837c478bd9Sstevel@tonic-gate int procfd; 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate int reverse = (g_flags & F_REVERSE) ? 1 : 0; 2867c478bd9Sstevel@tonic-gate int ovalid = 0, nmatches = 0, flags = 0; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate if (g_flags & F_LONG_FMT) 2897c478bd9Sstevel@tonic-gate flags |= PSEXP_PSARGS; 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate if (g_flags & F_EXACT_MATCH) 2927c478bd9Sstevel@tonic-gate flags |= PSEXP_EXACT; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate while ((dent = readdir(dirp)) != NULL) { 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate if (dent->d_name[0] == '.') 2977c478bd9Sstevel@tonic-gate continue; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate (void) snprintf(procpath, sizeof (procpath), "%s/%s/psinfo", 3007c478bd9Sstevel@tonic-gate dirpath, dent->d_name); 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate if ((procfd = open(procpath, O_RDONLY)) == -1) 3037c478bd9Sstevel@tonic-gate continue; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate if ((read(procfd, &ps, sizeof (ps)) == sizeof (psinfo_t)) && 3067c478bd9Sstevel@tonic-gate (ps.pr_nlwp != 0) && (ps.pr_pid != g_pid) && 3077c478bd9Sstevel@tonic-gate (psexp_match(psexp, &ps, flags) ^ reverse)) { 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if (g_flags & F_NEWEST) { 3107c478bd9Sstevel@tonic-gate /* LINTED - opsinfo use ok */ 3117c478bd9Sstevel@tonic-gate if (!ovalid || NEWER(ps, ops)) { 3127c478bd9Sstevel@tonic-gate (void) memcpy(&ops, &ps, 3137c478bd9Sstevel@tonic-gate sizeof (psinfo_t)); 3147c478bd9Sstevel@tonic-gate ovalid = 1; 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate } else if (g_flags & F_OLDEST) { 3177c478bd9Sstevel@tonic-gate if (!ovalid || NEWER(ops, ps)) { 3187c478bd9Sstevel@tonic-gate (void) memcpy(&ops, &ps, 3197c478bd9Sstevel@tonic-gate sizeof (psinfo_t)); 3207c478bd9Sstevel@tonic-gate ovalid = 1; 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate } else { 3237c478bd9Sstevel@tonic-gate (*funcp)(&ps); 3247c478bd9Sstevel@tonic-gate nmatches++; 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate (void) close(procfd); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate if ((g_flags & (F_NEWEST | F_OLDEST)) && ovalid) { 3327c478bd9Sstevel@tonic-gate (*funcp)(&ops); 3337c478bd9Sstevel@tonic-gate nmatches++; 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate return (nmatches); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate static int 3407c478bd9Sstevel@tonic-gate parse_ids(idtab_t *idt, char *arg, int base, int opt, idkey_t zero) 3417c478bd9Sstevel@tonic-gate { 3427c478bd9Sstevel@tonic-gate char *ptr, *next; 3437c478bd9Sstevel@tonic-gate idkey_t id; 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 3467c478bd9Sstevel@tonic-gate if ((id = (idkey_t)strtoul(ptr, &next, base)) != 0) 3477c478bd9Sstevel@tonic-gate idtab_append(idt, id); 3487c478bd9Sstevel@tonic-gate else 3497c478bd9Sstevel@tonic-gate idtab_append(idt, zero); 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate if (next == ptr || *next != 0) { 3527c478bd9Sstevel@tonic-gate uu_warn("invalid argument for option '%c' -- %s\n", 3537c478bd9Sstevel@tonic-gate opt, ptr); 3547c478bd9Sstevel@tonic-gate return (-1); 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate return (0); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate static int 3627c478bd9Sstevel@tonic-gate parse_uids(idtab_t *idt, char *arg) 3637c478bd9Sstevel@tonic-gate { 3647c478bd9Sstevel@tonic-gate char *ptr, *next; 3657c478bd9Sstevel@tonic-gate struct passwd *pwent; 3667c478bd9Sstevel@tonic-gate idkey_t id; 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 3697c478bd9Sstevel@tonic-gate if (isdigit(ptr[0])) { 3707c478bd9Sstevel@tonic-gate id = strtol(ptr, &next, 10); 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate if (next != ptr && *next == '\0') { 3737c478bd9Sstevel@tonic-gate idtab_append(idt, id); 3747c478bd9Sstevel@tonic-gate continue; 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate if ((pwent = getpwnam(ptr)) != NULL) 3797c478bd9Sstevel@tonic-gate idtab_append(idt, pwent->pw_uid); 3807c478bd9Sstevel@tonic-gate else 3817c478bd9Sstevel@tonic-gate goto err; 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate return (0); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate err: 3877c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid user name -- %s\n"), ptr); 3887c478bd9Sstevel@tonic-gate return (-1); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate static int 3927c478bd9Sstevel@tonic-gate parse_gids(idtab_t *idt, char *arg) 3937c478bd9Sstevel@tonic-gate { 3947c478bd9Sstevel@tonic-gate char *ptr, *next; 3957c478bd9Sstevel@tonic-gate struct group *grent; 3967c478bd9Sstevel@tonic-gate idkey_t id; 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 3997c478bd9Sstevel@tonic-gate if (isdigit(ptr[0])) { 4007c478bd9Sstevel@tonic-gate id = strtol(ptr, &next, 10); 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate if (next != ptr && *next == '\0') { 4037c478bd9Sstevel@tonic-gate idtab_append(idt, id); 4047c478bd9Sstevel@tonic-gate continue; 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate if ((grent = getgrnam(ptr)) != NULL) 4097c478bd9Sstevel@tonic-gate idtab_append(idt, grent->gr_gid); 4107c478bd9Sstevel@tonic-gate else 4117c478bd9Sstevel@tonic-gate goto err; 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate return (0); 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate err: 4177c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid group name -- %s\n"), ptr); 4187c478bd9Sstevel@tonic-gate return (-1); 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate static int 4227c478bd9Sstevel@tonic-gate parse_ttys(idtab_t *idt, char *arg) 4237c478bd9Sstevel@tonic-gate { 4247c478bd9Sstevel@tonic-gate char devpath[MAXPATHLEN]; 4257c478bd9Sstevel@tonic-gate struct stat buf; 4267c478bd9Sstevel@tonic-gate char *ptr; 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate int seen_console = 0; /* Flag so we only stat syscon and systty once */ 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 4317c478bd9Sstevel@tonic-gate if (strcmp(ptr, "none") == 0) { 4327c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)PRNODEV); 4337c478bd9Sstevel@tonic-gate continue; 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate if (strcmp(ptr, "console") == 0) { 4377c478bd9Sstevel@tonic-gate if (seen_console) 4387c478bd9Sstevel@tonic-gate continue; 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate if (stat("/dev/syscon", &buf) == 0) 4417c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)buf.st_rdev); 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (stat("/dev/systty", &buf) == 0) 4447c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)buf.st_rdev); 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate seen_console++; 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate (void) snprintf(devpath, MAXPATHLEN - 1, "/dev/%s", ptr); 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate if (stat(devpath, &buf) == -1) 4527c478bd9Sstevel@tonic-gate goto err; 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate idtab_append(idt, (idkey_t)buf.st_rdev); 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate return (0); 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate err: 4607c478bd9Sstevel@tonic-gate uu_warn(gettext("unknown terminal name -- %s\n"), ptr); 4617c478bd9Sstevel@tonic-gate return (-1); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate static int 4657c478bd9Sstevel@tonic-gate parse_projects(idtab_t *idt, char *arg) 4667c478bd9Sstevel@tonic-gate { 4677c478bd9Sstevel@tonic-gate char *ptr, *next; 4687c478bd9Sstevel@tonic-gate projid_t projid; 4697c478bd9Sstevel@tonic-gate idkey_t id; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 4727c478bd9Sstevel@tonic-gate if (isdigit(ptr[0])) { 4737c478bd9Sstevel@tonic-gate id = strtol(ptr, &next, 10); 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate if (next != ptr && *next == '\0') { 4767c478bd9Sstevel@tonic-gate idtab_append(idt, id); 4777c478bd9Sstevel@tonic-gate continue; 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(ptr)) != -1) 4827c478bd9Sstevel@tonic-gate idtab_append(idt, projid); 4837c478bd9Sstevel@tonic-gate else 4847c478bd9Sstevel@tonic-gate goto err; 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate return (0); 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate err: 4907c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid project name -- %s\n"), ptr); 4917c478bd9Sstevel@tonic-gate return (-1); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate static int 4957c478bd9Sstevel@tonic-gate parse_zones(idtab_t *idt, char *arg) 4967c478bd9Sstevel@tonic-gate { 4977c478bd9Sstevel@tonic-gate char *ptr; 4987c478bd9Sstevel@tonic-gate zoneid_t id; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) { 5017c478bd9Sstevel@tonic-gate if (zone_get_id(ptr, &id) != 0) { 5027c478bd9Sstevel@tonic-gate uu_warn(gettext("invalid zone name -- %s\n"), ptr); 5037c478bd9Sstevel@tonic-gate return (-1); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate idtab_append(idt, id); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate return (0); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5127c478bd9Sstevel@tonic-gate static int 5137c478bd9Sstevel@tonic-gate opt_euid(char c, char *arg) 5147c478bd9Sstevel@tonic-gate { 5157c478bd9Sstevel@tonic-gate return (parse_uids(&g_psexp.ps_euids, arg)); 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5197c478bd9Sstevel@tonic-gate static int 5207c478bd9Sstevel@tonic-gate opt_uid(char c, char *arg) 5217c478bd9Sstevel@tonic-gate { 5227c478bd9Sstevel@tonic-gate return (parse_uids(&g_psexp.ps_ruids, arg)); 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5267c478bd9Sstevel@tonic-gate static int 5277c478bd9Sstevel@tonic-gate opt_gid(char c, char *arg) 5287c478bd9Sstevel@tonic-gate { 5297c478bd9Sstevel@tonic-gate return (parse_gids(&g_psexp.ps_rgids, arg)); 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate static int 5337c478bd9Sstevel@tonic-gate opt_ppid(char c, char *arg) 5347c478bd9Sstevel@tonic-gate { 5357c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_ppids, arg, 10, c, 0)); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate static int 5397c478bd9Sstevel@tonic-gate opt_pgrp(char c, char *arg) 5407c478bd9Sstevel@tonic-gate { 5417c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_pgids, arg, 10, c, getpgrp())); 5427c478bd9Sstevel@tonic-gate } 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate static int 5457c478bd9Sstevel@tonic-gate opt_sid(char c, char *arg) 5467c478bd9Sstevel@tonic-gate { 5477c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_sids, arg, 10, c, getsid(0))); 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5517c478bd9Sstevel@tonic-gate static int 5527c478bd9Sstevel@tonic-gate opt_term(char c, char *arg) 5537c478bd9Sstevel@tonic-gate { 5547c478bd9Sstevel@tonic-gate return (parse_ttys(&g_psexp.ps_ttys, arg)); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5587c478bd9Sstevel@tonic-gate static int 5597c478bd9Sstevel@tonic-gate opt_projid(char c, char *arg) 5607c478bd9Sstevel@tonic-gate { 5617c478bd9Sstevel@tonic-gate return (parse_projects(&g_psexp.ps_projids, arg)); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate static int 5657c478bd9Sstevel@tonic-gate opt_taskid(char c, char *arg) 5667c478bd9Sstevel@tonic-gate { 5677c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_taskids, arg, 10, c, gettaskid())); 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5717c478bd9Sstevel@tonic-gate static int 5727c478bd9Sstevel@tonic-gate opt_zoneid(char c, char *arg) 5737c478bd9Sstevel@tonic-gate { 5747c478bd9Sstevel@tonic-gate return (parse_zones(&g_psexp.ps_zoneids, arg)); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate static int 5787c478bd9Sstevel@tonic-gate opt_ctid(char c, char *arg) 5797c478bd9Sstevel@tonic-gate { 5807c478bd9Sstevel@tonic-gate return (parse_ids(&g_psexp.ps_ctids, arg, 10, c, getctid())); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate static void 5847c478bd9Sstevel@tonic-gate print_usage(FILE *stream) 5857c478bd9Sstevel@tonic-gate { 5867c478bd9Sstevel@tonic-gate if (g_flags & F_KILL) 5877c478bd9Sstevel@tonic-gate (void) fprintf(stream, gettext(PKILL_USAGE), g_pname); 5887c478bd9Sstevel@tonic-gate else 5897c478bd9Sstevel@tonic-gate (void) fprintf(stream, gettext(PGREP_USAGE), g_pname); 5907c478bd9Sstevel@tonic-gate } 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate int 5937c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 5947c478bd9Sstevel@tonic-gate { 5957c478bd9Sstevel@tonic-gate void (*funcp)(psinfo_t *); 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate const char *optstr; 5987c478bd9Sstevel@tonic-gate optdesc_t *optd; 5997c478bd9Sstevel@tonic-gate int nmatches, c; 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate DIR *dirp; 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 6047c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate UU_EXIT_FATAL = E_ERROR; 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate g_pname = uu_setpname(argv[0]); 6097c478bd9Sstevel@tonic-gate g_pid = getpid(); 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate psexp_create(&g_psexp); 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate if (strcmp(g_pname, "pkill") == 0) { 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate if (argc > 1 && argv[1][0] == '-' && 6167c478bd9Sstevel@tonic-gate str2sig(&argv[1][1], &g_signal) == 0) { 6177c478bd9Sstevel@tonic-gate argv[1] = argv[0]; 6187c478bd9Sstevel@tonic-gate argv++; 6197c478bd9Sstevel@tonic-gate argc--; 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate optstr = PKILL_OPTS; 6237c478bd9Sstevel@tonic-gate g_flags |= F_KILL; 6247c478bd9Sstevel@tonic-gate } else 6257c478bd9Sstevel@tonic-gate optstr = PGREP_OPTS; 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate opterr = 0; 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate while (optind < argc) { 6307c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, optstr)) != (int)EOF) { 6317c478bd9Sstevel@tonic-gate 632*e8d80663SEric Schrock if (c == ':' || c == '?' || 633*e8d80663SEric Schrock g_optdtab[c - 'A'].o_opts == 0) { 634*e8d80663SEric Schrock if (c == ':') { 635*e8d80663SEric Schrock uu_warn( 636*e8d80663SEric Schrock gettext("missing argument -- %c\n"), 637*e8d80663SEric Schrock optopt); 638*e8d80663SEric Schrock } else if (optopt != '?') { 6397c478bd9Sstevel@tonic-gate uu_warn( 6407c478bd9Sstevel@tonic-gate gettext("illegal option -- %c\n"), 6417c478bd9Sstevel@tonic-gate optopt); 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate print_usage(stderr); 6457c478bd9Sstevel@tonic-gate return (E_USAGE); 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate optd = &g_optdtab[c - 'A']; 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_SETB) 6517c478bd9Sstevel@tonic-gate *((ushort_t *)optd->o_ptr) |= optd->o_bits; 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_CLRB) 6547c478bd9Sstevel@tonic-gate *((ushort_t *)optd->o_ptr) &= ~optd->o_bits; 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_STR) 6577c478bd9Sstevel@tonic-gate *((char **)optd->o_ptr) = optarg; 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_CRIT) 6607c478bd9Sstevel@tonic-gate g_flags |= F_HAVE_CRIT; 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate if (optd->o_opts & OPT_FUNC) { 6637c478bd9Sstevel@tonic-gate if (optd->o_func(c, optarg) == -1) 6647c478bd9Sstevel@tonic-gate return (E_USAGE); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate if (optind < argc) { 6697c478bd9Sstevel@tonic-gate if (g_psexp.ps_pat != NULL) { 6707c478bd9Sstevel@tonic-gate uu_warn(gettext("illegal argument -- %s\n"), 6717c478bd9Sstevel@tonic-gate argv[optind]); 6727c478bd9Sstevel@tonic-gate print_usage(stderr); 6737c478bd9Sstevel@tonic-gate return (E_USAGE); 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate g_psexp.ps_pat = argv[optind++]; 6777c478bd9Sstevel@tonic-gate g_flags |= F_HAVE_CRIT; 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate if ((g_flags & F_NEWEST) && (g_flags & F_OLDEST)) { 6827c478bd9Sstevel@tonic-gate uu_warn(gettext("-n and -o are mutually exclusive\n")); 6837c478bd9Sstevel@tonic-gate print_usage(stderr); 6847c478bd9Sstevel@tonic-gate return (E_USAGE); 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate if ((g_flags & F_HAVE_CRIT) == 0) { 6887c478bd9Sstevel@tonic-gate uu_warn(gettext("No matching criteria specified\n")); 6897c478bd9Sstevel@tonic-gate print_usage(stderr); 6907c478bd9Sstevel@tonic-gate return (E_USAGE); 6917c478bd9Sstevel@tonic-gate } 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate if (psexp_compile(&g_psexp) == -1) { 6947c478bd9Sstevel@tonic-gate psexp_destroy(&g_psexp); 6957c478bd9Sstevel@tonic-gate return (E_USAGE); 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate if ((dirp = open_proc_dir(g_procdir)) == NULL) 6997c478bd9Sstevel@tonic-gate return (E_ERROR); 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate if (g_flags & F_KILL) 7027c478bd9Sstevel@tonic-gate funcp = kill_proc; 7037c478bd9Sstevel@tonic-gate else if (g_flags & F_LONG_OUT) 7047c478bd9Sstevel@tonic-gate funcp = print_proc_long; 7057c478bd9Sstevel@tonic-gate else 7067c478bd9Sstevel@tonic-gate funcp = print_proc; 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate nmatches = scan_proc_dir(g_procdir, dirp, &g_psexp, funcp); 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate if (g_flags & F_OUTPUT) 7117c478bd9Sstevel@tonic-gate (void) fputc('\n', stdout); 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate psexp_destroy(&g_psexp); 7147c478bd9Sstevel@tonic-gate return (nmatches ? E_MATCH : E_NOMATCH); 7157c478bd9Sstevel@tonic-gate } 716