#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <memory.h>
#include <sys/types.h>
#include <signal.h>
#include <libproc.h>
#include "ramdata.h"
#include "systable.h"
#include "proto.h"
extern char *strtok_r(char *s1, const char *s2, char **lasts);
void upcase(char *);
const char white[] = " \t\n";
const char sepr[] = " ,\t\n";
const char csepr[] = " :,\t\n";
int
syslist(char *str,
sysset_t *setp,
int *fp)
{
char *name;
int exclude = FALSE;
int rc = 0;
char *lasts;
name = strtok_r(str, sepr, &lasts);
if (name != NULL && *name == '!') {
exclude = TRUE;
if (*++name == '\0')
name = strtok_r(NULL, sepr, &lasts);
} else if (!*fp) {
premptyset(setp);
*fp = TRUE;
}
for (; name; name = strtok_r(NULL, sepr, &lasts)) {
int sys;
int sysx;
int sysxx;
int sys64;
char *next;
if (*name == '!') {
exclude = TRUE;
while (*++name == '!')
;
if (*name == '\0')
continue;
}
sys = strtol(name, &next, 0);
sysx = sysxx = sys64 = 0;
if (sys < 0 || sys > PRMAXSYS || *next != '\0')
sys = 0;
if (sys == 0) {
const struct systable *stp = systable;
for (; sys == 0 && stp->nargs >= 0; stp++)
if (stp->name && strcmp(stp->name, name) == 0)
sys = stp-systable;
}
if (sys == 0) {
const struct sysalias *sap = sysalias;
for (; sys == 0 && sap->name; sap++)
if (strcmp(sap->name, name) == 0)
sys = sap->number;
}
if (sys > 0 && sys <= PRMAXSYS) {
switch (sys) {
case SYS_fstatat:
case SYS_fstatat64:
sys = SYS_fstatat;
sys64 = SYS_fstatat64;
goto def;
case SYS_stat:
case SYS_stat64:
sys = SYS_stat;
sys64 = SYS_stat64;
sysx = SYS_fstatat;
sysxx = SYS_fstatat64;
goto def;
case SYS_lstat:
case SYS_lstat64:
sys = SYS_lstat;
sys64 = SYS_lstat64;
sysx = SYS_fstatat;
sysxx = SYS_fstatat64;
goto def;
case SYS_fstat:
case SYS_fstat64:
sys = SYS_fstat;
sys64 = SYS_fstat64;
sysx = SYS_fstatat;
sysxx = SYS_fstatat64;
goto def;
case SYS_getdents:
case SYS_getdents64:
sys = SYS_getdents;
sys64 = SYS_getdents64;
goto def;
case SYS_mmap:
case SYS_mmap64:
sys = SYS_mmap;
sys64 = SYS_mmap64;
goto def;
case SYS_statvfs:
case SYS_statvfs64:
sys = SYS_statvfs;
sys64 = SYS_statvfs64;
goto def;
case SYS_fstatvfs:
case SYS_fstatvfs64:
sys = SYS_fstatvfs;
sys64 = SYS_fstatvfs64;
goto def;
case SYS_setrlimit:
case SYS_setrlimit64:
sys = SYS_setrlimit;
sys64 = SYS_setrlimit64;
goto def;
case SYS_getrlimit:
case SYS_getrlimit64:
sys = SYS_getrlimit;
sys64 = SYS_getrlimit64;
goto def;
case SYS_pread:
case SYS_pread64:
sys = SYS_pread;
sys64 = SYS_pread64;
goto def;
case SYS_pwrite:
case SYS_pwrite64:
sys = SYS_pwrite;
sys64 = SYS_pwrite64;
goto def;
case SYS_openat:
case SYS_openat64:
case SYS_open:
case SYS_open64:
sys = SYS_openat;
sys64 = SYS_openat64;
sysx = SYS_open;
sysxx = SYS_open64;
goto def;
case SYS_forksys:
case SYS_vfork:
sysx = SYS_forksys;
sys = SYS_vfork;
goto def;
case SYS_sigprocmask:
case SYS_lwp_sigmask:
sysx = SYS_sigprocmask;
sys = SYS_lwp_sigmask;
goto def;
case SYS_lseek:
case SYS_llseek:
sysx = SYS_lseek;
sys = SYS_llseek;
goto def;
case SYS_rename:
sysx = SYS_renameat;
goto def;
case SYS_link:
sysx = SYS_linkat;
goto def;
case SYS_unlink:
case SYS_rmdir:
sysx = SYS_unlinkat;
goto def;
case SYS_symlink:
sysx = SYS_symlinkat;
goto def;
case SYS_readlink:
sysx = SYS_readlinkat;
goto def;
case SYS_chmod:
case SYS_fchmod:
sysx = SYS_fchmodat;
goto def;
case SYS_chown:
case SYS_lchown:
case SYS_fchown:
sysx = SYS_fchownat;
goto def;
case SYS_mkdir:
sysx = SYS_mkdirat;
goto def;
case SYS_mknod:
sysx = SYS_mknodat;
goto def;
case SYS_access:
sysx = SYS_faccessat;
goto def;
default:
def:
if (exclude) {
prdelset(setp, sys);
if (sysx)
prdelset(setp, sysx);
if (sysxx)
prdelset(setp, sysxx);
if (sys64)
prdelset(setp, sys64);
} else {
praddset(setp, sys);
if (sysx)
praddset(setp, sysx);
if (sysxx)
praddset(setp, sysxx);
if (sys64)
praddset(setp, sys64);
}
break;
}
} else if (strcmp(name, "all") == 0 ||
strcmp(name, "ALL") == 0) {
if (exclude) {
premptyset(setp);
} else {
prfillset(setp);
}
} else {
(void) fprintf(stderr,
"%s: unrecognized syscall: %s\n",
command, name);
rc = -1;
}
}
return (rc);
}
int
siglist(private_t *pri,
char *str,
sigset_t *setp,
int *fp)
{
char *name;
int exclude = FALSE;
int rc = 0;
char *lasts;
upcase(str);
name = strtok_r(str, sepr, &lasts);
if (name != NULL && *name == '!') {
exclude = TRUE;
if (*++name == '\0')
name = strtok_r(NULL, sepr, &lasts);
} else if (!*fp) {
premptyset(setp);
*fp = TRUE;
}
for (; name; name = strtok_r(NULL, sepr, &lasts)) {
int sig;
char *next;
if (*name == '!') {
exclude = TRUE;
while (*++name == '!')
;
if (*name == '\0')
continue;
}
sig = strtol(name, &next, 0);
if (sig <= 0 || sig > PRMAXSIG || *next != '\0') {
for (sig = 1; sig <= PRMAXSIG; sig++) {
const char *sname = rawsigname(pri, sig);
if (sname == NULL)
continue;
if (strcmp(sname, name) == 0 ||
strcmp(sname+3, name) == 0)
break;
}
if (sig > PRMAXSIG)
sig = 0;
}
if (sig > 0 && sig <= PRMAXSIG) {
if (exclude) {
prdelset(setp, sig);
} else {
praddset(setp, sig);
}
} else if (strcmp(name, "ALL") == 0) {
if (exclude) {
premptyset(setp);
} else {
prfillset(setp);
}
} else {
(void) fprintf(stderr,
"%s: unrecognized signal name/number: %s\n",
command, name);
rc = -1;
}
}
return (rc);
}
int
fltlist(char *str,
fltset_t *setp,
int *fp)
{
char *name;
int exclude = FALSE;
int rc = 0;
char *lasts;
upcase(str);
name = strtok_r(str, sepr, &lasts);
if (name != NULL && *name == '!') {
exclude = TRUE;
if (*++name == '\0')
name = strtok_r(NULL, sepr, &lasts);
} else if (!*fp) {
premptyset(setp);
*fp = TRUE;
}
for (; name; name = strtok_r(NULL, sepr, &lasts)) {
int flt;
char *next;
if (*name == '!') {
exclude = TRUE;
while (*++name == '!')
;
if (*name == '\0')
continue;
}
flt = strtol(name, &next, 0);
if (flt <= 0 || flt > PRMAXFAULT || *next != '\0') {
for (flt = 1; flt <= PRMAXFAULT; flt++) {
char fname[32];
if (proc_fltname(flt, fname,
sizeof (fname)) == NULL)
continue;
if (strcmp(fname, name) == 0 ||
strcmp(fname+3, name) == 0)
break;
}
if (flt > PRMAXFAULT)
flt = 0;
}
if (flt > 0 && flt <= PRMAXFAULT) {
if (exclude) {
prdelset(setp, flt);
} else {
praddset(setp, flt);
}
} else if (strcmp(name, "ALL") == 0) {
if (exclude) {
premptyset(setp);
} else {
prfillset(setp);
}
} else {
(void) fprintf(stderr,
"%s: unrecognized fault name/number: %s\n",
command, name);
rc = -1;
}
}
return (rc);
}
int
fdlist(char *str,
fileset_t *setp)
{
char *name;
int exclude = FALSE;
int rc = 0;
char *lasts;
upcase(str);
name = strtok_r(str, sepr, &lasts);
if (name != NULL && *name == '!') {
exclude = TRUE;
if (*++name == '\0')
name = strtok_r(NULL, sepr, &lasts);
}
for (; name; name = strtok_r(NULL, sepr, &lasts)) {
int fd;
char *next;
if (*name == '!') {
exclude = TRUE;
while (*++name == '!')
;
if (*name == '\0')
continue;
}
fd = strtol(name, &next, 0);
if (fd >= 0 && fd < NOFILES_MAX && *next == '\0') {
fd++;
if (exclude) {
prdelset(setp, fd);
} else {
praddset(setp, fd);
}
} else if (strcmp(name, "ALL") == 0) {
if (exclude) {
premptyset(setp);
} else {
prfillset(setp);
}
} else {
(void) fprintf(stderr,
"%s: filedescriptor not in range[0..%d]: %s\n",
command, NOFILES_MAX-1, name);
rc = -1;
}
}
return (rc);
}
void
upcase(char *str)
{
int c;
while ((c = *str) != '\0')
*str++ = toupper(c);
}
int
liblist(char *arg, int hang)
{
const char *star = "*";
struct dynpat *Dyp;
char *pat;
char *fpat;
char *lasts;
uint_t maxpat;
Dyp = my_malloc(sizeof (struct dynpat), NULL);
Dyp->next = NULL;
if (Lastpat == NULL)
Dynpat = Lastpat = Dyp;
else {
Lastpat->next = Dyp;
Lastpat = Dyp;
}
Dyp->flag = hang? BPT_HANG : 0;
Dyp->exclude_lib = 0;
Dyp->exclude = 0;
Dyp->internal = 0;
Dyp->Dp = NULL;
if ((fpat = strchr(arg, ':')) != NULL)
*fpat++ = '\0';
pat = strtok_r(arg, sepr, &lasts);
if (pat != NULL && *pat == '!') {
Dyp->exclude_lib = 1;
pat += strspn(pat, "!");
if (*pat == '\0')
pat = strtok_r(NULL, sepr, &lasts);
Dyp->exclude = 1;
Dyp->internal = 1;
fpat = NULL;
}
if (pat == NULL) {
Dyp->libpat = my_malloc(sizeof (char *), NULL);
Dyp->libpat[0] = star;
Dyp->nlibpat = 1;
} else {
maxpat = 1;
Dyp->libpat = my_malloc(maxpat * sizeof (char *), NULL);
Dyp->nlibpat = 0;
Dyp->libpat[Dyp->nlibpat++] = pat;
while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) {
if (Dyp->nlibpat == maxpat) {
maxpat *= 2;
Dyp->libpat = my_realloc(Dyp->libpat,
maxpat * sizeof (char *), NULL);
}
Dyp->libpat[Dyp->nlibpat++] = pat;
}
}
if (fpat == NULL)
pat = NULL;
else {
fpat += strspn(fpat, white);
if (*fpat == ':') {
Dyp->internal = 1;
*fpat++ = '\0';
}
pat = strtok_r(fpat, csepr, &lasts);
}
if (pat != NULL && *pat == '!') {
Dyp->exclude = 1;
Dyp->internal = 1;
pat += strspn(pat, "!");
if (*pat == '\0')
pat = strtok_r(NULL, sepr, &lasts);
}
if (pat == NULL) {
Dyp->sympat = my_malloc(sizeof (char *), NULL);
Dyp->sympat[0] = star;
Dyp->nsympat = 1;
} else {
maxpat = 1;
Dyp->sympat = my_malloc(maxpat * sizeof (char *), NULL);
Dyp->nsympat = 0;
Dyp->sympat[Dyp->nsympat++] = pat;
while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) {
if (Dyp->nsympat == maxpat) {
maxpat *= 2;
Dyp->sympat = my_realloc(Dyp->sympat,
maxpat * sizeof (char *), NULL);
}
Dyp->sympat[Dyp->nsympat++] = pat;
}
}
return (0);
}