#ifndef lint
static char copyright[] =
"@(#) Copyright 2002 Purdue Research Foundation.\nAll rights reserved.\n";
#endif
#include "LsofTest.h"
#include "lsof_fields.h"
char *Pn = (char *)NULL;
_PROTOTYPE(static void cleanup,(void));
_PROTOTYPE(static char *tstlsof,(char **texec, char **tkmem, char **tproc));
int
main(argc, argv)
int argc;
char *argv[];
{
char buf[2048];
char *em;
char *texec = (char *)NULL;
char *tkmem = (char *)NULL;
char *tproc = (char *)NULL;
int xv = 0;
if ((Pn = strrchr(argv[0], '/')))
Pn++;
else
Pn = argv[0];
(void) printf("%s ... ", Pn);
(void) fflush(stdout);
PrtMsg((char *)NULL, Pn);
if (ScanArg(argc, argv, "h", Pn))
xv = 1;
if (xv || LTopt_h) {
(void) PrtMsg("usage: [-h]", Pn);
PrtMsgX (" -h print help (this panel)", Pn, cleanup,
xv);
}
if ((em = IsLsofExec()))
(void) PrtMsgX(em, Pn, cleanup, 1);
if ((em = CanRdKmem()))
(void) PrtMsgX(em, Pn, cleanup, 1);
if ((em = tstlsof(&texec, &tkmem, &tproc)))
PrtMsg(em, Pn);
if (texec)
PrtMsg(texec, Pn);
if (tkmem)
PrtMsg(tkmem, Pn);
if (tproc)
PrtMsg(tproc, Pn);
if (em || texec || tkmem || tproc) {
if (strcmp(LT_DEF_LSOF_PATH, LsofPath)) {
PrtMsg (" ", Pn);
PrtMsg ("Hint: you used the LT_LSOF_PATH environment variable to",
Pn);
PrtMsg (" specify this path to the lsof executable:\n", Pn);
(void) snprintf(buf, sizeof(buf) - 1, " %s\n", LsofPath);
buf[sizeof(buf) - 1] = '\0';
PrtMsg (buf, Pn);
PrtMsgX(" Make sure its revision is 4.63 or higher.",
Pn, cleanup, 1);
} else
PrtMsgX("", Pn, cleanup, 1);
}
(void) PrtMsgX("OK", Pn, cleanup, 0);
return(0);
}
static void
cleanup()
{
}
static char *
tstlsof(texec, tkmem, tproc)
char **texec;
char **tkmem;
char **tproc;
{
char buf[2048];
char *cem;
LTfldo_t *cmdp;
LTdev_t cwddc;
struct stat cwdsb;
LTfldo_t *devp;
int execs = 0;
int fdn;
LTfldo_t *fdp;
LTfldo_t *fop;
char ibuf[64];
LTfldo_t *inop;
LTdev_t kmemdc;
int kmems = 0;
struct stat kmemsb;
LTdev_t lsofdc;
struct stat lsofsb;
int nf;
char *opv[4];
char *pem = (char *)NULL;
pid_t pid;
int pids = 0;
int procs = 0;
LTfldo_t *rdevp;
char *tcp;
int ti;
LTdev_t tmpdc;
LTfldo_t *typ;
int xwhile;
if (stat(LsofPath, &lsofsb)) {
(void) snprintf(buf, sizeof(buf) - 1, "ERROR!!! stat(%s): %s",
LsofPath, strerror(errno));
buf[sizeof(buf) - 1] = '\0';
cem = MkStrCpy(buf, &ti);
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
execs = 1;
} else if ((cem = ConvStatDev(&lsofsb.st_dev, &lsofdc))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
execs = 1;
}
#if defined(LT_KMEM)
if (stat("/dev/kmem", &kmemsb)) {
(void) snprintf(buf, sizeof(buf) - 1,
"ERROR!!! can't stat(2) /dev/kmem: %s", strerror(errno));
buf[sizeof(buf) - 1] = '\0';
cem = MkStrCpy(buf, &ti);
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
kmems = 1;
} else if ((cem = ConvStatDev(&kmemsb.st_rdev, &kmemdc))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
kmems = 1;
}
#else
kmems = 1;
#endif
if (stat(".", &cwdsb)) {
(void) snprintf(buf, sizeof(buf) - 1, "ERROR!!! stat(.): %s",
strerror(errno));
buf[sizeof(buf) - 1] = '\0';
cem = MkStrCpy(buf, &ti);
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
procs = 1;
} else if ((cem = ConvStatDev(&cwdsb.st_dev, &cwddc))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
procs = 1;
}
ti = 0;
#if defined(USE_LSOF_C_OPT)
opv[ti++] = "-C";
#endif
#if defined(USE_LSOF_X_OPT)
opv[ti++] = "-X";
#endif
opv[ti++] = "-clsof";
opv[ti] = (char *)NULL;
if ((cem = ExecLsof(opv))) {
if (pem)
(void) PrtMsg(pem, Pn);
return(cem);
}
xwhile = execs + kmems + procs;
while ((xwhile < 3) && (fop = RdFrLsof(&nf, &cem))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
switch (fop->ft) {
case LSOF_FID_PID:
pid = (pid_t)atoi(fop->v);
pids = 1;
cmdp = (LTfldo_t *)NULL;
for (fop++, ti = 1; ti < nf; fop++, ti++) {
switch (fop->ft) {
case LSOF_FID_CMD:
cmdp = fop;
break;
}
}
if (!cmdp || (pid != LsofPid))
pids = 0;
break;
case LSOF_FID_FD:
if (!pids)
break;
devp = inop = rdevp = typ = (LTfldo_t *)NULL;
fdp = fop;
for (fop++, ti = 1; ti < nf; fop++, ti++) {
switch(fop->ft) {
case LSOF_FID_DEVN:
devp = fop;
break;
case LSOF_FID_INODE:
inop = fop;
break;
case LSOF_FID_RDEV:
rdevp = fop;
break;
case LSOF_FID_TYPE:
typ = fop;
break;
}
}
for (fdn = 0, tcp = fdp->v; *tcp; tcp++) {
if (!isdigit((unsigned char)*tcp)) {
fdn = -1;
break;
}
fdn = (fdn * 10) + (int)(*tcp - '0');
}
if (!procs
&& (fdn == -1)
&& !strcasecmp(fdp->v, "cwd")
&& typ
&& (!strcasecmp(typ->v, "DIR") || !strcasecmp(typ->v, "VDIR"))
) {
if (!devp || !inop)
break;
if ((cem = ConvLsofDev(devp->v, &tmpdc))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
break;
}
(void) snprintf(ibuf, sizeof(ibuf) - 1, "%u",
(unsigned int)cwdsb.st_ino);
ibuf[sizeof(ibuf) - 1] = '\0';
if ((tmpdc.maj == cwddc.maj)
&& (tmpdc.min == cwddc.min)
&& (tmpdc.unit == cwddc.unit)
&& !strcmp(inop->v, ibuf)
) {
procs = 1;
xwhile++;
}
break;
}
if (!kmems
&& (fdn >= 0)
&& typ
&& (!strcasecmp(typ->v, "CHR") || !strcasecmp(typ->v, "VCHR"))
) {
if (!inop || !rdevp)
break;
if ((cem = ConvLsofDev(rdevp->v, &tmpdc))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
break;
}
(void) snprintf(ibuf, sizeof(ibuf) - 1, "%u",
(unsigned int)kmemsb.st_ino);
ibuf[sizeof(ibuf) - 1] = '\0';
if ((tmpdc.maj == kmemdc.maj)
&& (tmpdc.min == kmemdc.min)
&& (tmpdc.unit == kmemdc.unit)
&& !strcmp(inop->v, ibuf)
) {
kmems = 1;
xwhile++;
}
break;
}
if (!execs
&& (fdn == -1)
&& typ
&& (!strcasecmp(typ->v, "REG") || !strcasecmp(typ->v, "VREG"))
) {
if (!devp || !inop)
break;
if ((cem = ConvLsofDev(devp->v, &lsofdc))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
break;
}
(void) snprintf(ibuf, sizeof(ibuf) - 1, "%u",
(unsigned int)lsofsb.st_ino);
ibuf[sizeof(ibuf) - 1] = '\0';
if ((tmpdc.maj == lsofdc.maj)
&& (tmpdc.min == lsofdc.min)
&& (tmpdc.unit == lsofdc.unit)
&& !strcmp(inop->v, ibuf)
) {
execs = 1;
xwhile++;
}
}
}
}
(void) StopLsof();
if (!execs)
*texec = "ERROR!!! open lsof executable wasn't found.";
if (!kmems)
*tkmem = "ERROR!!! open lsof /dev/kmem usage wasn't found.";
if (!procs)
*tproc = "ERROR!!! lsof process wasn't found.";
return(pem);
}