10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
53235Sraf * Common Development and Distribution License (the "License").
63235Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
213235Sraf
220Sstevel@tonic-gate /*
23*12789SRoger.Faulkner@Oracle.COM * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
270Sstevel@tonic-gate /* All Rights Reserved */
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <stdio.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <unistd.h>
320Sstevel@tonic-gate #include <ctype.h>
330Sstevel@tonic-gate #include <string.h>
340Sstevel@tonic-gate #include <memory.h>
350Sstevel@tonic-gate #include <sys/types.h>
360Sstevel@tonic-gate #include <signal.h>
370Sstevel@tonic-gate #include <libproc.h>
380Sstevel@tonic-gate #include "ramdata.h"
390Sstevel@tonic-gate #include "systable.h"
400Sstevel@tonic-gate #include "proto.h"
410Sstevel@tonic-gate
420Sstevel@tonic-gate /* XXX A bug in the <string.h> header file requires this */
430Sstevel@tonic-gate extern char *strtok_r(char *s1, const char *s2, char **lasts);
440Sstevel@tonic-gate
450Sstevel@tonic-gate /*
460Sstevel@tonic-gate * option procesing ---
470Sstevel@tonic-gate * Routines for scanning syscall, signal, fault
480Sstevel@tonic-gate * and file descriptor lists.
490Sstevel@tonic-gate */
500Sstevel@tonic-gate
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate * Function prototypes for static routines in this module.
530Sstevel@tonic-gate */
540Sstevel@tonic-gate void upcase(char *);
550Sstevel@tonic-gate
560Sstevel@tonic-gate const char white[] = " \t\n"; /* white space characters */
570Sstevel@tonic-gate const char sepr[] = " ,\t\n"; /* list separator characters */
580Sstevel@tonic-gate const char csepr[] = " :,\t\n"; /* same, with ':' added */
590Sstevel@tonic-gate
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate * Scan list of syscall names.
620Sstevel@tonic-gate * Return 0 on success, != 0 on any failure.
630Sstevel@tonic-gate */
640Sstevel@tonic-gate int
syslist(char * str,sysset_t * setp,int * fp)650Sstevel@tonic-gate syslist(char *str, /* string of syscall names */
660Sstevel@tonic-gate sysset_t *setp, /* syscall set */
670Sstevel@tonic-gate int *fp) /* first-time flag */
680Sstevel@tonic-gate {
690Sstevel@tonic-gate char *name;
700Sstevel@tonic-gate int exclude = FALSE;
710Sstevel@tonic-gate int rc = 0;
720Sstevel@tonic-gate char *lasts;
730Sstevel@tonic-gate
740Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts);
750Sstevel@tonic-gate
760Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */
770Sstevel@tonic-gate exclude = TRUE;
780Sstevel@tonic-gate if (*++name == '\0')
790Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts);
800Sstevel@tonic-gate } else if (!*fp) { /* first time, clear the set */
810Sstevel@tonic-gate premptyset(setp);
820Sstevel@tonic-gate *fp = TRUE;
830Sstevel@tonic-gate }
840Sstevel@tonic-gate
850Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) {
860Sstevel@tonic-gate int sys;
870Sstevel@tonic-gate int sysx;
883235Sraf int sysxx;
890Sstevel@tonic-gate int sys64;
900Sstevel@tonic-gate char *next;
910Sstevel@tonic-gate
920Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */
930Sstevel@tonic-gate exclude = TRUE;
940Sstevel@tonic-gate while (*++name == '!')
950Sstevel@tonic-gate /* empty */;
960Sstevel@tonic-gate if (*name == '\0')
970Sstevel@tonic-gate continue;
980Sstevel@tonic-gate }
990Sstevel@tonic-gate
1000Sstevel@tonic-gate sys = strtol(name, &next, 0);
1013235Sraf sysx = sysxx = sys64 = 0;
1020Sstevel@tonic-gate if (sys < 0 || sys > PRMAXSYS || *next != '\0')
1030Sstevel@tonic-gate sys = 0;
1040Sstevel@tonic-gate if (sys == 0) {
1050Sstevel@tonic-gate const struct systable *stp = systable;
1060Sstevel@tonic-gate for (; sys == 0 && stp->nargs >= 0; stp++)
1070Sstevel@tonic-gate if (stp->name && strcmp(stp->name, name) == 0)
1080Sstevel@tonic-gate sys = stp-systable;
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate if (sys == 0) {
1110Sstevel@tonic-gate const struct sysalias *sap = sysalias;
1120Sstevel@tonic-gate for (; sys == 0 && sap->name; sap++)
1130Sstevel@tonic-gate if (strcmp(sap->name, name) == 0)
1140Sstevel@tonic-gate sys = sap->number;
1150Sstevel@tonic-gate }
1160Sstevel@tonic-gate if (sys > 0 && sys <= PRMAXSYS) {
1170Sstevel@tonic-gate switch (sys) {
11811798SRoger.Faulkner@Sun.COM case SYS_fstatat: /* set both if either */
11911798SRoger.Faulkner@Sun.COM case SYS_fstatat64:
12011798SRoger.Faulkner@Sun.COM sys = SYS_fstatat;
12111798SRoger.Faulkner@Sun.COM sys64 = SYS_fstatat64;
12211798SRoger.Faulkner@Sun.COM goto def;
12311798SRoger.Faulkner@Sun.COM
12411798SRoger.Faulkner@Sun.COM case SYS_stat: /* set all if either */
1250Sstevel@tonic-gate case SYS_stat64:
1260Sstevel@tonic-gate sys = SYS_stat;
1270Sstevel@tonic-gate sys64 = SYS_stat64;
12811798SRoger.Faulkner@Sun.COM sysx = SYS_fstatat;
12911798SRoger.Faulkner@Sun.COM sysxx = SYS_fstatat64;
1300Sstevel@tonic-gate goto def;
1310Sstevel@tonic-gate
13211798SRoger.Faulkner@Sun.COM case SYS_lstat: /* set all if either */
1330Sstevel@tonic-gate case SYS_lstat64:
1340Sstevel@tonic-gate sys = SYS_lstat;
1350Sstevel@tonic-gate sys64 = SYS_lstat64;
13611798SRoger.Faulkner@Sun.COM sysx = SYS_fstatat;
13711798SRoger.Faulkner@Sun.COM sysxx = SYS_fstatat64;
1380Sstevel@tonic-gate goto def;
1390Sstevel@tonic-gate
14011798SRoger.Faulkner@Sun.COM case SYS_fstat: /* set all if either */
1410Sstevel@tonic-gate case SYS_fstat64:
1420Sstevel@tonic-gate sys = SYS_fstat;
1430Sstevel@tonic-gate sys64 = SYS_fstat64;
14411798SRoger.Faulkner@Sun.COM sysx = SYS_fstatat;
14511798SRoger.Faulkner@Sun.COM sysxx = SYS_fstatat64;
1460Sstevel@tonic-gate goto def;
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate case SYS_getdents: /* set both if either */
1490Sstevel@tonic-gate case SYS_getdents64:
1500Sstevel@tonic-gate sys = SYS_getdents;
1510Sstevel@tonic-gate sys64 = SYS_getdents64;
1520Sstevel@tonic-gate goto def;
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate case SYS_mmap: /* set both if either */
1550Sstevel@tonic-gate case SYS_mmap64:
1560Sstevel@tonic-gate sys = SYS_mmap;
1570Sstevel@tonic-gate sys64 = SYS_mmap64;
1580Sstevel@tonic-gate goto def;
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate case SYS_statvfs: /* set both if either */
1610Sstevel@tonic-gate case SYS_statvfs64:
1620Sstevel@tonic-gate sys = SYS_statvfs;
1630Sstevel@tonic-gate sys64 = SYS_statvfs64;
1640Sstevel@tonic-gate goto def;
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate case SYS_fstatvfs: /* set both if either */
1670Sstevel@tonic-gate case SYS_fstatvfs64:
1680Sstevel@tonic-gate sys = SYS_fstatvfs;
1690Sstevel@tonic-gate sys64 = SYS_fstatvfs64;
1700Sstevel@tonic-gate goto def;
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate case SYS_setrlimit: /* set both if either */
1730Sstevel@tonic-gate case SYS_setrlimit64:
1740Sstevel@tonic-gate sys = SYS_setrlimit;
1750Sstevel@tonic-gate sys64 = SYS_setrlimit64;
1760Sstevel@tonic-gate goto def;
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate case SYS_getrlimit: /* set both if either */
1790Sstevel@tonic-gate case SYS_getrlimit64:
1800Sstevel@tonic-gate sys = SYS_getrlimit;
1810Sstevel@tonic-gate sys64 = SYS_getrlimit64;
1820Sstevel@tonic-gate goto def;
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate case SYS_pread: /* set both if either */
1850Sstevel@tonic-gate case SYS_pread64:
1860Sstevel@tonic-gate sys = SYS_pread;
1870Sstevel@tonic-gate sys64 = SYS_pread64;
1880Sstevel@tonic-gate goto def;
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate case SYS_pwrite: /* set both if either */
1910Sstevel@tonic-gate case SYS_pwrite64:
1920Sstevel@tonic-gate sys = SYS_pwrite;
1930Sstevel@tonic-gate sys64 = SYS_pwrite64;
1940Sstevel@tonic-gate goto def;
1950Sstevel@tonic-gate
19611798SRoger.Faulkner@Sun.COM case SYS_openat: /* set all if any */
19711798SRoger.Faulkner@Sun.COM case SYS_openat64:
19811798SRoger.Faulkner@Sun.COM case SYS_open:
1990Sstevel@tonic-gate case SYS_open64:
20011798SRoger.Faulkner@Sun.COM sys = SYS_openat;
20111798SRoger.Faulkner@Sun.COM sys64 = SYS_openat64;
20211798SRoger.Faulkner@Sun.COM sysx = SYS_open;
20311798SRoger.Faulkner@Sun.COM sysxx = SYS_open64;
2040Sstevel@tonic-gate goto def;
2050Sstevel@tonic-gate
20611798SRoger.Faulkner@Sun.COM case SYS_forksys: /* set both if either */
2070Sstevel@tonic-gate case SYS_vfork:
20811798SRoger.Faulkner@Sun.COM sysx = SYS_forksys;
20911798SRoger.Faulkner@Sun.COM sys = SYS_vfork;
2100Sstevel@tonic-gate goto def;
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate case SYS_sigprocmask: /* set both if either */
2130Sstevel@tonic-gate case SYS_lwp_sigmask:
2140Sstevel@tonic-gate sysx = SYS_sigprocmask;
2150Sstevel@tonic-gate sys = SYS_lwp_sigmask;
2160Sstevel@tonic-gate goto def;
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate case SYS_lseek: /* set both if either */
2190Sstevel@tonic-gate case SYS_llseek:
2200Sstevel@tonic-gate sysx = SYS_lseek;
2210Sstevel@tonic-gate sys = SYS_llseek;
2220Sstevel@tonic-gate goto def;
2230Sstevel@tonic-gate
22411798SRoger.Faulkner@Sun.COM case SYS_rename: /* set both */
22511798SRoger.Faulkner@Sun.COM sysx = SYS_renameat;
22611798SRoger.Faulkner@Sun.COM goto def;
22711798SRoger.Faulkner@Sun.COM
228*12789SRoger.Faulkner@Oracle.COM case SYS_link: /* set both */
229*12789SRoger.Faulkner@Oracle.COM sysx = SYS_linkat;
23011798SRoger.Faulkner@Sun.COM goto def;
23111798SRoger.Faulkner@Sun.COM
232*12789SRoger.Faulkner@Oracle.COM case SYS_unlink: /* set both */
23311798SRoger.Faulkner@Sun.COM case SYS_rmdir: /* set both */
23411798SRoger.Faulkner@Sun.COM sysx = SYS_unlinkat;
2350Sstevel@tonic-gate goto def;
2360Sstevel@tonic-gate
237*12789SRoger.Faulkner@Oracle.COM case SYS_symlink: /* set both */
238*12789SRoger.Faulkner@Oracle.COM sysx = SYS_symlinkat;
239*12789SRoger.Faulkner@Oracle.COM goto def;
240*12789SRoger.Faulkner@Oracle.COM
241*12789SRoger.Faulkner@Oracle.COM case SYS_readlink: /* set both */
242*12789SRoger.Faulkner@Oracle.COM sysx = SYS_readlinkat;
243*12789SRoger.Faulkner@Oracle.COM goto def;
244*12789SRoger.Faulkner@Oracle.COM
245*12789SRoger.Faulkner@Oracle.COM case SYS_chmod: /* set both */
246*12789SRoger.Faulkner@Oracle.COM case SYS_fchmod: /* set both */
247*12789SRoger.Faulkner@Oracle.COM sysx = SYS_fchmodat;
248*12789SRoger.Faulkner@Oracle.COM goto def;
249*12789SRoger.Faulkner@Oracle.COM
25011798SRoger.Faulkner@Sun.COM case SYS_chown: /* set both */
251*12789SRoger.Faulkner@Oracle.COM case SYS_lchown: /* set both */
252*12789SRoger.Faulkner@Oracle.COM case SYS_fchown: /* set both */
25311798SRoger.Faulkner@Sun.COM sysx = SYS_fchownat;
25411798SRoger.Faulkner@Sun.COM goto def;
25511798SRoger.Faulkner@Sun.COM
256*12789SRoger.Faulkner@Oracle.COM case SYS_mkdir: /* set both */
257*12789SRoger.Faulkner@Oracle.COM sysx = SYS_mkdirat;
25811798SRoger.Faulkner@Sun.COM goto def;
25911798SRoger.Faulkner@Sun.COM
260*12789SRoger.Faulkner@Oracle.COM case SYS_mknod: /* set both */
261*12789SRoger.Faulkner@Oracle.COM sysx = SYS_mknodat;
26211798SRoger.Faulkner@Sun.COM goto def;
26311798SRoger.Faulkner@Sun.COM
26411798SRoger.Faulkner@Sun.COM case SYS_access: /* set both */
26511798SRoger.Faulkner@Sun.COM sysx = SYS_faccessat;
2660Sstevel@tonic-gate goto def;
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate default:
2690Sstevel@tonic-gate def:
2700Sstevel@tonic-gate if (exclude) {
2710Sstevel@tonic-gate prdelset(setp, sys);
2720Sstevel@tonic-gate if (sysx)
2730Sstevel@tonic-gate prdelset(setp, sysx);
2743235Sraf if (sysxx)
2753235Sraf prdelset(setp, sysxx);
2760Sstevel@tonic-gate if (sys64)
2770Sstevel@tonic-gate prdelset(setp, sys64);
2780Sstevel@tonic-gate } else {
2790Sstevel@tonic-gate praddset(setp, sys);
2800Sstevel@tonic-gate if (sysx)
2810Sstevel@tonic-gate praddset(setp, sysx);
2823235Sraf if (sysxx)
2833235Sraf praddset(setp, sysxx);
2840Sstevel@tonic-gate if (sys64)
2850Sstevel@tonic-gate praddset(setp, sys64);
2860Sstevel@tonic-gate }
2870Sstevel@tonic-gate break;
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate } else if (strcmp(name, "all") == 0 ||
2900Sstevel@tonic-gate strcmp(name, "ALL") == 0) {
2910Sstevel@tonic-gate if (exclude) {
2920Sstevel@tonic-gate premptyset(setp);
2930Sstevel@tonic-gate } else {
2940Sstevel@tonic-gate prfillset(setp);
2950Sstevel@tonic-gate }
2960Sstevel@tonic-gate } else {
2970Sstevel@tonic-gate (void) fprintf(stderr,
2985891Sraf "%s: unrecognized syscall: %s\n",
2995891Sraf command, name);
3000Sstevel@tonic-gate rc = -1;
3010Sstevel@tonic-gate }
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate
3040Sstevel@tonic-gate return (rc);
3050Sstevel@tonic-gate }
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate /*
3080Sstevel@tonic-gate * List of signals to trace.
3090Sstevel@tonic-gate * Return 0 on success, != 0 on any failure.
3100Sstevel@tonic-gate */
3110Sstevel@tonic-gate int
siglist(private_t * pri,char * str,sigset_t * setp,int * fp)3120Sstevel@tonic-gate siglist(private_t *pri,
3130Sstevel@tonic-gate char *str, /* string of signal names */
3140Sstevel@tonic-gate sigset_t *setp, /* signal set */
3150Sstevel@tonic-gate int *fp) /* first-time flag */
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate char *name;
3180Sstevel@tonic-gate int exclude = FALSE;
3190Sstevel@tonic-gate int rc = 0;
3200Sstevel@tonic-gate char *lasts;
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate upcase(str);
3230Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts);
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */
3260Sstevel@tonic-gate exclude = TRUE;
3270Sstevel@tonic-gate if (*++name == '\0')
3280Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts);
3290Sstevel@tonic-gate } else if (!*fp) { /* first time, clear the set */
3300Sstevel@tonic-gate premptyset(setp);
3310Sstevel@tonic-gate *fp = TRUE;
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) {
3350Sstevel@tonic-gate int sig;
3360Sstevel@tonic-gate char *next;
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */
3390Sstevel@tonic-gate exclude = TRUE;
3400Sstevel@tonic-gate while (*++name == '!')
3410Sstevel@tonic-gate /* empty */;
3420Sstevel@tonic-gate if (*name == '\0')
3430Sstevel@tonic-gate continue;
3440Sstevel@tonic-gate }
3450Sstevel@tonic-gate
3460Sstevel@tonic-gate sig = strtol(name, &next, 0);
3470Sstevel@tonic-gate if (sig <= 0 || sig > PRMAXSIG || *next != '\0') {
3480Sstevel@tonic-gate for (sig = 1; sig <= PRMAXSIG; sig++) {
3490Sstevel@tonic-gate const char *sname = rawsigname(pri, sig);
3500Sstevel@tonic-gate if (sname == NULL)
3510Sstevel@tonic-gate continue;
3520Sstevel@tonic-gate if (strcmp(sname, name) == 0 ||
3530Sstevel@tonic-gate strcmp(sname+3, name) == 0)
3540Sstevel@tonic-gate break;
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate if (sig > PRMAXSIG)
3570Sstevel@tonic-gate sig = 0;
3580Sstevel@tonic-gate }
3590Sstevel@tonic-gate if (sig > 0 && sig <= PRMAXSIG) {
3600Sstevel@tonic-gate if (exclude) {
3610Sstevel@tonic-gate prdelset(setp, sig);
3620Sstevel@tonic-gate } else {
3630Sstevel@tonic-gate praddset(setp, sig);
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate } else if (strcmp(name, "ALL") == 0) {
3660Sstevel@tonic-gate if (exclude) {
3670Sstevel@tonic-gate premptyset(setp);
3680Sstevel@tonic-gate } else {
3690Sstevel@tonic-gate prfillset(setp);
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate } else {
3720Sstevel@tonic-gate (void) fprintf(stderr,
3735891Sraf "%s: unrecognized signal name/number: %s\n",
3745891Sraf command, name);
3750Sstevel@tonic-gate rc = -1;
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate return (rc);
3800Sstevel@tonic-gate }
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate /*
3830Sstevel@tonic-gate * List of faults to trace.
3840Sstevel@tonic-gate * return 0 on success, != 0 on any failure.
3850Sstevel@tonic-gate */
3860Sstevel@tonic-gate int
fltlist(char * str,fltset_t * setp,int * fp)3870Sstevel@tonic-gate fltlist(char *str, /* string of fault names */
3880Sstevel@tonic-gate fltset_t *setp, /* fault set */
3890Sstevel@tonic-gate int *fp) /* first-time flag */
3900Sstevel@tonic-gate {
3910Sstevel@tonic-gate char *name;
3920Sstevel@tonic-gate int exclude = FALSE;
3930Sstevel@tonic-gate int rc = 0;
3940Sstevel@tonic-gate char *lasts;
3950Sstevel@tonic-gate
3960Sstevel@tonic-gate upcase(str);
3970Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts);
3980Sstevel@tonic-gate
3990Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */
4000Sstevel@tonic-gate exclude = TRUE;
4010Sstevel@tonic-gate if (*++name == '\0')
4020Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts);
4030Sstevel@tonic-gate } else if (!*fp) { /* first time, clear the set */
4040Sstevel@tonic-gate premptyset(setp);
4050Sstevel@tonic-gate *fp = TRUE;
4060Sstevel@tonic-gate }
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) {
4090Sstevel@tonic-gate int flt;
4100Sstevel@tonic-gate char *next;
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */
4130Sstevel@tonic-gate exclude = TRUE;
4140Sstevel@tonic-gate while (*++name == '!')
4150Sstevel@tonic-gate /* empty */;
4160Sstevel@tonic-gate if (*name == '\0')
4170Sstevel@tonic-gate continue;
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate
4200Sstevel@tonic-gate flt = strtol(name, &next, 0);
4210Sstevel@tonic-gate if (flt <= 0 || flt > PRMAXFAULT || *next != '\0') {
4220Sstevel@tonic-gate for (flt = 1; flt <= PRMAXFAULT; flt++) {
4230Sstevel@tonic-gate char fname[32];
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate if (proc_fltname(flt, fname,
4260Sstevel@tonic-gate sizeof (fname)) == NULL)
4270Sstevel@tonic-gate continue;
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate if (strcmp(fname, name) == 0 ||
4300Sstevel@tonic-gate strcmp(fname+3, name) == 0)
4310Sstevel@tonic-gate break;
4320Sstevel@tonic-gate }
4330Sstevel@tonic-gate if (flt > PRMAXFAULT)
4340Sstevel@tonic-gate flt = 0;
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate if (flt > 0 && flt <= PRMAXFAULT) {
4370Sstevel@tonic-gate if (exclude) {
4380Sstevel@tonic-gate prdelset(setp, flt);
4390Sstevel@tonic-gate } else {
4400Sstevel@tonic-gate praddset(setp, flt);
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate } else if (strcmp(name, "ALL") == 0) {
4430Sstevel@tonic-gate if (exclude) {
4440Sstevel@tonic-gate premptyset(setp);
4450Sstevel@tonic-gate } else {
4460Sstevel@tonic-gate prfillset(setp);
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate } else {
4490Sstevel@tonic-gate (void) fprintf(stderr,
4505891Sraf "%s: unrecognized fault name/number: %s\n",
4515891Sraf command, name);
4520Sstevel@tonic-gate rc = -1;
4530Sstevel@tonic-gate }
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate return (rc);
4570Sstevel@tonic-gate }
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate /*
4600Sstevel@tonic-gate * Gather file descriptors to dump.
4610Sstevel@tonic-gate * Return 0 on success, != 0 on any failure.
4620Sstevel@tonic-gate */
4630Sstevel@tonic-gate int
fdlist(char * str,fileset_t * setp)4640Sstevel@tonic-gate fdlist(char *str, /* string of filedescriptors */
4650Sstevel@tonic-gate fileset_t *setp) /* set of boolean flags */
4660Sstevel@tonic-gate {
4670Sstevel@tonic-gate char *name;
4680Sstevel@tonic-gate int exclude = FALSE;
4690Sstevel@tonic-gate int rc = 0;
4700Sstevel@tonic-gate char *lasts;
4710Sstevel@tonic-gate
4720Sstevel@tonic-gate upcase(str);
4730Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts);
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */
4760Sstevel@tonic-gate exclude = TRUE;
4770Sstevel@tonic-gate if (*++name == '\0')
4780Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts);
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) {
4820Sstevel@tonic-gate int fd;
4830Sstevel@tonic-gate char *next;
4840Sstevel@tonic-gate
4850Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */
4860Sstevel@tonic-gate exclude = TRUE;
4870Sstevel@tonic-gate while (*++name == '!')
4880Sstevel@tonic-gate /* empty */;
4890Sstevel@tonic-gate if (*name == '\0')
4900Sstevel@tonic-gate continue;
4910Sstevel@tonic-gate }
4920Sstevel@tonic-gate
4930Sstevel@tonic-gate fd = strtol(name, &next, 0);
4940Sstevel@tonic-gate if (fd >= 0 && fd < NOFILES_MAX && *next == '\0') {
4950Sstevel@tonic-gate fd++;
4960Sstevel@tonic-gate if (exclude) {
4970Sstevel@tonic-gate prdelset(setp, fd);
4980Sstevel@tonic-gate } else {
4990Sstevel@tonic-gate praddset(setp, fd);
5000Sstevel@tonic-gate }
5010Sstevel@tonic-gate } else if (strcmp(name, "ALL") == 0) {
5020Sstevel@tonic-gate if (exclude) {
5030Sstevel@tonic-gate premptyset(setp);
5040Sstevel@tonic-gate } else {
5050Sstevel@tonic-gate prfillset(setp);
5060Sstevel@tonic-gate }
5070Sstevel@tonic-gate } else {
5080Sstevel@tonic-gate (void) fprintf(stderr,
5095891Sraf "%s: filedescriptor not in range[0..%d]: %s\n",
5105891Sraf command, NOFILES_MAX-1, name);
5110Sstevel@tonic-gate rc = -1;
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate }
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate return (rc);
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate void
upcase(char * str)5190Sstevel@tonic-gate upcase(char *str)
5200Sstevel@tonic-gate {
5210Sstevel@tonic-gate int c;
5220Sstevel@tonic-gate
5230Sstevel@tonic-gate while ((c = *str) != '\0')
5240Sstevel@tonic-gate *str++ = toupper(c);
5250Sstevel@tonic-gate }
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate /*
5280Sstevel@tonic-gate * 'arg' points to a string like:
5290Sstevel@tonic-gate * libc,libnsl,... : printf,read,write,...
5300Sstevel@tonic-gate * or
5310Sstevel@tonic-gate * libc,libnsl,... :: printf,read,write,...
5320Sstevel@tonic-gate * with possible filename pattern-matching metacharacters.
5330Sstevel@tonic-gate *
5340Sstevel@tonic-gate * Assumption: No library or function name can contain ',' or ':'.
5350Sstevel@tonic-gate */
5360Sstevel@tonic-gate int
liblist(char * arg,int hang)5370Sstevel@tonic-gate liblist(char *arg, int hang)
5380Sstevel@tonic-gate {
5390Sstevel@tonic-gate const char *star = "*";
5400Sstevel@tonic-gate struct dynpat *Dyp;
5410Sstevel@tonic-gate char *pat;
5420Sstevel@tonic-gate char *fpat;
5430Sstevel@tonic-gate char *lasts;
5440Sstevel@tonic-gate uint_t maxpat;
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate /* append a new dynpat structure to the end of the Dynpat list */
5470Sstevel@tonic-gate Dyp = my_malloc(sizeof (struct dynpat), NULL);
5480Sstevel@tonic-gate Dyp->next = NULL;
5490Sstevel@tonic-gate if (Lastpat == NULL)
5500Sstevel@tonic-gate Dynpat = Lastpat = Dyp;
5510Sstevel@tonic-gate else {
5520Sstevel@tonic-gate Lastpat->next = Dyp;
5530Sstevel@tonic-gate Lastpat = Dyp;
5540Sstevel@tonic-gate }
5550Sstevel@tonic-gate Dyp->flag = hang? BPT_HANG : 0;
5560Sstevel@tonic-gate Dyp->exclude_lib = 0;
5570Sstevel@tonic-gate Dyp->exclude = 0;
5580Sstevel@tonic-gate Dyp->internal = 0;
5590Sstevel@tonic-gate Dyp->Dp = NULL;
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate /*
5620Sstevel@tonic-gate * Find the beginning of the filename patterns
5630Sstevel@tonic-gate * and null-terminate the library name patterns.
5640Sstevel@tonic-gate */
5650Sstevel@tonic-gate if ((fpat = strchr(arg, ':')) != NULL)
5660Sstevel@tonic-gate *fpat++ = '\0';
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate /*
5690Sstevel@tonic-gate * Library name patterns.
5700Sstevel@tonic-gate */
5710Sstevel@tonic-gate pat = strtok_r(arg, sepr, &lasts);
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate /* '!' introduces an exclusion list */
5740Sstevel@tonic-gate if (pat != NULL && *pat == '!') {
5750Sstevel@tonic-gate Dyp->exclude_lib = 1;
5760Sstevel@tonic-gate pat += strspn(pat, "!");
5770Sstevel@tonic-gate if (*pat == '\0')
5780Sstevel@tonic-gate pat = strtok_r(NULL, sepr, &lasts);
5790Sstevel@tonic-gate /* force exclusion of all functions as well */
5800Sstevel@tonic-gate Dyp->exclude = 1;
5810Sstevel@tonic-gate Dyp->internal = 1;
5820Sstevel@tonic-gate fpat = NULL;
5830Sstevel@tonic-gate }
5840Sstevel@tonic-gate
5850Sstevel@tonic-gate if (pat == NULL) {
5860Sstevel@tonic-gate /* empty list means all libraries */
5870Sstevel@tonic-gate Dyp->libpat = my_malloc(sizeof (char *), NULL);
5880Sstevel@tonic-gate Dyp->libpat[0] = star;
5890Sstevel@tonic-gate Dyp->nlibpat = 1;
5900Sstevel@tonic-gate } else {
5910Sstevel@tonic-gate /*
5920Sstevel@tonic-gate * We are now at the library list.
5930Sstevel@tonic-gate * Generate the list and count the library name patterns.
5940Sstevel@tonic-gate */
5950Sstevel@tonic-gate maxpat = 1;
5960Sstevel@tonic-gate Dyp->libpat = my_malloc(maxpat * sizeof (char *), NULL);
5970Sstevel@tonic-gate Dyp->nlibpat = 0;
5980Sstevel@tonic-gate Dyp->libpat[Dyp->nlibpat++] = pat;
5990Sstevel@tonic-gate while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) {
6000Sstevel@tonic-gate if (Dyp->nlibpat == maxpat) {
6010Sstevel@tonic-gate maxpat *= 2;
6020Sstevel@tonic-gate Dyp->libpat = my_realloc(Dyp->libpat,
6035891Sraf maxpat * sizeof (char *), NULL);
6040Sstevel@tonic-gate }
6050Sstevel@tonic-gate Dyp->libpat[Dyp->nlibpat++] = pat;
6060Sstevel@tonic-gate }
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate /*
6100Sstevel@tonic-gate * Function name patterns.
6110Sstevel@tonic-gate */
6120Sstevel@tonic-gate if (fpat == NULL)
6130Sstevel@tonic-gate pat = NULL;
6140Sstevel@tonic-gate else {
6150Sstevel@tonic-gate /*
6160Sstevel@tonic-gate * We have already seen a ':'. Look for another.
6170Sstevel@tonic-gate * Double ':' means trace internal calls.
6180Sstevel@tonic-gate */
6190Sstevel@tonic-gate fpat += strspn(fpat, white);
6200Sstevel@tonic-gate if (*fpat == ':') {
6210Sstevel@tonic-gate Dyp->internal = 1;
6220Sstevel@tonic-gate *fpat++ = '\0';
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate pat = strtok_r(fpat, csepr, &lasts);
6250Sstevel@tonic-gate }
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate /* '!' introduces an exclusion list */
6280Sstevel@tonic-gate if (pat != NULL && *pat == '!') {
6290Sstevel@tonic-gate Dyp->exclude = 1;
6300Sstevel@tonic-gate Dyp->internal = 1;
6310Sstevel@tonic-gate pat += strspn(pat, "!");
6320Sstevel@tonic-gate if (*pat == '\0')
6330Sstevel@tonic-gate pat = strtok_r(NULL, sepr, &lasts);
6340Sstevel@tonic-gate }
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate if (pat == NULL) {
6370Sstevel@tonic-gate /* empty function list means exclude all functions */
6380Sstevel@tonic-gate Dyp->sympat = my_malloc(sizeof (char *), NULL);
6390Sstevel@tonic-gate Dyp->sympat[0] = star;
6400Sstevel@tonic-gate Dyp->nsympat = 1;
6410Sstevel@tonic-gate } else {
6420Sstevel@tonic-gate /*
6430Sstevel@tonic-gate * We are now at the function list.
6440Sstevel@tonic-gate * Generate the list and count the symbol name patterns.
6450Sstevel@tonic-gate */
6460Sstevel@tonic-gate maxpat = 1;
6470Sstevel@tonic-gate Dyp->sympat = my_malloc(maxpat * sizeof (char *), NULL);
6480Sstevel@tonic-gate Dyp->nsympat = 0;
6490Sstevel@tonic-gate Dyp->sympat[Dyp->nsympat++] = pat;
6500Sstevel@tonic-gate while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) {
6510Sstevel@tonic-gate if (Dyp->nsympat == maxpat) {
6520Sstevel@tonic-gate maxpat *= 2;
6530Sstevel@tonic-gate Dyp->sympat = my_realloc(Dyp->sympat,
6545891Sraf maxpat * sizeof (char *), NULL);
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate Dyp->sympat[Dyp->nsympat++] = pat;
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate }
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate return (0);
6610Sstevel@tonic-gate }
662