#ifndef lint
static char copyright[] =
"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: main.c,v 1.53 2008/10/21 16:21:41 abe Exp $";
#endif
#include "lsof.h"
static int GObk[] = { 1, 1 };
static char GOp;
static char *GOv = (char *)NULL;
static int GOx1 = 1;
static int GOx2 = 0;
_PROTOTYPE(static int GetOpt,(int ct, char *opt[], char *rules, int *err));
_PROTOTYPE(static char *sv_fmt_str,(char *f));
int
main(argc, argv)
int argc;
char *argv[];
{
int ad, c, i, n, rv, se1, se2, ss;
char *cp;
int err = 0;
int ev = 0;
int fh = 0;
char *fmtr = (char *)NULL;
long l;
MALLOC_S len;
struct lfile *lf;
struct nwad *np, *npn;
char options[128];
int rc = 0;
struct stat sb;
struct sfile *sfp;
struct lproc **slp = (struct lproc **)NULL;
int sp = 0;
struct str_lst *str, *strt;
int version = 0;
int xover = 0;
#if defined(HAS_STRFTIME)
char *fmt = (char *)NULL;
size_t fmtl;
#endif
#if defined(HASZONES)
znhash_t *zp;
#endif
#if defined(HASSELINUX)
cntxlist_t *cntxp;
CntxStatus = is_selinux_enabled() ? 1 : 0;
#endif
if ((Pn = strrchr(argv[0], '/')))
Pn++;
else
Pn = argv[0];
for (i = 3, n = GET_MAX_FD(); i < n; i++)
(void) close(i);
while (((i = open("/dev/null", O_RDWR, 0)) >= 0) && (i < 2))
;
if (i < 0)
Exit(1);
if (i > 2)
(void) close(i);
(void) umask(0);
#if defined(HASSETLOCALE)
(void) setlocale(LC_CTYPE, "");
#endif
Mypid = getpid();
if ((Mygid = (gid_t)getgid()) != getegid())
Setgid = 1;
Euid = geteuid();
if ((Myuid = (uid_t)getuid()) && !Euid)
Setuidroot = 1;
if (!(Namech = (char *)malloc(MAXPATHLEN + 1))) {
(void) fprintf(stderr, "%s: no space for name buffer\n", Pn);
Exit(1);
}
Namechl = (size_t)(MAXPATHLEN + 1);
(void) snpf(options, sizeof(options),
"?a%sbc:D:d:%sf:F:g:hi:%slL:%sMnNo:Op:Pr:%ss:S:tT:u:UvVwx:%s%s%s",
#if defined(HAS_AFS) && defined(HASAOPT)
"A:",
#else
"",
#endif
#if defined(HASNCACHE)
"C",
#else
"",
#endif
#if defined(HASKOPT)
"k:",
#else
"",
#endif
#if defined(HASMOPT) || defined(HASMNTSUP)
"m:",
#else
"",
#endif
#if defined(HASPPID)
"R",
#else
"",
#endif
#if defined(HASXOPT)
# if defined(HASXOPT_ROOT)
(Myuid == 0) ? "X" : "",
# else
"X",
# endif
#else
"",
#endif
#if defined(HASZONES)
"z:",
#else
"",
#endif
#if defined(HASSELINUX)
"Z:"
#else
""
#endif
);
while ((c = GetOpt(argc, argv, options, &rv)) != EOF) {
if (rv) {
err = 1;
continue;
}
switch (c) {
case 'a':
Fand = 1;
break;
#if defined(HAS_AFS) && defined(HASAOPT)
case 'A':
if (!GOv || *GOv == '-' || *GOv == '+') {
(void) fprintf(stderr, "%s: -A not followed by path\n", Pn);
err = 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
} else
AFSApath = GOv;
break;
#endif
case 'b':
Fblock = 1;
break;
case 'c':
if (GOp == '+') {
if (!GOv || (*GOv == '-') || (*GOv == '+')
|| !isdigit((int)*GOv))
{
(void) fprintf(stderr,
"%s: +c not followed by width number\n", Pn);
err = 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
} else {
CmdLim = atoi(GOv);
#if defined(MAXSYSCMDL)
if (CmdLim > MAXSYSCMDL) {
(void) fprintf(stderr,
"%s: +c %d > what system provides (%d)\n",
Pn, CmdLim, MAXSYSCMDL);
err = 1;
}
#endif
}
break;
}
if (GOv && (*GOv == '/')) {
if (enter_cmd_rx(GOv))
err = 1;
} else {
if (enter_str_lst("-c", GOv, &Cmdl, &Cmdni, &Cmdnx))
err = 1;
#if defined(MAXSYSCMDL)
else if (Cmdl->len > MAXSYSCMDL) {
(void) fprintf(stderr, "%s: \"-c ", Pn);
(void) safestrprt(Cmdl->str, stderr, 2);
(void) fprintf(stderr, "\" length (%d) > what system",
Cmdl->len);
(void) fprintf(stderr, " provides (%d)\n",
MAXSYSCMDL);
Cmdl->len = 0;
err = 1;
}
#endif
}
break;
#if defined(HASNCACHE)
case 'C':
Fncache = (GOp == '-') ? 0 : 1;
break;
#endif
case 'd':
if (GOp == '+') {
if (enter_dir(GOv, 0))
err = 1;
else {
Selflags |= SELNM;
xover = 1;
}
} else {
if (enter_fd(GOv))
err = 1;
}
break;
case 'D':
if (GOp == '+') {
if (enter_dir(GOv, 1))
err = 1;
else {
Selflags |= SELNM;
xover = 1;
}
} else {
#if defined(HASDCACHE)
if (ctrl_dcache(GOv))
err = 1;
#else
(void) fprintf(stderr, "%s: unsupported option: -D\n", Pn);
err = 1;
#endif
}
break;
case 'f':
if (!GOv || *GOv == '-' || *GOv == '+') {
Ffilesys = (GOp == '+') ? 2 : 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
}
#if defined(HASFSTRUCT)
for (; *GOv; GOv++) {
switch (*GOv) {
# if !defined(HASNOFSCOUNT)
case 'c':
case 'C':
if (GOp == '+') {
Fsv |= FSV_CT;
FsvByf = 1;
} else
Fsv &= (unsigned char)~FSV_CT;
break;
# endif
# if !defined(HASNOFSADDR)
case 'f':
case 'F':
if (GOp == '+') {
Fsv |= FSV_FA;
FsvByf = 1;
} else
Fsv &= (unsigned char)~FSV_FA;
break;
# endif
# if !defined(HASNOFSFLAGS)
case 'g':
case 'G':
if (GOp == '+') {
Fsv |= FSV_FG;
FsvByf = 1;
} else
Fsv &= (unsigned char)~FSV_FG;
FsvFlagX = (*GOv == 'G') ? 1 : 0;
break;
# endif
# if !defined(HASNOFSNADDR)
case 'n':
case 'N':
if (GOp == '+') {
Fsv |= FSV_NI;
FsvByf = 1;
} else
Fsv &= (unsigned char)~FSV_NI;
break;
# endif
default:
(void) fprintf(stderr,
"%s: unknown file struct option: %c\n", Pn, *GOv);
err++;
}
}
#else
(void) fprintf(stderr,
"%s: unknown string for %cf: %s\n", Pn, GOp, GOv);
err++;
#endif
break;
case 'F':
if (!GOv || *GOv == '-' || *GOv == '+'
|| strcmp(GOv, "0") == 0) {
if (GOv) {
if (*GOv == '-' || *GOv == '+') {
GOx1 = GObk[0];
GOx2 = GObk[1];
} else if (*GOv == '0')
Terminator = '\0';
}
for (i = 0; FieldSel[i].nm; i++) {
#if !defined(HASPPID)
if (FieldSel[i].id == LSOF_FID_PPID)
continue;
#endif
#if !defined(HASFSTRUCT)
if (FieldSel[i].id == LSOF_FID_CT
|| FieldSel[i].id == LSOF_FID_FA
|| FieldSel[i].id == LSOF_FID_FG
|| FieldSel[i].id == LSOF_FID_NI)
continue;
#endif
#if !defined(HASZONES)
if (FieldSel[i].id == LSOF_FID_ZONE)
continue;
#endif
#if defined(HASSELINUX)
if ((FieldSel[i].id == LSOF_FID_CNTX) && !CntxStatus)
continue;
#else
if (FieldSel[i].id == LSOF_FID_CNTX)
continue;
#endif
if (FieldSel[i].id == LSOF_FID_RDEV)
continue;
FieldSel[i].st = 1;
if (FieldSel[i].opt && FieldSel[i].ov)
*(FieldSel[i].opt) |= FieldSel[i].ov;
}
#if defined(HASFSTRUCT)
Ffield = FsvFlagX = 1;
#else
Ffield = 1;
#endif
break;
}
if (strcmp(GOv, "?") == 0) {
fh = 1;
break;
}
for (; *GOv; GOv++) {
for (i = 0; FieldSel[i].nm; i++) {
#if !defined(HASPPID)
if (FieldSel[i].id == LSOF_FID_PPID)
continue;
#endif
#if !defined(HASFSTRUCT)
if (FieldSel[i].id == LSOF_FID_CT
|| FieldSel[i].id == LSOF_FID_FA
|| FieldSel[i].id == LSOF_FID_FG
|| FieldSel[i].id == LSOF_FID_NI)
continue;
#endif
if (FieldSel[i].id == *GOv) {
FieldSel[i].st = 1;
if (FieldSel[i].opt && FieldSel[i].ov)
*(FieldSel[i].opt) |= FieldSel[i].ov;
#if defined(HASFSTRUCT)
if (i == LSOF_FIX_FG)
FsvFlagX = 1;
#endif
if (i == LSOF_FIX_TERM)
Terminator = '\0';
break;
}
}
if ( ! FieldSel[i].nm) {
(void) fprintf(stderr,
"%s: unknown field: %c\n", Pn, *GOv);
err++;
}
}
Ffield = 1;
break;
case 'g':
if (GOv) {
if (*GOv == '-' || *GOv == '+') {
GOx1 = GObk[0];
GOx2 = GObk[1];
} else if (enter_id(PGID, GOv))
err = 1;
}
Fpgid = 1;
break;
case 'h':
case '?':
Fhelp = 1;
break;
case 'i':
if (!GOv || *GOv == '-' || *GOv == '+') {
Fnet = 1;
FnetTy = 0;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
}
if (enter_network_address(GOv))
err = 1;
break;
#if defined(HASKOPT)
case 'k':
if (!GOv || *GOv == '-' || *GOv == '+') {
(void) fprintf(stderr, "%s: -k not followed by path\n", Pn);
err = 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
} else
Nmlst = GOv;
break;
#endif
case 'l':
Futol = 0;
break;
case 'L':
Fnlink = (GOp == '+') ? 1 : 0;
if (!GOv || *GOv == '-' || *GOv == '+') {
Nlink = 0l;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
}
for (cp = GOv, l = 0l, n = 0; *cp; cp++) {
if (!isdigit((unsigned char)*cp))
break;
l = (l * 10l) + ((long)*cp - (long)'0');
n++;
}
if (n) {
if (GOp != '+') {
(void) fprintf(stderr,
"%s: no number may follow -L\n", Pn);
err = 1;
} else {
Nlink = l;
Selflags |= SELNLINK;
}
} else
Nlink = 0l;
if (*cp) {
GOx1 = GObk[0];
GOx2 = GObk[1] + n;
}
break;
#if defined(HASMOPT) || defined(HASMNTSUP)
case 'm':
if (GOp == '-') {
# if defined(HASMOPT)
if (!GOv || *GOv == '-' || *GOv == '+') {
(void) fprintf(stderr,
"%s: -m not followed by path\n", Pn);
err = 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
} else
Memory = GOv;
# else
(void) fprintf(stderr, "%s: -m not supported\n", Pn);
err = 1;
# endif
} else if (GOp == '+') {
# if defined(HASMNTSUP)
if (!GOv || *GOv == '-' || *GOv == '+') {
MntSup = 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
} else {
MntSup = 2;
MntSupP = GOv;
}
# else
(void) fprintf(stderr, "%s: +m not supported\n", Pn);
err = 1;
# endif
} else {
(void) fprintf(stderr, "%s: %cm not supported\n", Pn, GOp);
err = 1;
}
break;
#endif
case 'M':
FportMap = (GOp == '+') ? 1 : 0;
break;
case 'n':
Fhost = (GOp == '-') ? 0 : 1;
break;
case 'N':
Fnfs = 1;
break;
case 'o':
if (!GOv || *GOv == '-' || *GOv == '+') {
Foffset = 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
}
for (cp = GOv, i = n = 0; *cp; cp++) {
if (!isdigit((unsigned char)*cp))
break;
i = (i * 10) + ((int)*cp - '0');
n++;
}
if (n)
OffDecDig = i;
else
Foffset = 1;
if (*cp) {
GOx1 = GObk[0];
GOx2 = GObk[1] + n;
}
break;
case 'O':
Fovhd = (GOp == '-') ? 1 : 0;
break;
case 'p':
if (enter_id(PID, GOv))
err = 1;
break;
case 'P':
Fport = (GOp == '-') ? 0 : 1;
break;
case 'r':
if (GOp == '+')
ev = rc = 1;
if (!GOv || *GOv == '-' || *GOv == '+') {
RptTm = RPTTM;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
}
for (cp = GOv, i = n = 0; *cp; cp++) {
if (!isdigit((unsigned char)*cp))
break;
i = (i * 10) + ((int)*cp - '0');
n++;
}
if (n)
RptTm = i;
else
RptTm = RPTTM;
if (!*cp)
break;
while(*cp && (*cp == ' '))
cp++;
if (*cp != LSOF_FID_MARK) {
GOx1 = GObk[0];
GOx2 = GObk[1] + n;
break;
}
#if defined(HAS_STRFTIME)
cp++;
if ((fmtl = strlen(cp) + 1) < 1) {
(void) fprintf(stderr, "%s: <fmt> too short: \"%s\"\n",
Pn, cp);
err = 1;
} else {
fmt = cp;
fmtl = (fmtl * 8) + 1;
if (!(fmtr = (char *)malloc((MALLOC_S)fmtl))) {
(void) fprintf(stderr,
"%s: no space (%d) for <fmt> result: \"%s\"\n",
Pn, (int)fmtl, cp);
Exit(1);
}
if (util_strftime(fmtr, fmtl - 1, fmt) < 1) {
(void) fprintf(stderr, "%s: illegal <fmt>: \"%s\"\n",
Pn, fmt);
err = 1;
}
}
#else
(void) fprintf(stderr, "%s: m<fmt> not supported: \"%s\"\n",
Pn, cp);
err = 1;
#endif
break;
#if defined(HASPPID)
case 'R':
Fppid = 1;
break;
#endif
case 's':
#if defined(HASTCPUDPSTATE)
if (!GOv || *GOv == '-' || *GOv == '+') {
Fsize = 1;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
} else {
if (enter_state_spec(GOv))
err = 1;
}
#else
Fsize = 1;
#endif
break;
case 'S':
if (!GOv || *GOv == '-' || *GOv == '+') {
TmLimit = TMLIMIT;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
}
for (cp = GOv, i = n = 0; *cp; cp++) {
if (!isdigit((unsigned char)*cp))
break;
i = (i * 10) + ((int)*cp - '0');
n++;
}
if (n)
TmLimit = i;
else
TmLimit = TMLIMIT;
if (*cp) {
GOx1 = GObk[0];
GOx2 = GObk[1] + n;
}
if (TmLimit < TMLIMMIN) {
(void) fprintf(stderr,
"%s: WARNING: -S time (%d) changed to %d\n",
Pn, TmLimit, TMLIMMIN);
TmLimit = TMLIMMIN;
}
break;
case 't':
Fterse = Fwarn = 1;
break;
case 'T':
if (!GOv || *GOv == '-' || *GOv == '+') {
Ftcptpi = (GOp == '-') ? 0 : TCPTPI_STATE;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
}
for (Ftcptpi = 0; *GOv; GOv++) {
switch (*GOv) {
#if defined(HASSOOPT) || defined(HASSOSTATE) || defined(HASTCPOPT)
case 'f':
Ftcptpi |= TCPTPI_FLAGS;
break;
#endif
#if defined(HASTCPTPIQ)
case 'q':
Ftcptpi |= TCPTPI_QUEUES;
break;
#endif
case 's':
Ftcptpi |= TCPTPI_STATE;
break;
#if defined(HASTCPTPIW)
case 'w':
Ftcptpi |= TCPTPI_WINDOWS;
break;
#endif
default:
(void) fprintf(stderr,
"%s: unsupported TCP/TPI info selection: %c\n",
Pn, *GOv);
err = 1;
}
}
break;
case 'u':
if (enter_uid(GOv))
err = 1;
break;
case 'U':
Funix = 1;
break;
case 'v':
version = 1;
break;
case 'V':
Fverbose = 1;
break;
case 'w':
Fwarn = (GOp == '+') ? 0 : 1;
break;
case 'x':
if (!GOv || *GOv == '-' || *GOv == '+') {
Fxover = XO_ALL;
if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
} else {
for (; *GOv; GOv++) {
switch (*GOv) {
case 'f':
Fxover |= XO_FILESYS;
break;
case 'l':
Fxover |= XO_SYMLINK;
break;
default:
(void) fprintf(stderr,
"%s: unknown cross-over option: %c\n",
Pn, *GOv);
err++;
}
}
}
break;
#if defined(HASXOPT)
case 'X':
Fxopt = Fxopt ? 0 : 1;
break;
#endif
#if defined(HASZONES)
case 'z':
Fzone = 1;
if (GOv && (*GOv != '-') && (*GOv != '+')) {
if (enter_zone_arg(GOv))
err = 1;
} else if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
break;
#endif
#if defined(HASSELINUX)
case 'Z':
if (!CntxStatus) {
(void) fprintf(stderr, "%s: -Z limited to SELinux\n", Pn);
err = 1;
} else {
Fcntx = 1;
if (GOv && (*GOv != '-') && (*GOv != '+')) {
if (enter_cntx_arg(GOv))
err = 1;
} else if (GOv) {
GOx1 = GObk[0];
GOx2 = GObk[1];
}
}
break;
#endif
default:
(void) fprintf(stderr, "%s: unknown option (%c)\n", Pn, c);
err = 1;
}
}
if (Cmdnx && Cmdni) {
for (str = Cmdl; str; str = str->next) {
if (str->x) {
for (strt = Cmdl; strt; strt = strt->next) {
if (!strt->x) {
if (!strcmp(str->str, strt->str)) {
(void) fprintf(stderr,
"%s: -c^%s and -c%s conflict.\n",
Pn, str->str, strt->str);
err++;
}
}
}
}
}
}
#if defined(HASTCPUDPSTATE)
if (TcpStXn && TcpStIn) {
for (i = 0; i < TcpNstates; i++) {
if (TcpStX[i] && TcpStI[i]) {
(void) fprintf(stderr,
"%s: can't include and exclude TCP state: %s\n",
Pn, TcpSt[i]);
err = 1;
}
}
}
if (UdpStXn && UdpStIn) {
for (i = 0; i < UdpNstates; i++) {
if (UdpStX[i] && UdpStI[i]) {
(void) fprintf(stderr,
"%s: can't include and exclude UDP state: %s\n",
Pn, UdpSt[i]);
err = 1;
}
}
}
#endif
if (Fsize && Foffset) {
(void) fprintf(stderr, "%s: -o and -s are mutually exclusive\n",
Pn);
err++;
}
if (Ffield) {
if (Fterse) {
(void) fprintf(stderr,
"%s: -F and -t are mutually exclusive\n", Pn);
err++;
}
FieldSel[LSOF_FIX_PID].st = 1;
#if defined(HAS_STRFTIME)
if (fmtr) {
for (cp = strchr(fmt, '%'); cp; cp = strchr(cp, '%')) {
if (*++cp == 'n') {
(void) fprintf(stderr,
"%s: %%n illegal in -r m<fmt> when -F has", Pn);
(void) fprintf(stderr,
" been specified: \"%s\"\n", fmt);
err++;
break;
} else if (*cp == '%')
cp++;
}
}
#endif
}
if (Fxover && !xover) {
(void) fprintf(stderr, "%s: -x must accompany +d or +D\n", Pn);
err++;
}
if (DChelp || err || Fhelp || fh || version)
usage(err ? 1 : 0, fh, version);
if (Suid && Nuid && Nuid < Mxuid) {
if (!(Suid = (struct seluid *)realloc((MALLOC_P *)Suid,
(MALLOC_S)(sizeof(struct seluid) * Nuid))))
{
(void) fprintf(stderr, "%s: can't realloc UID table\n", Pn);
Exit(1);
}
Mxuid = Nuid;
}
if ((Cmdl && Cmdni) || CmdRx)
Selflags |= SELCMD;
#if defined(HASSELINUX)
if (CntxArg)
Selflags |= SELCNTX;
#endif
if (Fdl)
Selflags |= SELFD;
if (Fnet)
Selflags |= SELNET;
if (Fnfs)
Selflags |= SELNFS;
if (Funix)
Selflags |= SELUNX;
if (Npgid && Npgidi)
Selflags |= SELPGID;
if (Npid && Npidi)
Selflags |= SELPID;
if (Nuid && Nuidincl)
Selflags |= SELUID;
if (Nwad)
Selflags |= SELNA;
#if defined(HASZONES)
if (ZoneArg)
Selflags |= SELZONE;
#endif
if (GOx1 < argc)
Selflags |= SELNM;
if (Selflags == 0) {
if (Fand) {
(void) fprintf(stderr,
"%s: no select options to AND via -a\n", Pn);
usage(1, 0, 0);
}
Selflags = SELALL;
} else {
if (GOx1 >= argc && (Selflags & (SELNA|SELNET)) != 0
&& (Selflags & ~(SELNA|SELNET)) == 0)
Selinet = 1;
Selall = 0;
}
if (stat(DEVDEV_PATH, &sb)) {
se1 = errno;
if ((ad = strcmp(DEVDEV_PATH, "/dev"))) {
if ((ss = stat("/dev", &sb)))
se2 = errno;
else
se2 = 0;
} else {
se2 = 0;
ss = 1;
}
if (ss) {
(void) fprintf(stderr, "%s: can't stat(%s): %s\n", Pn,
DEVDEV_PATH, strerror(se1));
if (ad) {
(void) fprintf(stderr, "%s: can't stat(/dev): %s\n", Pn,
strerror(se2));
}
Exit(1);
}
}
DevDev = sb.st_dev;
if (GOx1 < argc) {
if (ck_file_arg(GOx1, argc, argv, Ffilesys, 0, (struct stat *)NULL))
usage(1, 0, 0);
}
initialize();
if (Sfile)
(void) hashSfile();
#if defined(WILLDROPGID)
(void) dropgid();
#endif
#if defined(HASDCACHE)
if (DCstate)
readdev(0);
#endif
(void) snpf(options, sizeof(options), "%%%su", INODEPSPEC);
InodeFmt_d = sv_fmt_str(options);
(void) snpf(options, sizeof(options), "%%#%sx", INODEPSPEC);
InodeFmt_x = sv_fmt_str(options);
(void) snpf(options, sizeof(options), "0t%%%su", SZOFFPSPEC);
SzOffFmt_0t = sv_fmt_str(options);
(void) snpf(options, sizeof(options), "%%%su", SZOFFPSPEC);
SzOffFmt_d = sv_fmt_str(options);
(void) snpf(options, sizeof(options), "%%*%su", SZOFFPSPEC);
SzOffFmt_dv = sv_fmt_str(options);
(void) snpf(options, sizeof(options), "%%#%sx", SZOFFPSPEC);
SzOffFmt_x = sv_fmt_str(options);
#if defined(HASMNTSUP)
if (MntSup == 1) {
(void) readmnt();
Exit(0);
}
#endif
if (RptTm)
CkPasswd = 1;
do {
gather_proc_info();
if (Nlproc > 1) {
if (Nlproc > sp) {
len = (MALLOC_S)(Nlproc * sizeof(struct lproc *));
sp = Nlproc;
if (!slp)
slp = (struct lproc **)malloc(len);
else
slp = (struct lproc **)realloc((MALLOC_P *)slp, len);
if (!slp) {
(void) fprintf(stderr,
"%s: no space for %d sort pointers\n", Pn, Nlproc);
Exit(1);
}
}
for (i = 0; i < Nlproc; i++) {
slp[i] = &Lproc[i];
}
(void) qsort((QSORT_P *)slp, (size_t)Nlproc,
(size_t)sizeof(struct lproc *), comppid);
}
if ((n = Nlproc)) {
#if defined(HASNCACHE)
NcacheReload = 1;
#endif
for (lf = Lf, print_init(); PrPass < 2; PrPass++) {
for (i = n = 0; i < Nlproc; i++) {
Lp = (Nlproc > 1) ? slp[i] : &Lproc[i];
if (Lp->pss) {
if (print_proc())
n++;
}
if (RptTm && PrPass)
(void) free_lproc(Lp);
}
}
Lf = lf;
}
if (RptTm) {
if (rc) {
if (!n)
break;
else
ev = 0;
}
#if defined(HAS_STRFTIME)
if (fmt && fmtr) {
(void) util_strftime(fmtr, fmtl - 1, fmt);
fmtr[fmtl - 1] = '\0';
}
#endif
if (Ffield) {
putchar(LSOF_FID_MARK);
#if defined(HAS_STRFTIME)
if (fmtr)
(void) printf("%s", fmtr);
#endif
putchar(Terminator);
if (Terminator != '\n')
putchar('\n');
} else {
#if defined(HAS_STRFTIME)
if (fmtr)
cp = fmtr;
else
#endif
cp = "=======";
puts(cp);
}
(void) fflush(stdout);
(void) childx();
(void) sleep(RptTm);
Hdr = Nlproc = 0;
CkPasswd = 1;
}
} while (RptTm);
(void) childx();
rv = 0;
for (str = Cmdl; str; str = str->next) {
if (str->f)
continue;
rv = 1;
if (Fverbose) {
(void) printf("%s: command not located: ", Pn);
safestrprt(str->str, stdout, 1);
}
}
for (i = 0; i < NCmdRxU; i++) {
if (CmdRx[i].mc)
continue;
rv = 1;
if (Fverbose) {
(void) printf("%s: no command found for regex: ", Pn);
safestrprt(CmdRx[i].exp, stdout, 1);
}
}
for (sfp = Sfile; sfp; sfp = sfp->next) {
if (sfp->f)
continue;
rv = 1;
if (Fverbose) {
(void) printf("%s: no file%s use located: ", Pn,
sfp->type ? "" : " system");
safestrprt(sfp->aname, stdout, 1);
}
}
#if defined(HASPROCFS)
if (Procsrch && !Procfind) {
rv = 1;
if (Fverbose) {
(void) printf("%s: no file system use located: ", Pn);
safestrprt(Mtprocfs ? Mtprocfs->dir : HASPROCFS, stdout, 1);
}
}
{
struct procfsid *pfi;
for (pfi = Procfsid; pfi; pfi = pfi->next) {
if (!pfi->f) {
rv = 1;
if (Fverbose) {
(void) printf("%s: no file use located: ", Pn);
safestrprt(pfi->nm, stdout, 1);
}
}
}
}
#endif
if ((np = Nwad)) {
for (; np; np = np->next) {
if (!(cp = np->arg))
continue;
for (npn = np->next; npn; npn = npn->next) {
if (!npn->arg)
continue;
if (!strcmp(cp, npn->arg)) {
if (np->f)
npn->f = np->f;
else if (npn->f)
np->f = npn->f;
else
npn->f = 1;
}
}
}
for (np = Nwad; np; np = np->next) {
if (!np->f && (cp = np->arg)) {
rv = 1;
if (Fverbose) {
(void) printf("%s: Internet address not located: ", Pn);
safestrprt(cp ? cp : "(unknown)", stdout, 1);
}
}
}
}
if (Fnet && Fnet < 2) {
rv = 1;
if (Fverbose)
(void) printf("%s: no Internet files located\n", Pn);
}
#if defined(HASTCPUDPSTATE)
if (TcpStIn) {
for (i = 0; i < TcpNstates; i++) {
if (TcpStI[i] == 1) {
rv = 1;
if (Fverbose)
(void) printf("%s: TCP state not located: %s\n",
Pn, TcpSt[i]);
}
}
}
if (UdpStIn) {
for (i = 0; i < UdpNstates; i++) {
if (UdpStI[i] == 1) {
rv = 1;
if (Fverbose)
(void) printf("%s: UDP state not located: %s\n",
Pn, UdpSt[i]);
}
}
}
#endif
if (Fnfs && Fnfs < 2) {
rv = 1;
if (Fverbose)
(void) printf("%s: no NFS files located\n", Pn);
}
for (i = 0; i < Npid; i++) {
if (Spid[i].f || Spid[i].x)
continue;
rv = 1;
if (Fverbose)
(void) printf("%s: process ID not located: %d\n",
Pn, Spid[i].i);
}
#if defined(HASZONES)
if (ZoneArg) {
for (i = 0; i < HASHZONE; i++) {
for (zp = ZoneArg[i]; zp; zp = zp->next) {
if (!zp->f) {
rv = 1;
if (Fverbose) {
(void) printf("%s: zone not located: ", Pn);
safestrprt(zp->zn, stdout, 1);
}
}
}
}
}
#endif
#if defined(HASSELINUX)
if (CntxArg) {
for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) {
if (!cntxp->f) {
rv = 1;
if (Fverbose) {
(void) printf("%s: context not located: ", Pn);
safestrprt(cntxp->cntx, stdout, 1);
}
}
}
}
#endif
for (i = 0; i < Npgid; i++) {
if (Spgid[i].f || Spgid[i].x)
continue;
rv = 1;
if (Fverbose)
(void) printf("%s: process group ID not located: %d\n",
Pn, Spgid[i].i);
}
for (i = 0; i < Nuid; i++) {
if (Suid[i].excl || Suid[i].f)
continue;
rv = 1;
if (Fverbose) {
if (Suid[i].lnm) {
(void) printf("%s: login name (UID %lu) not located: ",
Pn, (unsigned long)Suid[i].uid);
safestrprt(Suid[i].lnm, stdout, 1);
} else
(void) printf("%s: user ID not located: %lu\n", Pn,
(unsigned long)Suid[i].uid);
}
}
if (!rv && rc)
rv = ev;
if (!rv && ErrStat)
rv = 1;
Exit(rv);
return(rv);
}
static int
GetOpt(ct, opt, rules, err)
int ct;
char *opt[];
char *rules;
int *err;
{
register int c;
register char *cp = (char *)NULL;
if (GOx2 == 0) {
if (GOx1 >= ct
|| (opt[GOx1][0] != '-' && opt[GOx1][0] != '+')
|| !opt[GOx1][1])
return(EOF);
if (strcmp(opt[GOx1], "--") == 0 || strcmp(opt[GOx1], "++") == 0) {
GOx1++;
return(EOF);
}
GOp = opt[GOx1][0];
GOx2 = 1;
}
*err = 0;
if ((c = opt[GOx1][GOx2]) == ':') {
(void) fprintf(stderr,
"%s: colon is an illegal option character.\n", Pn);
*err = 1;
} else if (!(cp = strchr(rules, c))) {
(void) fprintf(stderr, "%s: illegal option character: %c\n", Pn, c);
*err = 2;
}
if (*err) {
if (opt[GOx1][++GOx2] == '\0') {
GOx1++;
GOx2 = 0;
}
return(c);
}
if (*(cp + 1) == ':') {
if(opt[GOx1][GOx2 + 1] != '\0') {
GObk[0] = GOx1;
GObk[1] = ++GOx2;
GOv = &opt[GOx1++][GOx2];
} else if (++GOx1 >= ct)
GOv = (char *)NULL;
else {
GObk[0] = GOx1;
GObk[1] = 0;
GOv = opt[GOx1];
if (strcmp(GOv, "--") == 0)
GOv = (char *)NULL;
else
GOx1++;
}
GOx2 = 0;
} else {
if (opt[GOx1][++GOx2] == '\0') {
GOx2 = 0;
GOx1++;
}
GOv = (char *)NULL;
}
return(c);
}
static char *
sv_fmt_str(f)
char *f;
{
char *cp;
MALLOC_S l;
l = (MALLOC_S)(strlen(f) + 1);
if (!(cp = (char *)malloc(l))) {
(void) fprintf(stderr,
"%s: can't allocate %d bytes for format: %s\n", Pn, (int)l, f);
Exit(1);
}
(void) snpf(cp, l, "%s", f);
return(cp);
}