/*
 * dproc.c - Linux process access functions for /proc-based lsof
 */


/*
 * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana
 * 47907.  All rights reserved.
 *
 * Written by Victor A. Abell
 *
 * This software is not subject to any license of the American Telephone
 * and Telegraph Company or the Regents of the University of California.
 *
 * Permission is granted to anyone to use this software for any purpose on
 * any computer system, and to alter it and redistribute it freely, subject
 * to the following restrictions:
 *
 * 1. Neither the authors nor Purdue University are responsible for any
 *    consequences of the use of this software.
 *
 * 2. The origin of this software must not be misrepresented, either by
 *    explicit claim or by omission.  Credit to the authors and Purdue
 *    University must appear in documentation and sources.
 *
 * 3. Altered versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 *
 * 4. This notice may not be removed or altered.
 */

#ifndef lint
static char copyright[] =
"@(#) Copyright 1997 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: dproc.c,v 1.25 2011/09/07 19:07:45 abe Exp $";
#endif

#include "lsof.h"


/*
 * Local definitions
 */

#define	FDINFO_FLAGS		1	/* fdinfo flags available */
#define	FDINFO_POS		2	/* fdinfo position available */
#define FDINFO_ALL		(FDINFO_FLAGS | FDINFO_POS)
#define	LSTAT_TEST_FILE		"/"
#define LSTAT_TEST_SEEK		1

#if	!defined(ULLONG_MAX)
#define	ULLONG_MAX		18446744073709551615ULL
#endif	/* !defined(ULLONG_MAX) */


/*
 * Local structures
 */

struct l_fdinfo {
	int flags;			/* flags: line value */
	off_t pos;			/* pos: line value */
};


/*
 * Local variables
 */

static short Cckreg;			/* conditional status of regular file
					 * checking:
					 *     0 = unconditionally check
					 *     1 = conditionally check */
static short Ckscko;			/* socket file only checking status:
					 *     0 = none
					 *     1 = check only socket files */


/*
 * Local function prototypes
 */

_PROTOTYPE(static int get_fdinfo,(char *p, struct l_fdinfo *fi));
_PROTOTYPE(static int getlinksrc,(char *ln, char *src, int srcl));
_PROTOTYPE(static int isefsys,(char *path, char *type, int l,
			       efsys_list_t **rep, struct lfile **lfr));
_PROTOTYPE(static int nm2id,(char *nm, int *id, int *idl));
_PROTOTYPE(static int read_id_stat,(int ty, char *p, int id, char **cmd,
				    int *ppid, int *pgid));
_PROTOTYPE(static void process_proc_map,(char *p, struct stat *s, int ss));
_PROTOTYPE(static int process_id,(char *idp, int idpl, char *cmd, UID_ARG uid,
				  int pid, int ppid, int pgid, int tid));
_PROTOTYPE(static int statEx,(char *p, struct stat *s, int *ss));
 

#if	defined(HASSELINUX)
_PROTOTYPE(static int cmp_cntx_eq,(char *pcntx, char *ucntx));


#include <fnmatch.h>


/*
 * cmp_cntx_eq -- compare program and user security contexts
 */

static int
cmp_cntx_eq(pcntx, ucntx)
	char *pcntx;			       /* program context */
	char *ucntx;			       /* user supplied context */
{
	return !fnmatch(ucntx, pcntx, 0);
}


/*
 * enter_cntx_arg() - enter name ecurity context argument
 */

int
enter_cntx_arg(cntx)
	char *cntx;			       /* context */
{
	cntxlist_t *cntxp;
/*
 * Search the argument list for a duplicate.
 */
	for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) {
	    if (!strcmp(cntxp->cntx, cntx)) {
		if (!Fwarn) {
		    (void) fprintf(stderr, "%s: duplicate context: %s\n",
			Pn, cntx);
		}
		return(1);
	    }
	}
/*
 * Create and link a new context argument list entry.
 */
	if (!(cntxp = (cntxlist_t *)malloc((MALLOC_S)sizeof(cntxlist_t)))) {
	    (void) fprintf(stderr, "%s: no space for context: %s\n", Pn, cntx);
	    Exit(1);
	}
	cntxp->f = 0;
	cntxp->cntx = cntx;
	cntxp->next = CntxArg;
	CntxArg = cntxp;
	return(0);
}
#endif	/* defined(HASSELINUX) */


/*
 * gather_proc_info() -- gather process information
 */

void
gather_proc_info()
{
	char *cmd, *tcmd;
	struct dirent *dp;
	unsigned char ht, pidts;
	int n, nl, pgid, pid, ppid, rv, tid, tpgid, tppid, tx;
	static char *path = (char *)NULL;
	static int pathl = 0;
	static char *pidpath = (char *)NULL;
	static MALLOC_S pidpathl = 0;
	static MALLOC_S pidx = 0;
	static DIR *ps = (DIR *)NULL;
	struct stat sb;
	static char *taskpath = (char *)NULL;
	static int taskpathl = 0;
	static char *tidpath = (char *)NULL;
	static int tidpathl = 0;
	DIR *ts;
	UID_ARG uid;

/*
 * Do one-time setup.
 */
	if (!pidpath) {
	    pidx = strlen(PROCFS) + 1;
	    pidpathl = pidx + 64 + 1;	/* 64 is growth room */
	    if (!(pidpath = (char *)malloc(pidpathl))) {
		(void) fprintf(stderr,
		    "%s: can't allocate %d bytes for \"%s/\"<pid>\n",
		    Pn, (int)pidpathl, PROCFS);
		Exit(1);
	    }
	    (void) snpf(pidpath, pidpathl, "%s/", PROCFS);
	}
/*
 * Get lock and net information.
 */
	(void) make_proc_path(pidpath, pidx, &path, &pathl, "locks");
	(void) get_locks(path);
	(void) make_proc_path(pidpath, pidx, &path, &pathl, "net/");
	(void) set_net_paths(path, strlen(path));
/*
 * If only socket files have been selected, or socket files have been selected
 * ANDed with other selection options, enable the skipping of regular files.
 *
 * If socket files and some process options have been selected, enable
 * conditional skipping of regular file; i.e., regular files will be skipped
 * unless they belong to a process selected by one of the specified options.
 */
	if (Selflags & SELNW) {

	/*
	 * Some network files selection options have been specified.
	 */
	    if (Fand || !(Selflags & ~SELNW)) {

	    /*
	     * Selection ANDing or only network file options have been
	     * specified, so set unconditional skipping of regular files
	     * and socket file only checking.
	     */
		Cckreg = 0;
		Ckscko = 1;
	    } else {

	    /*
	     * If ORed file selection options have been specified, or no ORed
	     * process selection options have been specified, enable
	     * unconditional file checking and clear socket file only checking.
	     *
	     * If only ORed process selection options have been specified,
	     * enable conditional file skipping and socket file only checking.
	     */
		if ((Selflags & SELFILE) || !(Selflags & SELPROC))
		    Cckreg = Ckscko = 0;
		else
		    Cckreg = Ckscko = 1;
	    }
	} else {

	/*
	 * No network file selection options were specified.  Enable
	 * unconditional file checking and clear socket file only checking.
	 */
	    Cckreg = Ckscko = 0;
	}
/*
 * Read /proc, looking for PID directories.  Open each one and
 * gather its process and file information.
 */
	if (!ps) {
	    if (!(ps = opendir(PROCFS))) {
		(void) fprintf(stderr, "%s: can't open %s\n", Pn, PROCFS);
		Exit(1);
	    }
	} else
	    (void) rewinddir(ps);
	while ((dp = readdir(ps))) {
	    if (nm2id(dp->d_name, &pid, &n))
		continue;
	/*
	 * Build path to PID's directory.
	 */
	    if ((pidx + n + 1 + 1) > pidpathl) {
		pidpathl = pidx + n + 1 + 1 + 64;
		if (!(pidpath = (char *)realloc((MALLOC_P *)pidpath, pidpathl)))
		{
		    (void) fprintf(stderr,
			"%s: can't allocate %d bytes for \"%s/%s/\"\n",
			Pn, (int)pidpathl, PROCFS, dp->d_name);
		    Exit(1);
		}
	    }
	    (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name);
	    n += (pidx + 1);
	/*
	 * Process the PID's stat info.
	 */
	    if (stat(pidpath, &sb))
		continue;
	    uid = (UID_ARG)sb.st_uid;
	    ht = pidts = 0;

#if	defined(HASTASKS)
	/*
	 * If task reporting is selected, check the tasks of the process first,
	 * so that the "-p<PID> -aK" options work properly.
	 */
	    if ((Selflags & SELTASK)) {
		(void) make_proc_path(pidpath, n, &taskpath, &taskpathl,
				      "task");
		tx = n + 4;
		if ((ts = opendir(taskpath))) {

		/*
		 * Process the PID's tasks.  Record the open files of those
		 * whose TIDs do not match the PID and which are themselves
		 * not zombies.
		 */
		    while ((dp = readdir(ts))) {

		    /*
		     * Get the task ID.  Skip the task if its ID matches the
		     * process PID.
		     */
			if (nm2id(dp->d_name, &tid, &nl))
			    continue;
			if  (tid == pid) {
			    pidts = 1;
			    continue;
			}
		    /*
		     * Form the path for the TID.
		     */
			if ((tx + 1 + nl + 1 + 4) > tidpathl) {
			    tidpathl = tx + 1 + n + 1 + 4 + 64;
			    if (tidpath)
				tidpath = (char *)realloc((MALLOC_P *)tidpath,
							  tidpathl);
			    else
				tidpath = (char *)malloc((MALLOC_S)tidpathl);
			    if (!tidpath) {
				(void) fprintf(stderr,
				    "%s: can't allocate %d task bytes", Pn,
				    tidpathl);
				(void) fprintf(stderr, " for \"%s/%s/stat\"\n",
				    taskpath, dp->d_name);
				Exit(1);
			    }
			}
			(void) snpf(tidpath, tidpathl, "%s/%s/stat", taskpath,
			    dp->d_name);
		    /*
		     * Check the task state.
		     */
			rv = read_id_stat(1, tidpath, tid, &tcmd, &tppid,
					  &tpgid);
			if ((rv < 0) || (rv == 1))
			    continue;
		    /*
		     * Attempt to record the task.
		     */
			if (!process_id(tidpath, (tx + 1 + nl+ 1), tcmd, uid,
					pid, tppid, tpgid, tid))
			{
			    ht = 1;
			}
		    }
		    (void) closedir(ts);
		}
	    }
#endif	/* defined(HASTASKS) */

	/*
	 * If the main process is a task and task selection has been specified
	 * along with option ANDing, enter the main process temporarily as a
	 * task,  so that the "-aK" option set lists the main process along
	 * with its tasks.
	 */
	    (void) make_proc_path(pidpath, n, &path, &pathl, "stat");
	    if (((rv = read_id_stat(0, path, pid, &cmd, &ppid, &pgid)) >= 0) 
	    &&   (rv != 1))
	    {
		tid = (Fand && ht && pidts && (Selflags & SELTASK)) ? pid : 0;
		if ((!process_id(pidpath, n, cmd, uid, pid, ppid, pgid, tid))
		&&  tid)
		{
		    Lp->tid = 0;
		}
	    }
	}
}


/*
 * get_fdinfo() - get values from /proc/<PID>fdinfo/FD
 */

static int
get_fdinfo(p, fi)
	char *p;			/* path to fdinfo file */
	struct l_fdinfo *fi;		/* pointer to local fdinfo values
					 * return structure */
{
	char buf[MAXPATHLEN + 1], *ep, **fp;
	FILE *fs;
	int rv = 0;
	unsigned long ul;
	unsigned long long ull;
/*
 * Signal no values returned (0) if no fdinfo pointer was provided or if the
 * fdinfo path can't be opened.
 */
	if (!fi)
	    return(0);
	if (!p || !*p || !(fs = fopen(p, "r")))
	    return(0);
/*
 * Read the fdinfo file.
 */
	while (fgets(buf, sizeof(buf), fs)) {
	    if (get_fields(buf, (char *)NULL, &fp, (int *)NULL, 0) < 2)
		continue;
	    if (!fp[0] || !*fp[0] || !fp[1] || !*fp[1])
		continue;
	    if (!strcmp(fp[0], "flags:")) {

	    /*
	     * Process a "flags:" line.
	     */
		ep = (char *)NULL;
		if ((ul = strtoul(fp[1], &ep, 0)) == ULONG_MAX
		||  !ep || *ep)
		    continue;
		fi->flags = (unsigned int)ul;
		if ((rv |= FDINFO_FLAGS) == FDINFO_ALL)
		    break;
	    } else if (!strcmp(fp[0], "pos:")) {

	    /*
	     * Process a "pos:" line.
	     */
		ep = (char *)NULL;
		if ((ull = strtoull(fp[1], &ep, 0)) == ULLONG_MAX
		||  !ep || *ep)
		    continue;
		fi->pos = (off_t)ull;
		if ((rv |= FDINFO_POS) == FDINFO_ALL)
		    break;
	    }
	}
	fclose(fs);
/*
 * Signal via the return value what information was obtained. (0 == none)
 */
	return(rv);
}


/*
 * getlinksrc() - get the source path name for the /proc/<PID>/fd/<FD> link
 */


static int
getlinksrc(ln, src, srcl)
	char *ln;			/* link path */
	char *src;			/* link source path return address */
	int srcl;			/* length of src[] */
{
	char *cp;
	int ll;

	if ((ll = readlink(ln, src, srcl - 1)) < 1
	||  ll >= srcl)
	    return(-1);
	src[ll] = '\0';
	if (*src == '/')
	    return(ll);
	if ((cp = strchr(src, ':'))) {
	    *cp = '\0';
	    ll = strlen(src);
	}
	return(ll);
}


/*
 * initialize() - perform all initialization
 */

void
initialize()
{
	int fd;
	struct l_fdinfo fi;
	char path[MAXPATHLEN];
	struct stat sb;
/*
 * Test for -i and -X option conflict.
 */
	if (Fxopt && (Fnet || Nwad)) {
	    (void) fprintf(stderr, "%s: -i is useless when -X is specified.\n",
		Pn);
	    usage(1, 0, 0);
	}
/*
 * Open LSTAT_TEST_FILE and seek to byte LSTAT_TEST_SEEK, then lstat the
 * /proc/<PID>/fd/<FD> for LSTAT_TEST_FILE to see what position is reported.
 * If the result is LSTAT_TEST_SEEK, enable offset reporting.
 *
 * If the result isn't LSTAT_TEST_SEEK, next check the fdinfo file for the
 * open LSTAT_TEST_FILE file descriptor.  If it exists and contains a "pos:"
 * value, and if the value is LSTAT_TEST_SEEK, enable offset reporting.
 */
	if ((fd = open(LSTAT_TEST_FILE, O_RDONLY)) >= 0) {
	    if (lseek(fd, (off_t)LSTAT_TEST_SEEK, SEEK_SET)
	    == (off_t)LSTAT_TEST_SEEK) {
		(void) snpf(path, sizeof(path), "%s/%d/fd/%d", PROCFS, Mypid,
			    fd);
		if (!lstat(path, &sb)) {
		    if (sb.st_size == (off_t)LSTAT_TEST_SEEK)
			OffType = 1;
		}
	    }
	    if (!OffType) {
		(void) snpf(path, sizeof(path), "%s/%d/fdinfo/%d", PROCFS,
			    Mypid, fd);
		if (get_fdinfo(path, &fi) & FDINFO_POS) {
		    if (fi.pos == (off_t)LSTAT_TEST_SEEK)
			OffType = 2;
		}
	    }
	    (void) close(fd);
	}
	if (!OffType) {
	    if (Foffset && !Fwarn)
		(void) fprintf(stderr,
		    "%s: WARNING: can't report offset; disregarding -o.\n",
		    Pn);
	    Foffset = 0;
	    Fsize = 1;
	}
	if (Fsv && (OffType != 2)) {
	    if (!Fwarn && FsvByf)
		(void) fprintf(stderr,
		    "%s: WARNING: can't report file flags; disregarding +f.\n",
		    Pn);
	    Fsv = 0;
	}
/*
 * Make sure the local mount info table is loaded if doing anything other
 * than just Internet lookups.  (HasNFS is defined during the loading of the
 * local mount table.)
 */
	if (Selinet == 0)
	    (void) readmnt();
}


/*
 * make_proc_path() - make a path in a /proc directory
 *
 * entry:
 *	pp = pointer to /proc prefix
 *	lp = length of prefix
 *	np = pointer to malloc'd buffer to receive new file's path
 *	nl = length of new file path buffer
 *	sf = new path's suffix
 *
 * return: length of new path
 *	np = updated with new path
 *	nl = updated with new path length
 */

int
make_proc_path(pp, pl, np, nl, sf)
	char *pp;			/* path prefix -- e.g., /proc/<pid>/ */
	int pl;				/* strlen(pp) */
	char **np;			/* malloc'd receiving buffer */
	int *nl;			/* strlen(*np) */
	char *sf;			/* suffix of new path */
{
	char *cp;
	MALLOC_S rl, sl;

	sl = strlen(sf);
	if ((rl = pl + sl + 1) > *nl) {
	    if ((cp = *np))
		cp = (char *)realloc((MALLOC_P *)cp, rl);
	    else
		cp = (char *)malloc(rl);
	    if (!cp) {
		(void) fprintf(stderr,
		    "%s: can't allocate %d bytes for %s%s\n",
		    Pn, (int)rl, pp, sf);
		Exit(1);
	    }
	    *nl = rl;
	    *np = cp;
	}
	(void) snpf(*np, *nl, "%s", pp);
	(void) snpf(*np + pl, *nl - pl, "%s", sf);
	return(rl - 1);
}


/*
 * isefsys() -- is path on a file system exempted with -e
 *
 * Note: alloc_lfile() must have been called in advance.
 */

static int
isefsys(path, type, l, rep, lfr)
	char *path;			/* path to file */
	char *type;			/* unknown file type */
	int l;				/* link request: 0 = report
					 *               1 = link */
	efsys_list_t **rep;		/* returned Efsysl pointer, if not
					 * NULL */
	struct lfile **lfr;		/* allocated struct lfile pointer */
{
	efsys_list_t *ep;
	int ds, len;
	struct mounts *mp;
	char nmabuf[MAXPATHLEN + 1];

	len = (int) strlen(path);
	for (ep = Efsysl; ep; ep = ep->next) {

	/*
	 * Look for a matching exempt file system path at the beginning of
	 * the file path.
	 */
	    if (ep->pathl > len)
		continue;
	    if (strncmp(ep->path, path, ep->pathl))
		continue;
	/*
	 * If only reporting, return information as requested.
	 */
	    if (!l) {
		if (rep)
		    *rep = ep;
		return(0);
	    }
	/*
	 * Process an exempt file.
	 */
	    ds = 0;
	    if ((mp = ep->mp)) {
		if (mp->ds & SB_DEV) {
		    Lf->dev = mp->dev;
		    ds = Lf->dev_def = 1;
		}
		if (mp->ds & SB_RDEV) {
		    Lf->rdev = mp->rdev;
		    ds = Lf->rdev_def = 1;
		}
	    }
	    if (!ds)
		(void) enter_dev_ch("UNKNOWN");
	    Lf->ntype = N_UNKN;
	    (void) snpf(Lf->type, sizeof(Lf->type), "%s",
			(type ? type : "UNKN"));
	    (void) enter_nm(path);
	    (void) snpf(nmabuf, sizeof(nmabuf), "(%ce %s)",
		ep->rdlnk ? '+' : '-', ep->path);
	    nmabuf[sizeof(nmabuf) - 1] = '\0';
	    (void) add_nma(nmabuf, strlen(nmabuf));
	    if (Lf->sf) {
		if (lfr)
		    *lfr = Lf;
		link_lfile();
	    } else if (lfr)
		*lfr = (struct lfile *)NULL;
	    return(0);
	}
	return(1);
}


/*
 * nm2id() - convert a name to an integer ID
 */

static int
nm2id(nm, id, idl)
	char *nm;			/* pointer to name */
	int *id;			/* pointer to ID receiver */
	int *idl;			/* pointer to ID length receiver */
{
	register int tid, tidl;

	for (*id = *idl = tid = tidl = 0; *nm; nm++) {

#if	defined(__STDC__)	/* { */
	    if (!isdigit((unsigned char)*nm))
#else	/* !defined(__STDC__)	   } { */
	    if (!isascii(*nm) || !isdigit((unsigned char)*cp))
#endif	/* defined(__STDC__)	   } */

		{
		    return(1);
		}
		tid = tid * 10 + (int)(*nm - '0');
		tidl++;
	}
	*id = tid;
	*idl = tidl;
	return(0);
}


/*
 * open_proc_stream() -- open a /proc stream
 */

FILE *
open_proc_stream(p, m, buf, sz, act)
	char *p;			/* pointer to path to open */
	char *m;			/* pointer to mode -- e.g., "r" */
	char **buf;			/* pointer tp setvbuf() address
					 * (NULL if none) */
	size_t *sz;			/* setvbuf() size (0 if none or if
					 * getpagesize() desired */
	int act;			/* fopen() failure action:
					 *     0 : return (FILE *)NULL
					 *   <>0 : fprintf() an error message
					 *         and Exit(1)
					 */
{
	FILE *fs;			/* opened stream */
	static size_t psz = (size_t)0;	/* page size */
	size_t tsz;			/* temporary size */
/*
 * Open the stream.
 */
	if (!(fs = fopen(p, m))) {
	    if (!act)
		return((FILE *)NULL);
	    (void) fprintf(stderr, "%s: can't fopen(%s, \"%s\"): %s\n",
		Pn, p, m, strerror(errno));
	    Exit(1);
	}
/*
 * Return the stream if no buffer change is required.
 */
	if (!buf)
	    return(fs);
/*
 * Determine the buffer size required.
 */
	if (!(tsz = *sz)) {
	    if (!psz)
		psz = getpagesize();
	    tsz = psz;
	}
/*
 * Allocate a buffer for the stream, as required.
 */
	if (!*buf) {
	    if (!(*buf = (char *)malloc((MALLOC_S)tsz))) {
		(void) fprintf(stderr,
		    "%s: can't allocate %d bytes for %s stream buffer\n",
		    Pn, (int)tsz, p);
		Exit(1);
	    }
	    *sz = tsz;
	}
/*
 * Assign the buffer to the stream.
 */
	if (setvbuf(fs, *buf, _IOFBF, tsz)) {
	    (void) fprintf(stderr, "%s: setvbuf(%s)=%d failure: %s\n",
		Pn, p, (int)tsz, strerror(errno));
	    Exit(1);
	}
	return(fs);
}


/*
 * process_id - process ID: PID or LWP
 *
 * return:  0 == ID processed
 *          1 == ID not processed
 */

static int
process_id(idp, idpl, cmd, uid, pid, ppid, pgid, tid)
	char *idp;			/* pointer to ID's path */
	int idpl;			/* pointer to ID's path length */
	char *cmd;			/* pointer to ID's command */
	UID_ARG uid;			/* ID's UID */
	int pid;			/* ID's PID */
	int ppid;			/* parent PID */
	int pgid;			/* parent GID */
	int tid;			/* task ID, if non-zero */
{
	int av;
	static char *dpath = (char *)NULL;
	static int dpathl = 0;
	short efs, enls, enss, lnk, oty, pn, pss, sf, tsf;
	int fd, i, ls, n, ss, sv;
	struct l_fdinfo fi;
	DIR *fdp;
	struct dirent *fp;
	static char *ipath = (char *)NULL;
	static int ipathl = 0;
	int j = 0;
	struct lfile *lfr;
	struct stat lsb, sb;
	char nmabuf[MAXPATHLEN + 1], pbuf[MAXPATHLEN + 1];
	static char *path = (char *)NULL;
	static int pathl = 0;
	static char *pathi = (char *)NULL;
	static int pathil = 0;
	int txts = 0;

#if	defined(HASSELINUX)
	cntxlist_t *cntxp;
#endif	/* defined(HASSELINUX) */

/*
 * See if process is excluded.
 */
	if (is_proc_excl(pid, pgid, uid, &pss, &sf, tid)
	||  is_cmd_excl(cmd, &pss, &sf))
	    return(1);
	if (Cckreg) {

	/*
	 * If conditional checking of regular files is enabled, enable
	 * socket file only checking, based on the process' selection
	 * status.
	 */
	    Ckscko = (sf & SELPROC) ? 0 : 1;
	}
	alloc_lproc(pid, pgid, ppid, uid, cmd, (int)pss, (int)sf);
	Lp->tid = tid;
	Plf = (struct lfile *)NULL;
/*
 * Process the ID's current working directory info.
 */
	if (!Ckscko) {
	    (void) make_proc_path(idp, idpl, &path, &pathl, "cwd");
	    alloc_lfile(CWD, -1);
	    efs = 0;
	    if (getlinksrc(path, pbuf, sizeof(pbuf)) < 1) {
		if (!Fwarn) {
		    (void) memset((void *)&sb, 0, sizeof(sb));
		    lnk = ss = 0;
		    (void) snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)",
			strerror(errno));
		    nmabuf[sizeof(nmabuf) - 1] = '\0';
		    (void) add_nma(nmabuf, strlen(nmabuf));
		    pn = 1;
		} else
		    pn = 0;
	    } else {
		lnk = pn = 1;
		if (Efsysl && !isefsys(pbuf, "UNKNcwd", 1, NULL, &lfr)) {
		    efs = 1;
		    pn = 0;
		} else {
		    ss = SB_ALL;
		    if (HasNFS) {
			if ((sv = statsafely(path, &sb)))
			sv = statEx(pbuf, &sb, &ss);
		    } else
			sv = stat(path, &sb);
		    if (sv) {
			ss = 0;
			if (!Fwarn) {
			    (void) snpf(nmabuf, sizeof(nmabuf), "(stat: %s)",
				strerror(errno));
			    nmabuf[sizeof(nmabuf) - 1] = '\0';
			    (void) add_nma(nmabuf, strlen(nmabuf));
			}
		    }
		}
	    }
	    if (pn) {
		(void) process_proc_node(lnk ? pbuf : path,
					 &sb, ss,
					 (struct stat *)NULL, 0);
		if (Lf->sf)
		    link_lfile();
	    }
	}
/*
 * Process the ID's root directory info.
 */
	if (!Ckscko) {
	    (void) make_proc_path(idp, idpl, &path, &pathl, "root");
	    alloc_lfile(RTD, -1);
	    if (getlinksrc(path, pbuf, sizeof(pbuf)) < 1) {
		if (!Fwarn) {
		    (void) memset((void *)&sb, 0, sizeof(sb));
		    lnk = ss = 0;
		    (void) snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)",
			strerror(errno));
		    nmabuf[sizeof(nmabuf) - 1] = '\0';
		    (void) add_nma(nmabuf, strlen(nmabuf));
		    pn = 1;
		} else
		    pn = 0;
	    } else {
		lnk = pn = 1;
		if (Efsysl && !isefsys(pbuf, "UNKNrtd", 1, NULL, NULL))
		    pn = 0;
		else {
		    ss = SB_ALL;
		    if (HasNFS) {
			if ((sv = statsafely(path, &sb)))
			    sv = statEx(pbuf, &sb, &ss);
		    } else
			sv = stat(path, &sb);
		    if (sv) {
			ss = 0;
			if (!Fwarn) {
			    (void) snpf(nmabuf, sizeof(nmabuf), "(stat: %s)",
				strerror(errno));
			    nmabuf[sizeof(nmabuf) - 1] = '\0';
			    (void) add_nma(nmabuf, strlen(nmabuf));
			}
		    }
		}
	    }
	    if (pn) {
		(void) process_proc_node(lnk ? pbuf : path,
					 &sb, ss,
					 (struct stat *)NULL, 0);
		if (Lf->sf)
		    link_lfile();
	    }
	}
/*
 * Process the ID's execution info.
 */
	if (!Ckscko) {
	    txts = 0;
	    (void) make_proc_path(idp, idpl, &path, &pathl, "exe");
	    alloc_lfile("txt", -1);
	    if (getlinksrc(path, pbuf, sizeof(pbuf)) < 1) {
		(void) memset((void *)&sb, 0, sizeof(sb));
		lnk = ss = 0;
		if (!Fwarn) {
		    if ((errno != ENOENT) || uid) {
			(void) snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)",
			    strerror(errno));
			nmabuf[sizeof(nmabuf) - 1] = '\0';
			(void) add_nma(nmabuf, strlen(nmabuf));
		    }
		    pn = 1;
		} else
		    pn = 0;
	    } else {
		lnk = pn = 1;
		if (Efsysl && !isefsys(pbuf, "UNKNtxt", 1, NULL, NULL))
		    pn = 0;
		else {
		    ss = SB_ALL;
		    if (HasNFS) {
			if ((sv = statsafely(path, &sb))) {
			    sv = statEx(pbuf, &sb,  &ss);
			    if (!sv && (ss & SB_DEV) && (ss & SB_INO))
				txts = 1;
			}
		    } else
			sv = stat(path, &sb);
		    if (sv) {
			ss = 0;
			if (!Fwarn) {
			    (void) snpf(nmabuf, sizeof(nmabuf), "(stat: %s)",
				strerror(errno));
			    nmabuf[sizeof(nmabuf) - 1] = '\0';
			    (void) add_nma(nmabuf, strlen(nmabuf));
			}
		    } else
			txts = 1;
		}
	    }
	    if (pn) {
		(void) process_proc_node(lnk ? pbuf : path,
					 &sb, ss,
					 (struct stat *)NULL, 0);
		if (Lf->sf)
		    link_lfile();
	    }
	}
/*
 * Process the ID's memory map info.
 */
	if (!Ckscko) {
	    (void) make_proc_path(idp, idpl, &path, &pathl, "maps");
	    (void) process_proc_map(path, txts ? &sb : (struct stat *)NULL,
				    txts ? ss : 0);
	}

#if	defined(HASSELINUX)
/*
 * Process the PID's SELinux context.
 */
	if (Fcntx) {

	/*
	 * If the -Z (cntx) option was specified, match the valid contexts.
	 */
	    errno = 0;
	    if (getpidcon(pid, &Lp->cntx) == -1) {
		Lp->cntx = (char *)NULL;
		if (!Fwarn) {
		    (void) snpf(nmabuf, sizeof(nmabuf),
			"(getpidcon: %s)", strerror(errno));
		    if (!(Lp->cntx = strdup(nmabuf))) {
			(void) fprintf(stderr,
			    "%s: no context error space: PID %ld",
			    Pn, (long)Lp->pid);
			Exit(1);
		    }
		}
	    } else if (CntxArg) {

	    /*
	     * See if context includes the process.
	     */
		for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) {
		    if (cmp_cntx_eq(Lp->cntx, cntxp->cntx)) {
			cntxp->f = 1;
			Lp->pss |= PS_PRI;
			Lp->sf |= SELCNTX;
			break;
		    }
		}
	    }
	}
#endif	/* defined(HASSELINUX) */

/*
 * Process the ID's file descriptor directory.
 */
	if ((i = make_proc_path(idp, idpl, &dpath, &dpathl, "fd/")) < 3)
	    return(0);
	dpath[i - 1] = '\0';
	if ((OffType == 2)
	&&  ((j = make_proc_path(idp, idpl, &ipath, &ipathl, "fdinfo/")) >= 7))
	    oty = 1;
	else
	    oty = 0;
	if (!(fdp = opendir(dpath))) {
	    if (!Fwarn) {
		(void) snpf(nmabuf, sizeof(nmabuf), "%s (opendir: %s)",
		    dpath, strerror(errno));
		alloc_lfile("NOFD", -1);
		nmabuf[sizeof(nmabuf) - 1] = '\0';
		(void) add_nma(nmabuf, strlen(nmabuf));
		link_lfile();
	    }
	    return(0);
	}
	dpath[i - 1] = '/';
	while ((fp = readdir(fdp))) {
	    if (nm2id(fp->d_name, &fd, &n))
		continue;
	    (void) make_proc_path(dpath, i, &path, &pathl, fp->d_name);
	    (void) alloc_lfile((char *)NULL, fd);
	    if (getlinksrc(path, pbuf, sizeof(pbuf)) < 1) {
		(void) memset((void *)&sb, 0, sizeof(sb));
		lnk = ss = 0;
		if (!Fwarn) {
		    (void) snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)",
			strerror(errno));
		    nmabuf[sizeof(nmabuf) - 1] = '\0';
		    (void) add_nma(nmabuf, strlen(nmabuf));
		    pn = 1;
		} else
		    pn = 0;
	    } else {
		lnk = 1;
		if (Efsysl && !isefsys(pbuf, "UNKNfd", 1, NULL, &lfr)) {
		    efs = 1;
		    pn = 0;
		} else {
		    if (HasNFS) {
			if (lstatsafely(path, &lsb)) {
			    (void) statEx(pbuf, &lsb, &ls);
			    enls = errno;
			} else {
			    enls = 0;
			    ls = SB_ALL;
			}
			if (statsafely(path, &sb)) {
			    (void) statEx(pbuf, &sb, &ss);
			    enss = errno;
			} else {
			    enss = 0;
			    ss = SB_ALL;
			}
		    } else {
			ls = lstat(path, &lsb) ? 0 : SB_ALL;
			enls = errno;
			ss = stat(path, &sb) ? 0 : SB_ALL;
			enss = errno;
		    }
		    if (!ls && !Fwarn) {
			(void) snpf(nmabuf, sizeof(nmabuf), "lstat: %s)",
			    strerror(enls));
			nmabuf[sizeof(nmabuf) - 1] = '\0';
			(void) add_nma(nmabuf, strlen(nmabuf));
		    }
		    if (!ss && !Fwarn) {
			(void) snpf(nmabuf, sizeof(nmabuf), "(stat: %s)",
			    strerror(enss));
			nmabuf[sizeof(nmabuf) - 1] = '\0';
			(void) add_nma(nmabuf, strlen(nmabuf));
		    }
		    if (Ckscko) {
			if ((ss & SB_MODE)
			&&  ((sb.st_mode & S_IFMT) == S_IFSOCK))
			{
			    pn = 1;
			} else
			    pn = 0;
		    } else
			pn = 1;
		}
	    }
	    if (pn || (efs && lfr && oty)) {
		if (oty) {
		    (void) make_proc_path(ipath, j, &pathi, &pathil,
					  fp->d_name);
		    if ((av = get_fdinfo(pathi, &fi)) & FDINFO_POS) {
			if (efs) {
			    if (Foffset) {
				lfr->off = (SZOFFTYPE)fi.pos;
				lfr->off_def = 1;
			    }
			} else {
			    ls |= SB_SIZE;
			    lsb.st_size = fi.pos;
			}
		    } else
			ls &= ~SB_SIZE;

#if	!defined(HASNOFSFLAGS)
		    if ((av & FDINFO_FLAGS) && (Fsv & FSV_FG)) {
			if (efs) {
			    lfr->ffg = (long)fi.flags;
			    lfr->fsv |= FSV_FG;
			} else {
			    Lf->ffg = (long)fi.flags;
			    Lf->fsv |= FSV_FG;
			}
		     }
# endif	/* !defined(HASNOFSFLAGS) */

		}
		if (pn) {
		    process_proc_node(lnk ? pbuf : path, &sb, ss, &lsb, ls);
		    if (Lf->sf)
			link_lfile();
		}
	    }
	}
	(void) closedir(fdp);
	return(0);
}


/*
 * process_proc_map() - process the memory map of a process
 */

static void
process_proc_map(p, s, ss)
	char *p;			/* path to process maps file */
	struct stat *s;			/* executing text file state buffer */
	int ss;				/* *s status -- i.e., SB_* values */
{
	char buf[MAXPATHLEN + 1], *ep, fmtbuf[32], **fp, nmabuf[MAXPATHLEN + 1];
	dev_t dev;
	int ds, efs, en, i, mss, nf, sv;
	int eb = 6;
	INODETYPE inode;
	MALLOC_S len;
	long maj, min;
	struct mounts *mp;
	FILE *ms;
	int ns = 0;
	struct stat sb;
	struct saved_map {
	    dev_t dev;
	    INODETYPE inode;
	};
	static struct saved_map *sm = (struct saved_map *)NULL;
	efsys_list_t *rep;
	static int sma = 0;
	static char *vbuf = (char *)NULL;
	static size_t vsz = (size_t)0;
/*
 * Open the /proc/<pid>/maps file, assign a page size buffer to its stream,
 * and read it/
 */
	if (!(ms = open_proc_stream(p, "r", &vbuf, &vsz, 0)))
	    return;
	while (fgets(buf, sizeof(buf), ms)) {
	    if ((nf = get_fields(buf, ":", &fp, &eb, 1)) < 7)
		continue;			/* not enough fields */
	    if (!fp[6] || !*fp[6])
		continue;			/* no path name */
	/*
	 * See if the path ends in " (deleted)".  If it does, strip the
	 * " (deleted)" characters and remember that they were there.
	 */
	    if (((ds = (int)strlen(fp[6])) > 10)
	    &&  !strcmp(fp[6] + ds - 10, " (deleted)"))
	    {
		*(fp[6] + ds - 10) = '\0';
	    } else
		ds = 0;
	/*
	 * Assemble the major and minor device numbers.
	 */
	    ep = (char *)NULL;
	    if (!fp[3] || !*fp[3]
	    ||  (maj = strtol(fp[3], &ep, 16)) == LONG_MIN || maj == LONG_MAX
	    ||  !ep || *ep)
		continue;
	    ep = (char *)NULL;
	    if (!fp[4] || !*fp[4]
	    ||  (min = strtol(fp[4], &ep, 16)) == LONG_MIN || min == LONG_MAX
	    ||  !ep || *ep)
		continue;
	/*
	 * Assemble the device and inode numbers.  If they are both zero, skip
	 * the entry.
	 */
	    dev = (dev_t)makedev((int)maj, (int)min);
	    if (!fp[5] || !*fp[5])
		continue;
	    ep = (char *)NULL;
	    if ((inode = strtoull(fp[5], &ep, 0)) == ULLONG_MAX
	    ||  !ep || *ep)
		continue;
	    if (!dev && !inode)
		continue;
	/*
	 * See if the device + inode pair match that of the executable.
	 * If they do, skip this map entry.
	 */
	    if (s && (ss & SB_DEV) && (ss & SB_INO)
	    &&  (dev == s->st_dev) && (inode == (INODETYPE)s->st_ino))
		continue;
	/*
	 * See if this device + inode pair has already been processed as
	 * a map entry.
	 */
	    for (i = 0; i < ns; i++) {
		if (dev == sm[i].dev && inode == sm[i].inode)
		    break;
	    }
	    if (i < ns)
		continue;
	/*
	 * Record the processing of this map entry's device and inode pair.
	 */
	    if (ns >= sma) {
		sma += 10;
		len = (MALLOC_S)(sma * sizeof(struct saved_map));
		if (sm)
		    sm = (struct saved_map *)realloc(sm, len);
		else
		    sm = (struct saved_map *)malloc(len);
		if (!sm) {
		    (void) fprintf(stderr,
			"%s: can't allocate %d bytes for saved maps, PID %d\n",
			Pn, (int)len, Lp->pid);
		    Exit(1);
		}
	    }
	    sm[ns].dev = dev;
	    sm[ns++].inode = inode;
	/*
	 * Allocate space for the mapped file, then get stat(2) information
	 * for it.  Skip the stat(2) operation if this is on an exempt file
	 * system.
	 */
	    alloc_lfile("mem", -1);
	    if (Efsysl && !isefsys(fp[6], (char *)NULL, 0, &rep, NULL))
		efs = sv = 1;
	    else
		efs = 0;
	    if (!efs) {
		if (HasNFS)
		    sv = statsafely(fp[6], &sb);
		else
		    sv = stat(fp[6], &sb);
	    }
	    if (sv || efs) {
		en = errno;
	    /*
	     * Applying stat(2) to the file was not possible (file is on an
	     * exempt file system) or stat(2) failed, so manufacture a partial
	     * stat(2) reply from the process' maps file entry.
	     *
	     * If the file has been deleted, reset its type to "DEL"; otherwise
	     * generate a stat() error name addition.
	     */
		(void) memset((void *)&sb, 0, sizeof(sb));
		sb.st_dev = dev;
		sb.st_ino = (ino_t)inode;
		sb.st_mode = S_IFREG;
		mss = SB_DEV | SB_INO | SB_MODE;
		if (ds)
		    alloc_lfile("DEL", -1);
		else if (!efs) {
		    (void) snpf(nmabuf, sizeof(nmabuf), "(stat: %s)",
			strerror(en));
		    nmabuf[sizeof(nmabuf) - 1] = '\0';
		    (void) add_nma(nmabuf, strlen(nmabuf));
		}
	    } else if ((sb.st_dev != dev) || ((INODETYPE)sb.st_ino != inode)) {

	    /*
	     * The stat(2) device and inode numbers don't match those obtained
	     * from the process' maps file.
	     *
	     * If the file has been deleted, reset its type to "DEL"; otherwise
	     * generate inconsistency name additions.
	     *
	     * Manufacture a partial stat(2) reply from the maps file
	     * information.
	     */
		if (ds)
		    alloc_lfile("DEL", -1);
		else if (!Fwarn) {
		    char *sep;

		    if (sb.st_dev != dev) {
			(void) snpf(nmabuf, sizeof(nmabuf),
			    "(path dev=%d,%d%s",
			    GET_MAJ_DEV(sb.st_dev), GET_MIN_DEV(sb.st_dev),
			    ((INODETYPE)sb.st_ino == inode) ? ")" : ",");
			nmabuf[sizeof(nmabuf) - 1] = '\0';
			(void) add_nma(nmabuf, strlen(nmabuf));
			sep = "";
		    } else
			sep = "(path ";
		    if ((INODETYPE)sb.st_ino != inode) {
			(void) snpf(fmtbuf, sizeof(fmtbuf), "%%sinode=%s)",
			    InodeFmt_d);
			(void) snpf(nmabuf, sizeof(nmabuf), fmtbuf,
			    sep, (INODETYPE)sb.st_ino);
			nmabuf[sizeof(nmabuf) - 1] = '\0';
			(void) add_nma(nmabuf, strlen(nmabuf));
		    }
		}
		(void) memset((void *)&sb, 0, sizeof(sb));
		sb.st_dev = dev;
		sb.st_ino = (ino_t)inode;
		sb.st_mode = S_IFREG;
		mss = SB_DEV | SB_INO | SB_MODE;
	    } else
		mss = SB_ALL;
	/*
	 * Record the file's information.
	 */
	    if (!efs)
		process_proc_node(fp[6], &sb, mss, (struct stat *)NULL, 0);
	    else {

	    /*
	     * If this file is on an exempt file system, complete the lfile
	     * structure, but change its type and add the exemption note to
	     * the NAME column.
	     */
		Lf->dev = sb.st_dev;
		Lf->inode = (ino_t)sb.st_ino;
		Lf->dev_def = Lf->inp_ty = 1;
		(void) enter_nm(fp[6]);
		(void) snpf(Lf->type, sizeof(Lf->type), "%s",
			    (ds ? "UNKNdel" : "UNKNmem"));
		(void) snpf(nmabuf, sizeof(nmabuf), "(%ce %s)",
		    rep->rdlnk ? '+' : '-', rep->path);
		nmabuf[sizeof(nmabuf) - 1] = '\0';
		(void) add_nma(nmabuf, strlen(nmabuf));
	    }
	    if (Lf->sf)
		link_lfile();
	}
	(void) fclose(ms);
}


/*
 * read_id_stat() - read ID (PID or LWP ID) status
 *
 * return: -1 == ID is unavailable
 *          0 == ID OK
 *          1 == ID is a zombie
 *	    2 == ID is a thread
 */

static int
read_id_stat(ty, p, id, cmd, ppid, pgid)
	int ty;				/* type: 0 == PID, 1 == LWP */
	char *p;			/* path to status file */
	int id;				/* ID: PID or LWP */
	char **cmd;			/* malloc'd command name */
	int *ppid;			/* returned parent PID for PID type */
	int *pgid;			/* returned process group ID for PID
					 * type */
{
	char buf[MAXPATHLEN], *cp, *cp1, **fp;
	static char *cbf = (char *)NULL;
	static MALLOC_S cbfa = 0;
	FILE *fs;
	MALLOC_S len;
	int nf;
	static char *vbuf = (char *)NULL;
	static size_t vsz = (size_t)0;
/*
 * Open the stat file path, assign a page size buffer to its stream,
 * and read the file's first line.
 */
	if (!(fs = open_proc_stream(p, "r", &vbuf, &vsz, 0)))
	    return(-1);
	cp = fgets(buf, sizeof(buf), fs);
	(void) fclose(fs);
	if (!cp)
	    return(-1);
/*
 * Separate the line into fields on white space separators.  Expect five fields
 * for a PID type and three for an LWP type.
 */
	if ((nf = get_fields(buf, (char *)NULL, &fp, (int *)NULL, 0))
	<  (ty ? 5 : 3))
	{
	    return(-1);
	}
/*
 * Convert the first field to an integer; its conversion must match the
 * ID argument.
 */
	if (!fp[0] || (atoi(fp[0]) != id))
	    return(-1);
/*
 * Get the command name from the second field.  Strip a starting '(' and
 * an ending ')'.  Allocate space to hold the result and return the space
 * pointer.
 */
	if (!(cp = fp[1]))
	    return(-1);
	if (cp && *cp == '(')
	    cp++;
	if ((cp1 = strrchr(cp, ')')))
	    *cp1 = '\0';
	if ((len = strlen(cp) + 1) > cbfa) {
	     cbfa = len;
	     if (cbf)
		cbf = (char *)realloc((MALLOC_P *)cbf, cbfa);
	     else
		cbf = (char *)malloc(cbfa);
	     if (!cbf) {
		(void) fprintf(stderr,
		    "%s: can't allocate %d bytes for command \"%s\"\n",
		    Pn, (int)cbfa, cp);
		Exit(1);
	     }
	}
	(void) snpf(cbf, len, "%s", cp);
	*cmd = cbf;
/*
 * Convert and return parent process (fourth field) and process group (fifth
 * field) IDs.
 */
	if (fp[3] && *fp[3])
	    *ppid = atoi(fp[3]);
	else
	    return(-1);
	if (fp[4] && *fp[4])
	    *pgid = atoi(fp[4]);
	else
	    return(-1);
/*
 * Check the state in the third field.  If it is 'Z', return that indication.
 */
	if (fp[2] && !strcmp(fp[2], "Z"))
	    return(1);
	else if (fp[2] && !strcmp(fp[2], "T"))
	    return(2);
	return(0);
}


/*
 * statEx() - extended stat() to get device numbers when a "safe" stat has
 *	      failed and the system has an NFS mount
 *
 * Note: this function was suggested by Paul Szabo as a way to get device
 *       numbers for NFS files when an NFS mount point has the root_squash
 *       option set.  In that case, even if lsof is setuid(root), the identity
 *	 of its requests to stat() NFS files lose root permission and may fail.
 *
 *	 This function should be used only when links have been successfully
 *	 resolved in the /proc path by getlinksrc().
 */

static int
statEx(p, s, ss)
	char *p;			/* file path */
	struct stat *s;			/* stat() result -- NULL if none
					 * wanted */
	int *ss;			/* stat() status --  SB_* values */
{
	static size_t ca = 0;
	static char *cb = NULL;
	char *cp;
	int ensv = ENOENT;
	struct stat sb;
	int st = 0;
	size_t sz;
/*
 * Make a copy of the path.
 */
	sz = strlen(p);
	if ((sz + 1) > ca) {
	    if (cb)
		cb = (char *)realloc((MALLOC_P *)cb, sz + 1);
	    else
		cb = (char *)malloc(sz + 1);
	    if (!cb) {
		(void) fprintf(stderr,
		    "%s: PID %ld: no statEx path space: %s\n",
		    Pn, (long)Lp->pid, p);
		Exit(1);
	    }
	    ca = sz + 1;
	}
	(void) strcpy(cb, p);
/*
 * Trim trailing leaves from the end of the path one at a time and do a safe
 * stat() on each trimmed result.  Stop when a safe stat() succeeds or doesn't
 * fail because of EACCES or EPERM.
 */
	for (cp = strrchr(cb, '/'); cp && (cp != cb);) {
	    *cp = '\0';
	    if (!statsafely(cb, &sb)) {
		st = 1;
		break;
	    }
	    ensv = errno;
	    if ((ensv != EACCES) && (ensv != EPERM))
		break;
	    cp = strrchr(cb, '/');
	}
/*
 * If a stat() on a trimmed result succeeded, form partial results containing
 * only the device and raw device numbers.
 */
	memset((void *)s, 0, sizeof(struct stat));
	if (st) {
	    errno = 0;
	    s->st_dev = sb.st_dev;
	    s->st_rdev = sb.st_rdev;
	    *ss = SB_DEV | SB_RDEV;
	    return(0);
	}
	errno = ensv;
	*ss = 0;
	return(1);
}
