Blame arg.c

Packit Service 603f59
/*
Packit Service 603f59
 * arg.c - common argument processing support functions for lsof
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana
Packit Service 603f59
 * 47907.  All rights reserved.
Packit Service 603f59
 *
Packit Service 603f59
 * Written by Victor A. Abell
Packit Service 603f59
 *
Packit Service 603f59
 * This software is not subject to any license of the American Telephone
Packit Service 603f59
 * and Telegraph Company or the Regents of the University of California.
Packit Service 603f59
 *
Packit Service 603f59
 * Permission is granted to anyone to use this software for any purpose on
Packit Service 603f59
 * any computer system, and to alter it and redistribute it freely, subject
Packit Service 603f59
 * to the following restrictions:
Packit Service 603f59
 *
Packit Service 603f59
 * 1. Neither the authors nor Purdue University are responsible for any
Packit Service 603f59
 *    consequences of the use of this software.
Packit Service 603f59
 *
Packit Service 603f59
 * 2. The origin of this software must not be misrepresented, either by
Packit Service 603f59
 *    explicit claim or by omission.  Credit to the authors and Purdue
Packit Service 603f59
 *    University must appear in documentation and sources.
Packit Service 603f59
 *
Packit Service 603f59
 * 3. Altered versions must be plainly marked as such, and must not be
Packit Service 603f59
 *    misrepresented as being the original software.
Packit Service 603f59
 *
Packit Service 603f59
 * 4. This notice may not be removed or altered.
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
#ifndef lint
Packit Service 603f59
static char copyright[] =
Packit Service 603f59
"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
Packit Service 603f59
static char *rcsid = "$Id: arg.c,v 1.51 2012/04/10 16:30:06 abe Exp abe $";
Packit Service 603f59
#endif
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
#include "lsof.h"
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * Local definitions
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
#define	CMDRXINCR	32		/* CmdRx[] allocation increment */
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * Local static variables
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
static int NCmdRxA = 0;			/* space allocated to CmdRx[] */
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * Local function prototypes
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
_PROTOTYPE(static int ckfd_range,(char *first, char *dash, char *last, int *lo, int *hi));
Packit Service 603f59
_PROTOTYPE(static int enter_fd_lst,(char *nm, int lo, int hi, int excl));
Packit Service 603f59
_PROTOTYPE(static int enter_nwad,(struct nwad *n, int sp, int ep, char *s, struct hostent *he));
Packit Service 603f59
_PROTOTYPE(static struct hostent *lkup_hostnm,(char *hn, struct nwad *n));
Packit Service 603f59
_PROTOTYPE(static char *isIPv4addr,(char *hn, unsigned char *a, int al));
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * ckfd_range() - check fd range
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
static int
Packit Service 603f59
ckfd_range(first, dash, last, lo, hi)
Packit Service 603f59
	char *first;			/* starting character */
Packit Service 603f59
	char *dash;			/* '-' location */
Packit Service 603f59
	char *last;			/* '\0' location */
Packit Service 603f59
	int *lo;			/* returned low value */
Packit Service 603f59
	int *hi;			/* returned high value */
Packit Service 603f59
{
Packit Service 603f59
	char *cp;
Packit Service 603f59
/*
Packit Service 603f59
 * See if the range character pointers make sense.
Packit Service 603f59
 */
Packit Service 603f59
	if (first >= dash || dash >= last) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: illegal FD range for -d: ", Pn);
Packit Service 603f59
	    safestrprt(first, stderr, 1);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Assemble and check the high and low values.
Packit Service 603f59
 */
Packit Service 603f59
	for (cp = first, *lo = 0; *cp && cp < dash; cp++) {
Packit Service 603f59
	    if (!isdigit((unsigned char)*cp)) {
Packit Service 603f59
Packit Service 603f59
FD_range_nondigit:
Packit Service 603f59
Packit Service 603f59
		(void) fprintf(stderr, "%s: non-digit in -d FD range: ", Pn);
Packit Service 603f59
		safestrprt(first, stderr, 1);
Packit Service 603f59
		return(1);
Packit Service 603f59
	    }
Packit Service 603f59
	    *lo = (*lo * 10) + (int)(*cp - '0');
Packit Service 603f59
	}
Packit Service 603f59
	for (cp = dash+1, *hi = 0; *cp && cp < last; cp++) {
Packit Service 603f59
	    if (!isdigit((unsigned char)*cp))
Packit Service 603f59
		goto FD_range_nondigit;
Packit Service 603f59
	    *hi = (*hi * 10) + (int)(*cp - '0');
Packit Service 603f59
	}
Packit Service 603f59
	if (*lo >= *hi) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: -d FD range's low >= its high: ", Pn);
Packit Service 603f59
	    safestrprt(first, stderr, 1);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * ck_file_arg() - check file arguments
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
ck_file_arg(i, ac, av, fv, rs, sbp)
Packit Service 603f59
	int i;			/* first file argument index */
Packit Service 603f59
	int ac;			/* argument count */
Packit Service 603f59
	char *av[];		/* argument vector */
Packit Service 603f59
	int fv;			/* Ffilesys value (real or temporary) */
Packit Service 603f59
	int rs;			/* Readlink() status if argument count == 1:
Packit Service 603f59
				 *	0 = undone; 1 = done */
Packit Service 603f59
	struct stat *sbp;	/* if non-NULL, pointer to stat(2) buffer
Packit Service 603f59
				 * when argument count == 1 */
Packit Service 603f59
{
Packit Service 603f59
	char *ap, *fnm, *fsnm, *path;
Packit Service 603f59
	short err = 0;
Packit Service 603f59
	int fsm, ftype, j, k;
Packit Service 603f59
	MALLOC_S l;
Packit Service 603f59
	struct mounts *mp;
Packit Service 603f59
	static struct mounts **mmp = (struct mounts **)NULL;
Packit Service 603f59
	int mx, nm;
Packit Service 603f59
	static int nma = 0;
Packit Service 603f59
	struct stat sb;
Packit Service 603f59
	struct sfile *sfp;
Packit Service 603f59
	short ss = 0;
Packit Service 603f59
Packit Service 603f59
#if	defined(CKFA_EXPDEV)
Packit Service 603f59
	dev_t dev, rdev;
Packit Service 603f59
#endif	/* defined(CKFA_EXPDEV) */
Packit Service 603f59
Packit Service 603f59
#if	defined(HASPROCFS)
Packit Service 603f59
	unsigned char ad, an;
Packit Service 603f59
	int pfsnl = -1;
Packit Service 603f59
	pid_t pid;
Packit Service 603f59
	struct procfsid *pfi;
Packit Service 603f59
#endif	/* defined(HASPROCFS) */
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * Loop through arguments.
Packit Service 603f59
 */
Packit Service 603f59
	for (; i < ac; i++) {
Packit Service 603f59
	    if (rs && (ac == 1) && (i == 0))
Packit Service 603f59
		path = av[i];
Packit Service 603f59
	    else {
Packit Service 603f59
		if (!(path = Readlink(av[i]))) {
Packit Service 603f59
		    ErrStat = 1;
Packit Service 603f59
		    continue;
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Remove terminating `/' characters from paths longer than one.
Packit Service 603f59
	 */
Packit Service 603f59
	    j = k = strlen(path);
Packit Service 603f59
	    while ((k > 1) && (path[k-1] == '/')) {
Packit Service 603f59
		k--;
Packit Service 603f59
	    }
Packit Service 603f59
	    if (k < j) {
Packit Service 603f59
		if (path != av[i])
Packit Service 603f59
		    path[k] = '\0';
Packit Service 603f59
		else {
Packit Service 603f59
		    if (!(ap = (char *)malloc((MALLOC_S)(k + 1)))) {
Packit Service 603f59
			(void) fprintf(stderr, "%s: no space for copy of %s\n",
Packit Service 603f59
			    Pn, path);
Packit Service 603f59
			Exit(1);
Packit Service 603f59
		    }
Packit Service 603f59
		    (void) strncpy(ap, path, k);
Packit Service 603f59
		    ap[k] = '\0';
Packit Service 603f59
		    path = ap;
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Check for file system argument.
Packit Service 603f59
	 */
Packit Service 603f59
	    for (ftype = 1, mp = readmnt(), nm = 0;
Packit Service 603f59
		 (fv != 1) && mp;
Packit Service 603f59
		 mp = mp->next)
Packit Service 603f59
	    {
Packit Service 603f59
		fsm = 0;
Packit Service 603f59
		if (strcmp(mp->dir, path) == 0)
Packit Service 603f59
		    fsm++;
Packit Service 603f59
		else if (fv == 2 || (mp->fs_mode & S_IFMT) == S_IFBLK) {
Packit Service 603f59
		    if (mp->fsnmres && strcmp(mp->fsnmres, path) == 0)
Packit Service 603f59
			fsm++;
Packit Service 603f59
		}
Packit Service 603f59
		if (!fsm)
Packit Service 603f59
		    continue;
Packit Service 603f59
		ftype = 0;
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Skip duplicates.
Packit Service 603f59
	     */
Packit Service 603f59
		for (mx = 0; mx < nm; mx++) {
Packit Service 603f59
		    if (strcmp(mp->dir, mmp[mx]->dir) == 0
Packit Service 603f59
		    &&  mp->dev == mmp[mx]->dev
Packit Service 603f59
		    &&  mp->rdev == mmp[mx]->rdev
Packit Service 603f59
		    &&  mp->inode == mmp[mx]->inode)
Packit Service 603f59
			break;
Packit Service 603f59
		}
Packit Service 603f59
		if (mx < nm)
Packit Service 603f59
		    continue;
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Allocate space for and save another mount point match and
Packit Service 603f59
	     * the type of match -- directory name (mounted) or file system
Packit Service 603f59
	     * name (mounted-on).
Packit Service 603f59
	     */
Packit Service 603f59
		if (nm >= nma) {
Packit Service 603f59
		    nma += 5;
Packit Service 603f59
		    l = (MALLOC_S)(nma * sizeof(struct mounts *));
Packit Service 603f59
		    if (mmp)
Packit Service 603f59
			mmp = (struct mounts **)realloc((MALLOC_P *)mmp, l);
Packit Service 603f59
		    else
Packit Service 603f59
			mmp = (struct mounts **)malloc(l);
Packit Service 603f59
		    if (!mmp) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: no space for mount pointers\n", Pn);
Packit Service 603f59
			Exit(1);
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
		mmp[nm++] = mp;
Packit Service 603f59
	    }
Packit Service 603f59
	    if (fv == 2 && nm == 0) {
Packit Service 603f59
		(void) fprintf(stderr, "%s: not a file system: ", Pn);
Packit Service 603f59
		safestrprt(av[i], stderr, 1);
Packit Service 603f59
		ErrStat = 1;
Packit Service 603f59
		continue;
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Loop through the file system matches.  If there were none, make one
Packit Service 603f59
	 * pass through the loop, using simply the path name.
Packit Service 603f59
	 */
Packit Service 603f59
	    mx = 0;
Packit Service 603f59
	    do {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Allocate an sfile structure and fill in the type and link.
Packit Service 603f59
	     */
Packit Service 603f59
		if (!(sfp = (struct sfile *)malloc(sizeof(struct sfile)))) {
Packit Service 603f59
		    (void) fprintf(stderr, "%s: no space for files\n", Pn);
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
		sfp->next = Sfile;
Packit Service 603f59
		Sfile = sfp;
Packit Service 603f59
		sfp->f = 0;
Packit Service 603f59
		if ((sfp->type = ftype)) {
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * For a non-file system path, use the path as the file name
Packit Service 603f59
		 * and set a NULL file system name.
Packit Service 603f59
		 */
Packit Service 603f59
		    fnm = path;
Packit Service 603f59
		    fsnm = (char *)NULL;
Packit Service 603f59
		/*
Packit Service 603f59
		 * Stat the path to obtain its characteristics.
Packit Service 603f59
		 */
Packit Service 603f59
		    if (sbp && (ac == 1))
Packit Service 603f59
			sb = *sbp;
Packit Service 603f59
		    else {
Packit Service 603f59
			if (statsafely(fnm, &sb) != 0) {
Packit Service 603f59
			    int en = errno;
Packit Service 603f59
Packit Service 603f59
			    (void) fprintf(stderr, "%s: status error on ", Pn);
Packit Service 603f59
			    safestrprt(fnm, stderr, 0);
Packit Service 603f59
			    (void) fprintf(stderr, ": %s\n", strerror(en));
Packit Service 603f59
			    Sfile = sfp->next;
Packit Service 603f59
			    (void) free((FREE_P *)sfp);
Packit Service 603f59
			    ErrStat = 1;
Packit Service 603f59
			    continue;
Packit Service 603f59
			}
Packit Service 603f59
Packit Service 603f59
#if	defined(HASSPECDEVD)
Packit Service 603f59
			(void) HASSPECDEVD(fnm, &sb);
Packit Service 603f59
#endif	/* defined(HASSPECDEVD) */
Packit Service 603f59
Packit Service 603f59
		    }
Packit Service 603f59
		    sfp->i = (INODETYPE)sb.st_ino;
Packit Service 603f59
		    sfp->mode = sb.st_mode & S_IFMT;
Packit Service 603f59
		
Packit Service 603f59
#if	defined(CKFA_EXPDEV)
Packit Service 603f59
		/*
Packit Service 603f59
		 * Expand device numbers before saving, so that they match the
Packit Service 603f59
		 * already-expanded local mount info table device numbers.
Packit Service 603f59
		 * (This is an EP/IX 2.1.1 and above artifact.)
Packit Service 603f59
		 */
Packit Service 603f59
		    sfp->dev = expdev(sb.st_dev);
Packit Service 603f59
		    sfp->rdev = expdev(sb.st_rdev);
Packit Service 603f59
#else	/* !defined(CKFA_EXPDEV) */
Packit Service 603f59
		    sfp->dev = sb.st_dev;
Packit Service 603f59
		    sfp->rdev = sb.st_rdev;
Packit Service 603f59
#endif	/* defined(CKFA_EXPDEV) */
Packit Service 603f59
Packit Service 603f59
#if	defined(CKFA_MPXCHAN)
Packit Service 603f59
		/*
Packit Service 603f59
		 * Save a (possible) multiplexed channel number.  (This is an
Packit Service 603f59
		 * AIX artifact.)
Packit Service 603f59
		 */
Packit Service 603f59
		    sfp->ch = getchan(path);
Packit Service 603f59
#endif	/* defined(CKFA_MPXCHAN) */
Packit Service 603f59
Packit Service 603f59
		} else {
Packit Service 603f59
Packit Service 603f59
#if	defined(SAVE_MP_IN_SFILE)
Packit Service 603f59
		    sfp->mp = mp = mmp[mx++];
Packit Service 603f59
#else	/* !defined(SAVE_MP_IN_SFILE) */
Packit Service 603f59
		    mp = mmp[mx++];
Packit Service 603f59
#endif	/* defined(SAVE_MP_IN_SFILE) */
Packit Service 603f59
Packit Service 603f59
		    ss++;
Packit Service 603f59
Packit Service 603f59
#if	defined(HASPROCFS)
Packit Service 603f59
		/*
Packit Service 603f59
		 * If this is a /proc file system, set the search flag and
Packit Service 603f59
		 * abandon the sfile entry.
Packit Service 603f59
		 */
Packit Service 603f59
		    if (mp == Mtprocfs) {
Packit Service 603f59
			Sfile = sfp->next;
Packit Service 603f59
			(void) free((FREE_P *)sfp);
Packit Service 603f59
			Procsrch = 1;
Packit Service 603f59
			continue;
Packit Service 603f59
		    }
Packit Service 603f59
#endif	/* defined(HASPROCFS) */
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * Derive file name and file system name for a mount point.
Packit Service 603f59
		 *
Packit Service 603f59
		 * Save the device numbers, inode number, and modes.
Packit Service 603f59
		 */
Packit Service 603f59
		    fnm = mp->dir;
Packit Service 603f59
		    fsnm = mp->fsname;
Packit Service 603f59
		    sfp->dev = mp->dev;
Packit Service 603f59
		    sfp->rdev = mp->rdev;
Packit Service 603f59
		    sfp->i = mp->inode;
Packit Service 603f59
		    sfp->mode = mp->mode & S_IFMT;
Packit Service 603f59
		}
Packit Service 603f59
		ss = 1;		/* indicate a "safe" stat() */
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Store the file name and file system name pointers in the sfile
Packit Service 603f59
	     * structure, allocating space as necessary.
Packit Service 603f59
	     */
Packit Service 603f59
		if (!fnm || fnm == path) {
Packit Service 603f59
		    sfp->name = fnm;
Packit Service 603f59
Packit Service 603f59
#if	defined(HASPROCFS)
Packit Service 603f59
		    an = 0;
Packit Service 603f59
#endif	/* defined(HASPROCFS) */
Packit Service 603f59
Packit Service 603f59
		} else {
Packit Service 603f59
		    if (!(sfp->name = mkstrcpy(fnm, (MALLOC_S *)NULL))) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: no space for file name: ", Pn);
Packit Service 603f59
			safestrprt(fnm, stderr, 1);
Packit Service 603f59
			Exit(1);
Packit Service 603f59
		    }
Packit Service 603f59
Packit Service 603f59
#if	defined(HASPROCFS)
Packit Service 603f59
		    an = 1;
Packit Service 603f59
#endif	/* defined(HASPROCFS) */
Packit Service 603f59
Packit Service 603f59
		}
Packit Service 603f59
		if (!fsnm || fsnm == path) {
Packit Service 603f59
		    sfp->devnm = fsnm;
Packit Service 603f59
Packit Service 603f59
#if	defined(HASPROCFS)
Packit Service 603f59
		    ad = 0;
Packit Service 603f59
#endif	/* defined(HASPROCFS) */
Packit Service 603f59
Packit Service 603f59
		} else {
Packit Service 603f59
		    if (!(sfp->devnm = mkstrcpy(fsnm, (MALLOC_S *)NULL))) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: no space for file system name: ", Pn);
Packit Service 603f59
			safestrprt(fsnm, stderr, 1);
Packit Service 603f59
			Exit(1);
Packit Service 603f59
		    }
Packit Service 603f59
Packit Service 603f59
#if	defined(HASPROCFS)
Packit Service 603f59
		    ad = 1;
Packit Service 603f59
#endif	/* defined(HASPROCFS) */
Packit Service 603f59
Packit Service 603f59
		}
Packit Service 603f59
		if (!(sfp->aname = mkstrcpy(av[i], (MALLOC_S *)NULL))) {
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: no space for argument file name: ", Pn);
Packit Service 603f59
			safestrprt(av[i], stderr, 1);
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
Packit Service 603f59
#if	defined(HASPROCFS)
Packit Service 603f59
	    /*
Packit Service 603f59
	     * See if this is an individual member of a proc file system.
Packit Service 603f59
	     */
Packit Service 603f59
		if (!Mtprocfs || Procsrch)
Packit Service 603f59
		    continue;
Packit Service 603f59
Packit Service 603f59
# if	defined(HASFSTYPE) && HASFSTYPE==1
Packit Service 603f59
		if (strcmp(sb.st_fstype, HASPROCFS) != 0)
Packit Service 603f59
		    continue;
Packit Service 603f59
# endif	/* defined(HASFSTYPE) && HASFSTYPE==1 */
Packit Service 603f59
Packit Service 603f59
		if (pfsnl == -1)
Packit Service 603f59
		    pfsnl = strlen(Mtprocfs->dir);
Packit Service 603f59
		if (!pfsnl)
Packit Service 603f59
		    continue;
Packit Service 603f59
		if (strncmp(Mtprocfs->dir, path, pfsnl) != 0)
Packit Service 603f59
		    continue;
Packit Service 603f59
		if (path[pfsnl] != '/')
Packit Service 603f59
Packit Service 603f59
# if	defined(HASPINODEN)
Packit Service 603f59
		    pid = 0;
Packit Service 603f59
# else	/* !defined(HASPINODEN) */
Packit Service 603f59
		    continue;
Packit Service 603f59
# endif	/* defined(HASPINODEN) */
Packit Service 603f59
Packit Service 603f59
		else {
Packit Service 603f59
		    for (j = pfsnl+1; path[j]; j++) {
Packit Service 603f59
			if (!isdigit((unsigned char)path[j]))
Packit Service 603f59
			    break;
Packit Service 603f59
		    }
Packit Service 603f59
		    if (path[j] || (j - pfsnl - 1) < 1
Packit Service 603f59
		    ||  (sfp->mode & S_IFMT) != S_IFREG)
Packit Service 603f59
Packit Service 603f59
# if	defined(HASPINODEN)
Packit Service 603f59
			pid = 0;
Packit Service 603f59
# else	/* !defined(HASPINODEN) */
Packit Service 603f59
			continue;
Packit Service 603f59
# endif	/* defined(HASPINODEN) */
Packit Service 603f59
Packit Service 603f59
		    else
Packit Service 603f59
			pid = atoi(&path[pfsnl+1]);
Packit Service 603f59
		}
Packit Service 603f59
		if (!(pfi = (struct procfsid *)malloc((MALLOC_S)
Packit Service 603f59
			     sizeof(struct procfsid))))
Packit Service 603f59
		{
Packit Service 603f59
		    (void) fprintf(stderr, "%s: no space for %s ID: ",
Packit Service 603f59
			Pn, Mtprocfs->dir);
Packit Service 603f59
		    safestrprt(path, stderr, 1);
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
		pfi->pid = pid;
Packit Service 603f59
		pfi->f = 0;
Packit Service 603f59
		pfi->nm = sfp->aname;
Packit Service 603f59
		pfi->next = Procfsid;
Packit Service 603f59
		Procfsid = pfi;
Packit Service 603f59
Packit Service 603f59
# if	defined(HASPINODEN)
Packit Service 603f59
		pfi->inode = (INODETYPE)sfp->i;
Packit Service 603f59
# endif	/* defined(HASPINODEN) */
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Abandon the Sfile entry, lest it be used in is_file_named().
Packit Service 603f59
	     */
Packit Service 603f59
		Sfile = sfp->next;
Packit Service 603f59
		if (ad)
Packit Service 603f59
		    (void) free((FREE_P *)sfp->devnm);
Packit Service 603f59
		if (an)
Packit Service 603f59
		    (void) free((FREE_P *)sfp->name);
Packit Service 603f59
		(void) free((FREE_P *)sfp);
Packit Service 603f59
#endif	/* defined(HASPROCFS) */
Packit Service 603f59
Packit Service 603f59
	    } while (mx < nm);
Packit Service 603f59
	}
Packit Service 603f59
	if (!ss)
Packit Service 603f59
	    err = 1;
Packit Service 603f59
	return((int)err);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
#if	defined(HASDCACHE)
Packit Service 603f59
/*
Packit Service 603f59
 * ctrl_dcache() - enter device cache control
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
ctrl_dcache(c)
Packit Service 603f59
	char *c;			/* control string */
Packit Service 603f59
{
Packit Service 603f59
	int rc = 0;
Packit Service 603f59
	
Packit Service 603f59
	if (!c) {
Packit Service 603f59
	    (void) fprintf(stderr,
Packit Service 603f59
		"%s: no device cache option control string\n", Pn);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Decode argument function character.
Packit Service 603f59
 */
Packit Service 603f59
	switch (*c) {
Packit Service 603f59
	case '?':
Packit Service 603f59
	    if (*(c+1) != '\0') {
Packit Service 603f59
		(void) fprintf(stderr, "%s: nothing should follow -D?\n", Pn);
Packit Service 603f59
		return(1);
Packit Service 603f59
	    }
Packit Service 603f59
	    DChelp = 1;
Packit Service 603f59
	    return(0);
Packit Service 603f59
	case 'b':
Packit Service 603f59
	case 'B':
Packit Service 603f59
	    if (Setuidroot
Packit Service 603f59
Packit Service 603f59
#if	!defined(WILLDROPGID)
Packit Service 603f59
	    ||  Myuid
Packit Service 603f59
#endif	/* !defined(WILLDROPGID) */
Packit Service 603f59
Packit Service 603f59
	    )
Packit Service 603f59
		rc = 1;
Packit Service 603f59
	    else
Packit Service 603f59
		DCstate = 1;
Packit Service 603f59
	    break;
Packit Service 603f59
	case 'r':
Packit Service 603f59
	case 'R':
Packit Service 603f59
	    if (Setuidroot && *(c+1))
Packit Service 603f59
		rc = 1;
Packit Service 603f59
	    else
Packit Service 603f59
		DCstate = 2;
Packit Service 603f59
	    break;
Packit Service 603f59
	case 'u':
Packit Service 603f59
	case 'U':
Packit Service 603f59
	    if (Setuidroot
Packit Service 603f59
Packit Service 603f59
#if	!defined(WILLDROPGID)
Packit Service 603f59
	    ||  Myuid
Packit Service 603f59
#endif	/* !defined(WILLDROPGID) */
Packit Service 603f59
Packit Service 603f59
	    )
Packit Service 603f59
		rc = 1;
Packit Service 603f59
	    else
Packit Service 603f59
		DCstate = 3;
Packit Service 603f59
	    break;
Packit Service 603f59
	case 'i':
Packit Service 603f59
	case 'I':
Packit Service 603f59
	    if (*(c+1) == '\0') {
Packit Service 603f59
		DCstate = 0;
Packit Service 603f59
		return(0);
Packit Service 603f59
	    }
Packit Service 603f59
	    /* fall through */
Packit Service 603f59
	default:
Packit Service 603f59
	    (void) fprintf(stderr, "%s: unknown -D option: ", Pn);
Packit Service 603f59
	    safestrprt(c, stderr, 1);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	if (rc) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: -D option restricted to root: ", Pn);
Packit Service 603f59
	    safestrprt(c, stderr, 1);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Skip to optional path name and save it.
Packit Service 603f59
 */
Packit Service 603f59
	for (c++; *c && (*c == ' ' || *c == '\t'); c++)
Packit Service 603f59
	    ;
Packit Service 603f59
	if (strlen(c)) {
Packit Service 603f59
	    if (!(DCpathArg = mkstrcpy(c, (MALLOC_S *)NULL))) {
Packit Service 603f59
		(void) fprintf(stderr, "%s: no space for -D path: ", Pn);
Packit Service 603f59
		safestrprt(c, stderr, 1);
Packit Service 603f59
		Exit(1);
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
#endif	/* defined(HASDCACHE) */
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_cmd_rx() - enter command regular expression
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_cmd_rx(x)
Packit Service 603f59
	char *x;			/* regular expression */
Packit Service 603f59
{
Packit Service 603f59
	int bmod = 0;
Packit Service 603f59
	int bxmod = 0;
Packit Service 603f59
	int i, re;
Packit Service 603f59
	int imod = 0;
Packit Service 603f59
	int xmod = 0;
Packit Service 603f59
	int co = REG_NOSUB|REG_EXTENDED;
Packit Service 603f59
	char reb[256], *xb, *xe, *xm;
Packit Service 603f59
	MALLOC_S xl;
Packit Service 603f59
	char *xp = (char *)NULL;
Packit Service 603f59
/*
Packit Service 603f59
 * Make sure the supplied string starts a regular expression.
Packit Service 603f59
 */
Packit Service 603f59
	if (!*x || (*x != '/')) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: regexp doesn't begin with '/': ", Pn);
Packit Service 603f59
	    if (x)
Packit Service 603f59
		safestrprt(x, stderr, 1);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Skip to the end ('/') of the regular expression.
Packit Service 603f59
 */
Packit Service 603f59
	xb = x + 1;
Packit Service 603f59
	for (xe = xb; *xe; xe++) {
Packit Service 603f59
	    if (*xe == '/')
Packit Service 603f59
		break;
Packit Service 603f59
	}
Packit Service 603f59
	if (*xe != '/') {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: regexp doesn't end with '/': ", Pn);
Packit Service 603f59
	    safestrprt(x, stderr, 1);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Decode any regular expression modifiers.
Packit Service 603f59
 */
Packit Service 603f59
	for (i = 0, xm = xe + 1; *xm; xm++) {
Packit Service 603f59
	    switch(*xm) {
Packit Service 603f59
	    case 'b':			/* This is a basic expression. */
Packit Service 603f59
		if (++bmod > 1) {
Packit Service 603f59
		    if (bmod == 2) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: b regexp modifier already used: ", Pn);
Packit Service 603f59
			safestrprt(x, stderr, 1);
Packit Service 603f59
		    }
Packit Service 603f59
		    i = 1;
Packit Service 603f59
		} else if (xmod) {
Packit Service 603f59
		    if (++bxmod == 1) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: b and x regexp modifiers conflict: ", Pn);
Packit Service 603f59
			safestrprt(x, stderr, 1);
Packit Service 603f59
		    }
Packit Service 603f59
		    i = 1;
Packit Service 603f59
		} else
Packit Service 603f59
		    co &= ~REG_EXTENDED;
Packit Service 603f59
		break;
Packit Service 603f59
	    case 'i':			/* Ignore case. */
Packit Service 603f59
		if (++imod > 1) {
Packit Service 603f59
		    if (imod == 2) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: i regexp modifier already used: ", Pn);
Packit Service 603f59
			safestrprt(x, stderr, 1);
Packit Service 603f59
		    }
Packit Service 603f59
		    i = 1;
Packit Service 603f59
		} else
Packit Service 603f59
		    co |= REG_ICASE;
Packit Service 603f59
		break;
Packit Service 603f59
	    case 'x':			/* This is an extended expression. */
Packit Service 603f59
		if (++xmod > 1) {
Packit Service 603f59
		    if (xmod == 2) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: x regexp modifier already used: ", Pn);
Packit Service 603f59
			safestrprt(x, stderr, 1);
Packit Service 603f59
		    }
Packit Service 603f59
		    i = 1;
Packit Service 603f59
		} else if (bmod) {
Packit Service 603f59
		    if (++bxmod == 1) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: b and x regexp modifiers conflict: ", Pn);
Packit Service 603f59
			safestrprt(x, stderr, 1);
Packit Service 603f59
		    }
Packit Service 603f59
		    i = 1;
Packit Service 603f59
		} else
Packit Service 603f59
		    co |= REG_EXTENDED;
Packit Service 603f59
		break;
Packit Service 603f59
	    default:
Packit Service 603f59
		(void) fprintf(stderr, "%s: invalid regexp modifier: %c\n",
Packit Service 603f59
		Pn, (int)*xm);
Packit Service 603f59
		i = 1;
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
	if (i)
Packit Service 603f59
	    return(1);
Packit Service 603f59
/*
Packit Service 603f59
 * Allocate space to hold expression and copy it there.
Packit Service 603f59
 */
Packit Service 603f59
	xl = (MALLOC_S)(xe - xb);
Packit Service 603f59
	if (!(xp = (char *)malloc(xl + 1))) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no regexp space for: ", Pn);
Packit Service 603f59
	    safestrprt(x, stderr, 1);
Packit Service 603f59
	    Exit(1);
Packit Service 603f59
	}
Packit Service 603f59
	(void) strncpy(xp, xb, xl);
Packit Service 603f59
	xp[(int)xl] = '\0';
Packit Service 603f59
/*
Packit Service 603f59
 * Assign a new CmdRx[] slot for this expression.
Packit Service 603f59
 */
Packit Service 603f59
	if (NCmdRxA >= NCmdRxU) {
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * More CmdRx[] space must be assigned.
Packit Service 603f59
	 */
Packit Service 603f59
	    NCmdRxA += CMDRXINCR;
Packit Service 603f59
	    xl = (MALLOC_S)(NCmdRxA * sizeof(lsof_rx_t));
Packit Service 603f59
	    if (CmdRx)
Packit Service 603f59
		CmdRx = (lsof_rx_t *)realloc((MALLOC_P *)CmdRx, xl);
Packit Service 603f59
	    else
Packit Service 603f59
		CmdRx = (lsof_rx_t *)malloc(xl);
Packit Service 603f59
	    if (!CmdRx) {
Packit Service 603f59
		(void) fprintf(stderr, "%s: no space for regexp: ", Pn);
Packit Service 603f59
		safestrprt(x, stderr, 1);
Packit Service 603f59
		Exit(1);
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
	i = NCmdRxU;
Packit Service 603f59
	CmdRx[i].exp = xp;
Packit Service 603f59
/*
Packit Service 603f59
 * Compile the expression.
Packit Service 603f59
 */
Packit Service 603f59
	if ((re = regcomp(&CmdRx[i].cx, xp, co))) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: regexp error: ", Pn);
Packit Service 603f59
	    safestrprt(x, stderr, 0);
Packit Service 603f59
	    (void) regerror(re, &CmdRx[i].cx, &reb[0], sizeof(reb));
Packit Service 603f59
	    (void) fprintf(stderr, ": %s\n", reb);
Packit Service 603f59
	    if (xp) {
Packit Service 603f59
		(void) free((FREE_P *)xp);
Packit Service 603f59
		xp = (char *)NULL;
Packit Service 603f59
	    }
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Complete the CmdRx[] table entry.
Packit Service 603f59
 */
Packit Service 603f59
	CmdRx[i].mc = 0;
Packit Service 603f59
	CmdRx[i].exp = xp;
Packit Service 603f59
	NCmdRxU++;
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
#if	defined(HASEOPT)
Packit Service 603f59
/*
Packit Service 603f59
 * enter_efsys() -- enter path of file system whose kernel blocks are to be
Packit Service 603f59
 *		    eliminated
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_efsys(e, rdlnk)
Packit Service 603f59
	char *e;			/* file system path */
Packit Service 603f59
	int rdlnk;			/* avoid readlink(2) if non-zero */
Packit Service 603f59
{
Packit Service 603f59
	char *ec;			/* pointer to copy of path */
Packit Service 603f59
	efsys_list_t *ep;		/* file system path list pointer */
Packit Service 603f59
	int i;				/* temporary index */
Packit Service 603f59
	char *path;			/* Readlink() of file system path */
Packit Service 603f59
Packit Service 603f59
	if (!e || (*e != '/')) {
Packit Service 603f59
	    if (!Fwarn)
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: -e not followed by a file system path: \"%s\"\n",
Packit Service 603f59
		    Pn, e);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	if (!(ec = mkstrcpy(e, (MALLOC_S *)NULL))) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no space for -e string: ", Pn);
Packit Service 603f59
	    safestrprt(e, stderr, 1);
Packit Service 603f59
	    Exit(1);
Packit Service 603f59
	}
Packit Service 603f59
	if (rdlnk)
Packit Service 603f59
	    path = ec;
Packit Service 603f59
	else {
Packit Service 603f59
	    if (!(path = Readlink(ec)))
Packit Service 603f59
		return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Remove terminating `/' characters from paths longer than one.
Packit Service 603f59
 */
Packit Service 603f59
	for (i = (int)strlen(path); (i > 1) && (path[i - 1] == '/'); i--) {
Packit Service 603f59
	    path[i - 1] = '\0';
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Enter file system path on list, avoiding duplicates.
Packit Service 603f59
 */
Packit Service 603f59
	for (ep = Efsysl; ep; ep = ep->next) {
Packit Service 603f59
	   if (!strcmp(ep->path, path)) {
Packit Service 603f59
		(void)free((FREE_P *)path);
Packit Service 603f59
		return (0);
Packit Service 603f59
	   }
Packit Service 603f59
	}
Packit Service 603f59
	if (!(ep = (efsys_list_t *)malloc((MALLOC_S)(sizeof(efsys_list_t))))) {
Packit Service 603f59
	   (void) fprintf(stderr, "%s: no space for \"-e %s\" entry\n",
Packit Service 603f59
		Pn, e);
Packit Service 603f59
	   Exit(1);
Packit Service 603f59
	}
Packit Service 603f59
	ep->path = path;
Packit Service 603f59
	ep->pathl = i;
Packit Service 603f59
	ep->rdlnk = rdlnk;
Packit Service 603f59
	ep->mp = (struct mounts *)NULL;
Packit Service 603f59
	ep->next = Efsysl;
Packit Service 603f59
	Efsysl = ep;
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
#endif	/* defined(HASEOPT) */
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_fd() - enter file descriptor list for searching
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_fd(f)
Packit Service 603f59
	char *f;			/* file descriptor list pointer */
Packit Service 603f59
{
Packit Service 603f59
	char c, *cp1, *cp2, *dash;
Packit Service 603f59
	int err, excl, hi, lo;
Packit Service 603f59
	char *fc;
Packit Service 603f59
/*
Packit Service 603f59
 *  Check for non-empty list and make a copy.
Packit Service 603f59
 */
Packit Service 603f59
	if (!f || (strlen(f) + 1) < 2) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no file descriptor specified\n", Pn);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	if (!(fc = mkstrcpy(f, (MALLOC_S *)NULL))) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no space for fd string: ", Pn);
Packit Service 603f59
	    safestrprt(f, stderr, 1);
Packit Service 603f59
	    Exit(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Isolate each file descriptor in the comma-separated list, then enter it
Packit Service 603f59
 * in the file descriptor string list.  If a descriptor has the form:
Packit Service 603f59
 *
Packit Service 603f59
 *	[0-9]+-[0-9]+
Packit Service 603f59
 *
Packit Service 603f59
 * treat it as an ascending range of file descriptor numbers.
Packit Service 603f59
 *
Packit Service 603f59
 * Accept a leading '^' as an excusion on match.
Packit Service 603f59
 */
Packit Service 603f59
	for (cp1 = fc, err = 0; *cp1;) {
Packit Service 603f59
	    if (*cp1 == '^') {
Packit Service 603f59
		excl = 1;
Packit Service 603f59
		cp1++;
Packit Service 603f59
	    } else
Packit Service 603f59
		excl = 0;
Packit Service 603f59
	    for (cp2 = cp1, dash = (char *)NULL; *cp2 && *cp2 != ','; cp2++) {
Packit Service 603f59
		if (*cp2 == '-')
Packit Service 603f59
		    dash = cp2;
Packit Service 603f59
	    }
Packit Service 603f59
	    if ((c = *cp2) != '\0')
Packit Service 603f59
		*cp2 = '\0';
Packit Service 603f59
	    if (cp2 > cp1) {
Packit Service 603f59
		if (dash) {
Packit Service 603f59
		    if (ckfd_range(cp1, dash, cp2, &lo, &hi))
Packit Service 603f59
			err = 1;
Packit Service 603f59
		    else {
Packit Service 603f59
			if (enter_fd_lst((char *)NULL, lo, hi, excl))
Packit Service 603f59
			    err = 1;
Packit Service 603f59
		    }
Packit Service 603f59
		} else {
Packit Service 603f59
		    if (enter_fd_lst(cp1, 0, 0, excl))
Packit Service 603f59
			err = 1;
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    if (c == '\0')
Packit Service 603f59
		break;
Packit Service 603f59
	    cp1 = cp2 + 1;
Packit Service 603f59
	}
Packit Service 603f59
	(void) free((FREE_P *)fc);
Packit Service 603f59
	return(err);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_fd_lst() - make an entry in the FD list, Fdl
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
static int
Packit Service 603f59
enter_fd_lst(nm, lo, hi, excl)
Packit Service 603f59
	char *nm;			/* FD name (none if NULL) */
Packit Service 603f59
	int lo;				/* FD low boundary (if nm NULL) */
Packit Service 603f59
	int hi;				/* FD high boundary (if nm NULL) */
Packit Service 603f59
	int excl;			/* exclusion on match */
Packit Service 603f59
{
Packit Service 603f59
	char buf[256], *cp;
Packit Service 603f59
	int n;
Packit Service 603f59
	struct fd_lst *f, *ft;
Packit Service 603f59
/*
Packit Service 603f59
 * Don't allow a mixture of exclusions and inclusions.
Packit Service 603f59
 */
Packit Service 603f59
	if (FdlTy >= 0) {
Packit Service 603f59
	    if (FdlTy != excl) {
Packit Service 603f59
		if (!Fwarn) {
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * If warnings are enabled, report a mixture.
Packit Service 603f59
		 */
Packit Service 603f59
		    if (nm) {
Packit Service 603f59
			(void) snpf(buf, sizeof(buf) - 1, "%s%s",
Packit Service 603f59
			    excl ? "^" : "", nm);
Packit Service 603f59
		    } else {
Packit Service 603f59
			if (lo != hi) {
Packit Service 603f59
			    (void) snpf(buf, sizeof(buf) - 1, "%s%d-%d",
Packit Service 603f59
				excl ? "^" : "", lo, hi);
Packit Service 603f59
			} else {
Packit Service 603f59
			    (void) snpf(buf, sizeof(buf) - 1, "%s%d",
Packit Service 603f59
				excl ? "^" : "", lo);
Packit Service 603f59
			}
Packit Service 603f59
		    }
Packit Service 603f59
		    buf[sizeof(buf) - 1] = '\0';
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
		        "%s: %s in an %s -d list: %s\n", Pn,
Packit Service 603f59
			excl ? "exclude" : "include",
Packit Service 603f59
			FdlTy ? "exclude" : "include",
Packit Service 603f59
			buf);
Packit Service 603f59
		}
Packit Service 603f59
		return(1);
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Allocate an fd_lst entry.
Packit Service 603f59
 */
Packit Service 603f59
	if (!(f = (struct fd_lst *)malloc((MALLOC_S)sizeof(struct fd_lst)))) {
Packit Service 603f59
	   (void) fprintf(stderr, "%s: no space for FD list entry\n", Pn);
Packit Service 603f59
	   Exit(1);
Packit Service 603f59
	}
Packit Service 603f59
	if (nm) {
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * Process an FD name.  First see if it contains only digits; if it
Packit Service 603f59
	 * does, convert them to an integer and set the low and high
Packit Service 603f59
	 * boundaries to the result.
Packit Service 603f59
	 *
Packit Service 603f59
	 * If the name has a non-digit, store it as a string, and set the
Packit Service 603f59
	 * boundaries to impossible values (i.e., low > high).
Packit Service 603f59
	 */
Packit Service 603f59
	    for (cp = nm, n = 0; *cp; cp++) {
Packit Service 603f59
		if (!isdigit((unsigned char)*cp))
Packit Service 603f59
		    break;
Packit Service 603f59
		n = (n * 10) + (int)(*cp - '0');
Packit Service 603f59
	    }
Packit Service 603f59
	    if (*cp) {
Packit Service 603f59
		if (!(f->nm = mkstrcpy(nm, (MALLOC_S *)NULL))) {
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: no space for copy of: %s\n", Pn, nm);
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
		lo = 1;
Packit Service 603f59
		hi = 0;
Packit Service 603f59
	    } else {
Packit Service 603f59
		f->nm = (char *)NULL;
Packit Service 603f59
		lo = hi = n;
Packit Service 603f59
	    }
Packit Service 603f59
	} else
Packit Service 603f59
	    f->nm = (char *)NULL;
Packit Service 603f59
/*
Packit Service 603f59
 * Skip duplicates.
Packit Service 603f59
 */
Packit Service 603f59
	for (ft = Fdl; ft; ft = ft->next) {
Packit Service 603f59
	    if (f->nm) {
Packit Service 603f59
		if (!ft->nm || strcmp(f->nm, ft->nm))
Packit Service 603f59
		    continue;
Packit Service 603f59
	    } else if ((lo != ft->lo) || (hi != ft->hi))
Packit Service 603f59
		continue;
Packit Service 603f59
	    (void) free((FREE_P *)f);
Packit Service 603f59
	    return(0);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Complete the fd_lst entry and link it to the head of the chain.
Packit Service 603f59
 */
Packit Service 603f59
	f->hi = hi;
Packit Service 603f59
	f->lo = lo;
Packit Service 603f59
	f->next = Fdl;
Packit Service 603f59
	Fdl = f;
Packit Service 603f59
	FdlTy = excl;
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_dir() - enter the files of a directory for searching
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
#define	EDDEFFNL	128		/* default file name length */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_dir(d, descend)
Packit Service 603f59
	char *d;			/* directory path name pointer */
Packit Service 603f59
	int descend;			/* subdirectory descend flag:
Packit Service 603f59
					 *	0 = don't descend
Packit Service 603f59
					 *	1 = descend */
Packit Service 603f59
{
Packit Service 603f59
	char *av[2];
Packit Service 603f59
	dev_t ddev;
Packit Service 603f59
	DIR *dfp;
Packit Service 603f59
	char *dn = (char *)NULL;
Packit Service 603f59
	MALLOC_S dnl, dnamlen;
Packit Service 603f59
	struct DIRTYPE *dp;
Packit Service 603f59
	int en, sl;
Packit Service 603f59
	int fct = 0;
Packit Service 603f59
	char *fp = (char *)NULL;
Packit Service 603f59
	MALLOC_S fpl = (MALLOC_S)0;
Packit Service 603f59
	MALLOC_S fpli = (MALLOC_S)0;
Packit Service 603f59
	struct stat sb;
Packit Service 603f59
/*
Packit Service 603f59
 * Check the directory path; reduce symbolic links; stat(2) it; make sure it's
Packit Service 603f59
 * really a directory.
Packit Service 603f59
 */
Packit Service 603f59
	if (!d || !*d || *d == '+' || *d == '-') {
Packit Service 603f59
	    if (!Fwarn)
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: +d not followed by a directory path\n", Pn);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	if (!(dn = Readlink(d)))
Packit Service 603f59
	    return(1);
Packit Service 603f59
	if (statsafely(dn, &sb)) {
Packit Service 603f59
	    if (!Fwarn) {
Packit Service 603f59
		en = errno;
Packit Service 603f59
		(void) fprintf(stderr, "%s: WARNING: can't stat(", Pn);
Packit Service 603f59
		safestrprt(dn, stderr, 0);
Packit Service 603f59
		(void) fprintf(stderr, "): %s\n", strerror(en));
Packit Service 603f59
	    }
Packit Service 603f59
	    if (dn && dn != d) {
Packit Service 603f59
		(void) free((FREE_P *)dn);
Packit Service 603f59
		dn = (char *)NULL;
Packit Service 603f59
	    }
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	if ((sb.st_mode & S_IFMT) != S_IFDIR) {
Packit Service 603f59
	    if (!Fwarn) {
Packit Service 603f59
		(void) fprintf(stderr, "%s: WARNING: not a directory: ", Pn);
Packit Service 603f59
		safestrprt(dn, stderr, 1);
Packit Service 603f59
	    }
Packit Service 603f59
	    if (dn && dn != d) {
Packit Service 603f59
		(void) free((FREE_P *)dn);
Packit Service 603f59
		dn = (char *)NULL;
Packit Service 603f59
	    }
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
Packit Service 603f59
#if	defined(HASSPECDEVD)
Packit Service 603f59
	(void) HASSPECDEVD(dn, &sb);
Packit Service 603f59
#endif	/* defined(HASSPECDEVD) */
Packit Service 603f59
Packit Service 603f59
	ddev = sb.st_dev;
Packit Service 603f59
/*
Packit Service 603f59
 * Stack the directory and record it in Sfile for searching.
Packit Service 603f59
 */
Packit Service 603f59
	Dstkn = Dstkx = 0;
Packit Service 603f59
	Dstk = (char **)NULL;
Packit Service 603f59
	(void) stkdir(dn);
Packit Service 603f59
	av[0] = (dn == d) ? mkstrcpy(dn, (MALLOC_S *)NULL) : dn;
Packit Service 603f59
	av[1] = (char *)NULL;
Packit Service 603f59
	dn = (char *)NULL;
Packit Service 603f59
	if (!ck_file_arg(0, 1, av, 1, 1, &sb)) {
Packit Service 603f59
	    av[0] = (char *)NULL;
Packit Service 603f59
	    fct++;
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Unstack the next directory and examine it.
Packit Service 603f59
 */
Packit Service 603f59
	while (--Dstkx >= 0) {
Packit Service 603f59
	    if (!(dn = Dstk[Dstkx]))
Packit Service 603f59
		continue;
Packit Service 603f59
	    Dstk[Dstkx] = (char *)NULL;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Open the directory path and prepare its name for use with the
Packit Service 603f59
	 * files in the directory.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (!(dfp = OpenDir(dn))) {
Packit Service 603f59
		if (!Fwarn) {
Packit Service 603f59
		    if ((en = errno) != ENOENT) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: WARNING: can't opendir(", Pn);
Packit Service 603f59
			safestrprt(dn, stderr, 0);
Packit Service 603f59
			(void) fprintf(stderr, "): %s\n", strerror(en));
Packit Service 603f59
		    }
Packit Service 603f59
	        }
Packit Service 603f59
		(void) free((FREE_P *)dn);
Packit Service 603f59
		dn = (char *)NULL;
Packit Service 603f59
		continue;
Packit Service 603f59
	    }
Packit Service 603f59
	    dnl = strlen(dn);
Packit Service 603f59
	    sl = ((dnl > 0) && (*(dn + dnl - 1) == '/')) ? 0 : 1;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Define space for possible addition to the directory path.
Packit Service 603f59
	 */
Packit Service 603f59
	    fpli = (MALLOC_S)(dnl + sl + EDDEFFNL + 1);
Packit Service 603f59
	    if ((int)fpli > (int)fpl) {
Packit Service 603f59
		fpl = fpli;
Packit Service 603f59
		if (!fp)
Packit Service 603f59
		    fp = (char *)malloc(fpl);
Packit Service 603f59
		else
Packit Service 603f59
		    fp = (char *)realloc(fp, fpl);
Packit Service 603f59
		if (!fp) {
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: no space for path to entries in directory: %s\n",
Packit Service 603f59
			Pn, dn);
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    (void) snpf(fp, (size_t)fpl, "%s%s", dn, sl ? "/" : "");
Packit Service 603f59
	    (void) free((FREE_P *)dn);
Packit Service 603f59
	    dn = (char *)NULL;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Read the contents of the directory.
Packit Service 603f59
	 */
Packit Service 603f59
	    for (dp = ReadDir(dfp); dp; dp = ReadDir(dfp)) {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Skip: entries with no inode number;
Packit Service 603f59
	     *	     entries with a zero length name;
Packit Service 603f59
	     *	     ".";
Packit Service 603f59
	     *	     and "..".
Packit Service 603f59
	     */
Packit Service 603f59
		if (!dp->d_ino)
Packit Service 603f59
		    continue;
Packit Service 603f59
Packit Service 603f59
#if     defined(HASDNAMLEN)
Packit Service 603f59
		dnamlen = (MALLOC_S)dp->d_namlen;
Packit Service 603f59
#else   /* !defined(HASDNAMLEN) */
Packit Service 603f59
		dnamlen = (MALLOC_S)strlen(dp->d_name);
Packit Service 603f59
#endif  /* defined(HASDNAMLEN) */
Packit Service 603f59
Packit Service 603f59
		if (!dnamlen)
Packit Service 603f59
		    continue;
Packit Service 603f59
		if (dnamlen <= 2 && dp->d_name[0] == '.') {
Packit Service 603f59
		    if (dnamlen == 1)
Packit Service 603f59
			continue;
Packit Service 603f59
		    if (dp->d_name[1] == '.')
Packit Service 603f59
			continue;
Packit Service 603f59
		}
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Form the entry's path name.
Packit Service 603f59
	     */
Packit Service 603f59
		fpli = (MALLOC_S)(dnamlen - (fpl - dnl - sl - 1));
Packit Service 603f59
		if ((int)fpli > 0) {
Packit Service 603f59
		    fpl += fpli;
Packit Service 603f59
		    if (!(fp = (char *)realloc(fp, fpl))) {
Packit Service 603f59
			(void) fprintf(stderr, "%s: no space for: ", Pn);
Packit Service 603f59
			safestrprt(dn, stderr, 0);
Packit Service 603f59
			putc('/', stderr);
Packit Service 603f59
			safestrprtn(dp->d_name, dnamlen, stderr, 1);
Packit Service 603f59
			Exit(1);
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
		(void) strncpy(fp + dnl + sl, dp->d_name, dnamlen);
Packit Service 603f59
		fp[dnl + sl + dnamlen] = '\0';
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Lstatsafely() the entry; complain if that fails.
Packit Service 603f59
	     *
Packit Service 603f59
	     * Stack entries that represent subdirectories.
Packit Service 603f59
	     */
Packit Service 603f59
		if (lstatsafely(fp, &sb)) {
Packit Service 603f59
		    if ((en = errno) != ENOENT) {
Packit Service 603f59
			if (!Fwarn) {
Packit Service 603f59
			    (void) fprintf(stderr,
Packit Service 603f59
				"%s: WARNING: can't lstat(", Pn);
Packit Service 603f59
			    safestrprt(fp, stderr, 0);
Packit Service 603f59
			    (void) fprintf(stderr, "): %s\n", strerror(en));
Packit Service 603f59
			}
Packit Service 603f59
		    }
Packit Service 603f59
		    continue;
Packit Service 603f59
		}
Packit Service 603f59
Packit Service 603f59
#if	defined(HASSPECDEVD)
Packit Service 603f59
		(void) HASSPECDEVD(fp, &sb);
Packit Service 603f59
#endif	/* defined(HASSPECDEVD) */
Packit Service 603f59
Packit Service 603f59
		if (!(Fxover & XO_FILESYS)) {
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * Unless "-x" or "-x f" was specified, don't cross over file
Packit Service 603f59
		 * system mount points.
Packit Service 603f59
		 */
Packit Service 603f59
		    if (sb.st_dev != ddev)
Packit Service 603f59
			continue;
Packit Service 603f59
		}
Packit Service 603f59
		if ((sb.st_mode & S_IFMT) == S_IFLNK) {
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * If this is a symbolic link and "-x_ or "-x l" was specified,
Packit Service 603f59
		 * Statsafely() the entry and process it.
Packit Service 603f59
		 *
Packit Service 603f59
		 * Otherwise skip symbolic links.
Packit Service 603f59
		 */
Packit Service 603f59
		    if (Fxover & XO_SYMLINK) {
Packit Service 603f59
			if (statsafely(fp, &sb)) {
Packit Service 603f59
			    if ((en = errno) != ENOENT) {
Packit Service 603f59
				if (!Fwarn) {
Packit Service 603f59
				    (void) fprintf(stderr,
Packit Service 603f59
					"%s: WARNING: can't stat(", Pn);
Packit Service 603f59
				    safestrprt(fp, stderr, 0);
Packit Service 603f59
				    (void) fprintf(stderr,
Packit Service 603f59
					") symbolc link: %s\n", strerror(en));
Packit Service 603f59
				}
Packit Service 603f59
			    }
Packit Service 603f59
			    continue;
Packit Service 603f59
		        }
Packit Service 603f59
		    } else
Packit Service 603f59
			continue;
Packit Service 603f59
		}
Packit Service 603f59
		if (av[0]) {
Packit Service 603f59
		    (void) free((FREE_P *)av[0]);
Packit Service 603f59
		    av[0] = (char *)NULL;
Packit Service 603f59
		}
Packit Service 603f59
		av[0] = mkstrcpy(fp, (MALLOC_S *)NULL);
Packit Service 603f59
		if ((sb.st_mode & S_IFMT) == S_IFDIR && descend)
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * Stack a subdirectory according to the descend argument.
Packit Service 603f59
		 */
Packit Service 603f59
		    stkdir(av[0]);
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Use ck_file_arg() to record the entry for searching.  Force it
Packit Service 603f59
	     * to consider the entry a file, not a file system.
Packit Service 603f59
	     */
Packit Service 603f59
		if (!ck_file_arg(0, 1, av, 1, 1, &sb)) {
Packit Service 603f59
		    av[0] = (char *)NULL;
Packit Service 603f59
		    fct++;
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    (void) CloseDir(dfp);
Packit Service 603f59
	    if (dn && dn != d) {
Packit Service 603f59
		(void) free((FREE_P *)dn);
Packit Service 603f59
		dn = (char *)NULL;
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Free malloc()'d space.
Packit Service 603f59
 */
Packit Service 603f59
	if (dn && dn != d) {
Packit Service 603f59
	    (void) free((FREE_P *)dn);
Packit Service 603f59
	    dn = (char *)NULL;
Packit Service 603f59
	}
Packit Service 603f59
	if (av[0] && av[0] != fp) {
Packit Service 603f59
	    (void) free((FREE_P *)av[0]);
Packit Service 603f59
	    av[0] = (char *)NULL;
Packit Service 603f59
	}
Packit Service 603f59
	if (fp) {
Packit Service 603f59
	    (void) free((FREE_P *)fp);
Packit Service 603f59
	    fp = (char *)NULL;
Packit Service 603f59
	}
Packit Service 603f59
	if (Dstk) {
Packit Service 603f59
	    (void) free((FREE_P *)Dstk);
Packit Service 603f59
	    Dstk = (char **)NULL;
Packit Service 603f59
	}
Packit Service 603f59
	if (!fct) {
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * Warn if no files were recorded for searching.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (!Fwarn) {
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: WARNING: no files found in directory: ", Pn);
Packit Service 603f59
		safestrprt(d, stderr, 1);
Packit Service 603f59
	    }
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_id() - enter PGID or PID for searching
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_id(ty, p)
Packit Service 603f59
	enum IDType ty;			/* type: PGID or PID */
Packit Service 603f59
	char *p;			/* process group ID string pointer */
Packit Service 603f59
{
Packit Service 603f59
	char *cp;
Packit Service 603f59
	int err, i, id, j, mx, n, ni, nx, x;
Packit Service 603f59
	struct int_lst *s;
Packit Service 603f59
Packit Service 603f59
	if (!p) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no process%s ID specified\n",
Packit Service 603f59
		Pn, (ty == PGID) ? " group" : "");
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Set up variables for the type of ID.
Packit Service 603f59
 */
Packit Service 603f59
	switch (ty) {
Packit Service 603f59
	case PGID:
Packit Service 603f59
	    mx = Mxpgid;
Packit Service 603f59
	    n = Npgid;
Packit Service 603f59
	    ni = Npgidi;
Packit Service 603f59
	    nx = Npgidx;
Packit Service 603f59
	    s = Spgid;
Packit Service 603f59
	    break;
Packit Service 603f59
	case PID:
Packit Service 603f59
	    mx = Mxpid;
Packit Service 603f59
	    n = Npid;
Packit Service 603f59
	    ni = Npidi;
Packit Service 603f59
	    nx = Npidx;
Packit Service 603f59
	    s = Spid;
Packit Service 603f59
	    break;
Packit Service 603f59
	default:
Packit Service 603f59
	    (void) fprintf(stderr, "%s: enter_id \"", Pn);
Packit Service 603f59
	    safestrprt(p, stderr, 0);
Packit Service 603f59
	    (void) fprintf(stderr, "\", invalid type: %d\n", ty);
Packit Service 603f59
	    Exit(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Convert and store the ID.
Packit Service 603f59
 */
Packit Service 603f59
	for (cp = p, err = 0; *cp;) {
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * Assemble ID.
Packit Service 603f59
	 */
Packit Service 603f59
	    for (i = id = x = 0; *cp && *cp != ','; cp++) {
Packit Service 603f59
		if (!i) {
Packit Service 603f59
		    i = 1;
Packit Service 603f59
		    if (*cp == '^') {
Packit Service 603f59
			x = 1;
Packit Service 603f59
			continue;
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
Packit Service 603f59
#if	defined(__STDC__)
Packit Service 603f59
		if (!isdigit((unsigned char)*cp))
Packit Service 603f59
#else	/* !defined(__STDC__) */
Packit Service 603f59
		if (!isascii(*cp) || ! isdigit((unsigned char)*cp))
Packit Service 603f59
#endif	/* __STDC__ */
Packit Service 603f59
Packit Service 603f59
		{
Packit Service 603f59
		    (void) fprintf(stderr, "%s: illegal process%s ID: ",
Packit Service 603f59
			Pn, (ty == PGID) ? " group" : "");
Packit Service 603f59
		    safestrprt(p, stderr, 1);
Packit Service 603f59
		    return(1);
Packit Service 603f59
		}
Packit Service 603f59
		id = (id * 10) + *cp - '0';
Packit Service 603f59
	    }
Packit Service 603f59
	    if (*cp)
Packit Service 603f59
		cp++;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Avoid entering duplicates and conflicts.
Packit Service 603f59
	 */
Packit Service 603f59
	    for (i = j = 0; i < n; i++) {
Packit Service 603f59
		if (id == s[i].i) {
Packit Service 603f59
		    if (x == s[i].x) {
Packit Service 603f59
			j = 1;
Packit Service 603f59
			continue;
Packit Service 603f59
		    }
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: P%sID %d has been included and excluded.\n",
Packit Service 603f59
			Pn,
Packit Service 603f59
			(ty == PGID) ? "G" : "",
Packit Service 603f59
			id);
Packit Service 603f59
		    err = j = 1;
Packit Service 603f59
		    break;
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    if (j)
Packit Service 603f59
		continue;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Allocate table table space.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (n >= mx) {
Packit Service 603f59
		mx += IDINCR;
Packit Service 603f59
		if (!s)
Packit Service 603f59
		    s = (struct int_lst *)malloc(
Packit Service 603f59
			(MALLOC_S)(sizeof(struct int_lst) * mx));
Packit Service 603f59
		else
Packit Service 603f59
		    s = (struct int_lst *)realloc((MALLOC_P *)s,
Packit Service 603f59
			(MALLOC_S)(sizeof(struct int_lst) * mx));
Packit Service 603f59
		if (!s) {
Packit Service 603f59
		    (void) fprintf(stderr, "%s: no space for %d process%s IDs",
Packit Service 603f59
			Pn, mx, (ty == PGID) ? " group" : "");
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    s[n].f = 0;
Packit Service 603f59
	    s[n].i = id;
Packit Service 603f59
	    s[n++].x = x;
Packit Service 603f59
	    if (x)
Packit Service 603f59
		nx++;
Packit Service 603f59
	    else
Packit Service 603f59
		ni++;
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Save variables for the type of ID.
Packit Service 603f59
 */
Packit Service 603f59
	if (ty == PGID) {
Packit Service 603f59
	    Mxpgid = mx;
Packit Service 603f59
	    Npgid = n;
Packit Service 603f59
	    Npgidi = ni;
Packit Service 603f59
	    Npgidx = nx;
Packit Service 603f59
	    Spgid = s;
Packit Service 603f59
	} else {
Packit Service 603f59
	    Mxpid = mx;
Packit Service 603f59
	    Npid = Npuns = n;
Packit Service 603f59
	    Npidi = ni;
Packit Service 603f59
	    Npidx = nx;
Packit Service 603f59
	    Spid = s;
Packit Service 603f59
	}
Packit Service 603f59
	return(err);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_network_address() - enter Internet address for searching
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_network_address(na)
Packit Service 603f59
	char *na;			/* Internet address string pointer */
Packit Service 603f59
{
Packit Service 603f59
	int ae, i, pr;
Packit Service 603f59
	int ep = -1;
Packit Service 603f59
	int ft = 0;
Packit Service 603f59
	struct hostent *he = (struct hostent *)NULL;
Packit Service 603f59
	char *hn = (char *)NULL;
Packit Service 603f59
	MALLOC_S l;
Packit Service 603f59
	struct nwad n;
Packit Service 603f59
	char *p, *wa;
Packit Service 603f59
	int pt = 0;
Packit Service 603f59
	int pu = 0;
Packit Service 603f59
	struct servent *se, *se1;
Packit Service 603f59
	char *sn = (char *)NULL;
Packit Service 603f59
	int sp = -1;
Packit Service 603f59
	MALLOC_S snl = 0;
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	char *cp;
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
	if (!na) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no network address specified\n", Pn);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	zeromem((char *)&n, sizeof(n));
Packit Service 603f59
	wa = na;
Packit Service 603f59
/*
Packit Service 603f59
 * Process an IP version type specification, IPv4 or IPv6, optionally followed
Packit Service 603f59
 * by a '@' and a host name or Internet address, or a ':' and a service name or
Packit Service 603f59
 * port number.
Packit Service 603f59
 */
Packit Service 603f59
	if ((*wa == '4') || (*wa == '6')) {
Packit Service 603f59
	    if (*wa == '4')
Packit Service 603f59
		ft = 4;
Packit Service 603f59
	    else if (*wa == '6') {
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
		ft = 6;
Packit Service 603f59
#else	/* !defined(HASIPv6) */
Packit Service 603f59
		(void) fprintf(stderr, "%s: IPv6 not supported: -i ", Pn);
Packit Service 603f59
		safestrprt(na, stderr, 1);
Packit Service 603f59
		goto nwad_exit;
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
	    }
Packit Service 603f59
	    wa++;
Packit Service 603f59
	    if (!*wa) {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * If nothing follows 4 or 6, then all network files of the
Packit Service 603f59
	     * specified IP version are selected.  Sequential -i, -i4, and
Packit Service 603f59
	     * -i6 specifications interact logically -- e.g., -i[46] followed
Packit Service 603f59
	     * by -i[64] is the same as -i.
Packit Service 603f59
	     */
Packit Service 603f59
		if (!Fnet) {
Packit Service 603f59
		    Fnet = 1;
Packit Service 603f59
		    FnetTy = ft;
Packit Service 603f59
		} else {
Packit Service 603f59
		    if (FnetTy) {
Packit Service 603f59
			if (FnetTy != ft)
Packit Service 603f59
			    FnetTy = 0;
Packit Service 603f59
		    } else
Packit Service 603f59
			FnetTy = ft;
Packit Service 603f59
		}
Packit Service 603f59
		return(0);
Packit Service 603f59
	    }
Packit Service 603f59
	} else if (Fnet)
Packit Service 603f59
	    ft = FnetTy;
Packit Service 603f59
/*
Packit Service 603f59
 * If an IP version has been specified, use it to set the address family.
Packit Service 603f59
 */
Packit Service 603f59
	switch (ft) {
Packit Service 603f59
	case 4:
Packit Service 603f59
	    n.af = AF_INET;
Packit Service 603f59
	    break;
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	case 6:
Packit Service 603f59
	    n.af = AF_INET6;
Packit Service 603f59
	    break;
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Process protocol name, optionally followed by a '@' and a host name or
Packit Service 603f59
 * Internet address, or a ':' and a service name or port number.
Packit Service 603f59
 */
Packit Service 603f59
	if (*wa && *wa != '@' && *wa != ':') {
Packit Service 603f59
	    for (p = wa; *wa && *wa != '@' && *wa != ':'; wa++)
Packit Service 603f59
		;
Packit Service 603f59
	    if ((l = wa - p)) {
Packit Service 603f59
		if (!(n.proto = mkstrcat(p, l, (char *)NULL, -1, (char *)NULL,
Packit Service 603f59
			        -1, (MALLOC_S *)NULL)))
Packit Service 603f59
		{
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: no space for protocol name from: -i ", Pn);
Packit Service 603f59
		    safestrprt(na, stderr, 1);
Packit Service 603f59
nwad_exit:
Packit Service 603f59
		    if (n.proto)
Packit Service 603f59
			(void) free((FREE_P *)n.proto);
Packit Service 603f59
		    if (hn)
Packit Service 603f59
			(void) free((FREE_P *)hn);
Packit Service 603f59
		    if (sn)
Packit Service 603f59
			(void) free((FREE_P *)sn);
Packit Service 603f59
		    return(1);
Packit Service 603f59
		}
Packit Service 603f59
	    /*
Packit Service 603f59
	     * The protocol name should be "tcp", "udp" or "udplite".
Packit Service 603f59
	     */
Packit Service 603f59
		if ((strcasecmp(n.proto, "tcp") != 0)
Packit Service 603f59
		&&  (strcasecmp(n.proto, "udp") != 0)
Packit Service 603f59
		&&  (strcasecmp(n.proto, "udplite") != 0))
Packit Service 603f59
		{
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: unknown protocol name (%s) in: -i ", Pn, n.proto);
Packit Service 603f59
		    safestrprt(na, stderr, 1);
Packit Service 603f59
		    goto nwad_exit;
Packit Service 603f59
		}
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Convert protocol name to lower case.
Packit Service 603f59
	     */
Packit Service 603f59
		for (p = n.proto; *p; p++) {
Packit Service 603f59
		    if (*p >= 'A' && *p <= 'Z')
Packit Service 603f59
			*p = *p - 'A' + 'a';
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Process an IPv4 address (1.2.3.4), IPv6 address ([1:2:3:4:5:6:7:8]),
Packit Service 603f59
 * or host name, preceded by a '@' and optionally followed by a colon
Packit Service 603f59
 * and a service name or port number.
Packit Service 603f59
 */
Packit Service 603f59
	if (*wa == '@') {
Packit Service 603f59
	    wa++;
Packit Service 603f59
	    if (!*wa || *wa == ':') {
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
unacc_address:
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: unacceptable Internet address in: -i ", Pn);
Packit Service 603f59
		safestrprt(na, stderr, 1);
Packit Service 603f59
		goto nwad_exit;
Packit Service 603f59
	    }
Packit Service 603f59
Packit Service 603f59
	    if ((p = isIPv4addr(wa, n.a, sizeof(n.a)))) {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Process IPv4 address.
Packit Service 603f59
	     */
Packit Service 603f59
		if (ft == 6) {
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: IPv4 addresses are prohibited: -i ", Pn);
Packit Service 603f59
		    safestrprt(na, stderr, 1);
Packit Service 603f59
		    goto nwad_exit;
Packit Service 603f59
		}
Packit Service 603f59
		wa = p;
Packit Service 603f59
		n.af = AF_INET;
Packit Service 603f59
	    } else if (*wa == '[') {
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Make sure IPv6 addresses are permitted.  If they are, assemble
Packit Service 603f59
	     * one.
Packit Service 603f59
	     */
Packit Service 603f59
		if (ft == 4) {
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: IPv6 addresses are prohibited: -i ", Pn);
Packit Service 603f59
		    safestrprt(na, stderr, 1);
Packit Service 603f59
		    goto nwad_exit;
Packit Service 603f59
		}
Packit Service 603f59
		if (!(cp = strrchr(++wa, ']')))
Packit Service 603f59
		    goto unacc_address;
Packit Service 603f59
		*cp = '\0';
Packit Service 603f59
		i = inet_pton(AF_INET6, wa, (void *)&n.a);
Packit Service 603f59
		*cp = ']';
Packit Service 603f59
		if (i != 1)
Packit Service 603f59
		    goto unacc_address;
Packit Service 603f59
		for (ae = i = 0; i < MAX_AF_ADDR; i++) {
Packit Service 603f59
		    if ((ae |= n.a[i]))
Packit Service 603f59
			break;
Packit Service 603f59
		}
Packit Service 603f59
		if (!ae)
Packit Service 603f59
		    goto unacc_address;
Packit Service 603f59
		if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)&n.a[0])) {
Packit Service 603f59
		    if (ft == 6) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: IPv4 addresses are prohibited: -i ", Pn);
Packit Service 603f59
			safestrprt(na, stderr, 1);
Packit Service 603f59
			goto nwad_exit;
Packit Service 603f59
		    }
Packit Service 603f59
		    for (i = 0; i < 4; i++) {
Packit Service 603f59
			n.a[i] = n.a[i+12];
Packit Service 603f59
		    }
Packit Service 603f59
		    n.af = AF_INET;
Packit Service 603f59
		} else
Packit Service 603f59
		    n.af = AF_INET6;
Packit Service 603f59
		wa = cp + 1;
Packit Service 603f59
#else	/* !defined(HASIPv6) */
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: unsupported IPv6 address in: -i ", Pn);
Packit Service 603f59
		safestrprt(na, stderr, 1);
Packit Service 603f59
		goto nwad_exit;
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
	    } else {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Assemble host name.
Packit Service 603f59
	     */
Packit Service 603f59
		for (p = wa; *p && *p != ':'; p++)
Packit Service 603f59
		    ;
Packit Service 603f59
		if ((l = p - wa)) {
Packit Service 603f59
		    if (!(hn = mkstrcat(wa, l, (char *)NULL, -1, (char *)NULL,
Packit Service 603f59
			       -1, (MALLOC_S *)NULL)))
Packit Service 603f59
		    {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: no space for host name: -i ", Pn);
Packit Service 603f59
			safestrprt(na, stderr, 1);
Packit Service 603f59
			goto nwad_exit;
Packit Service 603f59
		    }
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * If no IP version has been specified, look up an IPv6 host
Packit Service 603f59
		 * name first.  If that fails, look up an IPv4 host name.
Packit Service 603f59
		 *
Packit Service 603f59
		 * If the IPv6 version has been specified, look up the host
Packit Service 603f59
		 * name only under its IP version specification.
Packit Service 603f59
		 */
Packit Service 603f59
		    if (!ft)
Packit Service 603f59
			n.af = AF_INET6;
Packit Service 603f59
		    if (!(he = lkup_hostnm(hn, &n)) && !ft) {
Packit Service 603f59
			n.af = AF_INET;
Packit Service 603f59
			he = lkup_hostnm(hn, &n);
Packit Service 603f59
		    }
Packit Service 603f59
#else	/* !defined(HASIPv6) */
Packit Service 603f59
		    if (!ft)
Packit Service 603f59
			n.af = AF_INET;
Packit Service 603f59
		    he = lkup_hostnm(hn, &n);
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
		
Packit Service 603f59
		    if (!he) {
Packit Service 603f59
			fprintf(stderr, "%s: unknown host name (%s) in: -i ",
Packit Service 603f59
			    Pn, hn);
Packit Service 603f59
			safestrprt(na, stderr, 1);
Packit Service 603f59
			goto nwad_exit;
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
		wa = p;
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * If there is no port number, enter the address.
Packit Service 603f59
 */
Packit Service 603f59
	if (!*wa)
Packit Service 603f59
	    goto nwad_enter;
Packit Service 603f59
/*
Packit Service 603f59
 * Process a service name or port number list, preceded by a colon.
Packit Service 603f59
 *
Packit Service 603f59
 * Entries of the list are separated with commas; elements of a numeric range
Packit Service 603f59
 * are specified with a separating minus sign (`-'); all service names must
Packit Service 603f59
 * belong to the same protocol; embedded spaces are not allowed.  An embedded
Packit Service 603f59
 * minus sign in a name is taken to be part of the name, the starting entry
Packit Service 603f59
 * of a range can't be a service name.
Packit Service 603f59
 */
Packit Service 603f59
	if (*wa != ':' || *(wa + 1) == '\0') {
Packit Service 603f59
Packit Service 603f59
unacc_port:
Packit Service 603f59
	    (void) fprintf(stderr,
Packit Service 603f59
		"%s: unacceptable port specification in: -i ", Pn);
Packit Service 603f59
	    safestrprt(na, stderr, 1);
Packit Service 603f59
	    goto nwad_exit;
Packit Service 603f59
	}
Packit Service 603f59
	for (++wa; wa && *wa; wa++) {
Packit Service 603f59
	    for (ep = pr = sp = 0; *wa; wa++) {
Packit Service 603f59
		if (*wa < '0' || *wa > '9') {
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * Convert service name to port number, using already-specified
Packit Service 603f59
		 * protocol name.  A '-' is taken to be part of the name; hence
Packit Service 603f59
		 * the starting entry of a range can't be a service name.
Packit Service 603f59
		 */
Packit Service 603f59
		    for (p = wa; *wa && *wa != ','; wa++)
Packit Service 603f59
			;
Packit Service 603f59
		    if (!(l = wa - p)) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: invalid service name: -i ", Pn);
Packit Service 603f59
			safestrprt(na, stderr, 1);
Packit Service 603f59
			goto nwad_exit;
Packit Service 603f59
		    }
Packit Service 603f59
		    if (sn) {
Packit Service 603f59
			if (l > snl) {
Packit Service 603f59
			    sn = (char *)realloc((MALLOC_P *)sn, l + 1);
Packit Service 603f59
			    snl = l;
Packit Service 603f59
			}
Packit Service 603f59
		    } else {
Packit Service 603f59
			sn = (char *)malloc(l + 1);
Packit Service 603f59
			snl = l;
Packit Service 603f59
		    }
Packit Service 603f59
		    if (!sn) {
Packit Service 603f59
			(void) fprintf(stderr,
Packit Service 603f59
			    "%s: no space for service name: -i ", Pn);
Packit Service 603f59
			safestrprt(na, stderr, 1);
Packit Service 603f59
			goto nwad_exit;
Packit Service 603f59
		    }
Packit Service 603f59
		    (void) strncpy(sn, p, l);
Packit Service 603f59
		    *(sn + l) = '\0';
Packit Service 603f59
		    if (n.proto) {
Packit Service 603f59
Packit Service 603f59
		    /*
Packit Service 603f59
		     * If the protocol has been specified, look up the port
Packit Service 603f59
		     * number for the service name for the specified protocol.
Packit Service 603f59
		     */
Packit Service 603f59
			if (!(se = getservbyname(sn, n.proto))) {
Packit Service 603f59
			    (void) fprintf(stderr,
Packit Service 603f59
				"%s: unknown service %s for %s in: -i ",
Packit Service 603f59
				Pn, sn, n.proto);
Packit Service 603f59
			    safestrprt(na, stderr, 1);
Packit Service 603f59
			    goto nwad_exit;
Packit Service 603f59
			}
Packit Service 603f59
			pt = (int)ntohs(se->s_port);
Packit Service 603f59
		    } else {
Packit Service 603f59
Packit Service 603f59
		    /*
Packit Service 603f59
		     * If no protocol has been specified, look up the port
Packit Service 603f59
		     * numbers for the service name for both TCP and UDP.
Packit Service 603f59
		     */
Packit Service 603f59
			if((se = getservbyname(sn, "tcp")))
Packit Service 603f59
			    pt = (int)ntohs(se->s_port);
Packit Service 603f59
			if ((se1 = getservbyname(sn, "udp")))
Packit Service 603f59
			    pu = (int)ntohs(se1->s_port);
Packit Service 603f59
			if (!se && !se1) {
Packit Service 603f59
			    (void) fprintf(stderr,
Packit Service 603f59
				"%s: unknown service %s in: -i ", Pn, sn);
Packit Service 603f59
			    safestrprt(na, stderr, 1);
Packit Service 603f59
			    goto nwad_exit;
Packit Service 603f59
			}
Packit Service 603f59
			if (se && se1 && pt != pu) {
Packit Service 603f59
			    (void) fprintf(stderr,
Packit Service 603f59
				"%s: TCP=%d and UDP=%d %s ports conflict;\n",
Packit Service 603f59
				Pn, pt, pu, sn);
Packit Service 603f59
			    (void) fprintf(stderr,
Packit Service 603f59
				"      specify \"tcp:%s\" or \"udp:%s\": -i ",
Packit Service 603f59
				sn, sn);
Packit Service 603f59
			    safestrprt(na, stderr, 1);
Packit Service 603f59
			    goto nwad_exit;
Packit Service 603f59
			}
Packit Service 603f59
			if (!se && se1)
Packit Service 603f59
			    pt = pu;
Packit Service 603f59
		    }
Packit Service 603f59
		    if (pr)
Packit Service 603f59
			ep = pt;
Packit Service 603f59
		    else {
Packit Service 603f59
			sp = pt;
Packit Service 603f59
			if (*wa == '-')
Packit Service 603f59
			    pr++;
Packit Service 603f59
		    }
Packit Service 603f59
		} else {
Packit Service 603f59
Packit Service 603f59
		/*
Packit Service 603f59
		 * Assemble port number.
Packit Service 603f59
		 */
Packit Service 603f59
		    for (; *wa && *wa != ','; wa++) {
Packit Service 603f59
			if (*wa == '-') {
Packit Service 603f59
			    if (pr)
Packit Service 603f59
				goto unacc_port;
Packit Service 603f59
			    pr++;
Packit Service 603f59
			    break;
Packit Service 603f59
			}
Packit Service 603f59
			if (*wa < '0' || *wa > '9')
Packit Service 603f59
			    goto unacc_port;
Packit Service 603f59
			if (pr)
Packit Service 603f59
			    ep = (ep * 10) + *wa - '0';
Packit Service 603f59
			else
Packit Service 603f59
			    sp = (sp * 10) + *wa - '0';
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
		if (!*wa || *wa == ',')
Packit Service 603f59
		    break;
Packit Service 603f59
		if (pr)
Packit Service 603f59
		    continue;
Packit Service 603f59
		goto unacc_port;
Packit Service 603f59
	    }
Packit Service 603f59
	    if (!pr)
Packit Service 603f59
		ep = sp;
Packit Service 603f59
	    if (ep < sp)
Packit Service 603f59
		goto unacc_port;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Enter completed port or port range specification.
Packit Service 603f59
	 */
Packit Service 603f59
Packit Service 603f59
nwad_enter:
Packit Service 603f59
Packit Service 603f59
	    for (i = 1; i;) {
Packit Service 603f59
		if (enter_nwad(&n, sp, ep, na, he))
Packit Service 603f59
		    goto nwad_exit;
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	    /*
Packit Service 603f59
	     * If IPv6 is enabled, a host name was specified, and the
Packit Service 603f59
	     * associated * address is for the AF_INET6 address family,
Packit Service 603f59
	     * try to get and address for the AF_INET family, too, unless
Packit Service 603f59
	     * IPv4 is prohibited.
Packit Service 603f59
	     */
Packit Service 603f59
		if (hn && (n.af == AF_INET6) && (ft != 6)) {
Packit Service 603f59
		    n.af = AF_INET;
Packit Service 603f59
		    if ((he = lkup_hostnm(hn, &n)))
Packit Service 603f59
			continue;
Packit Service 603f59
		}
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
		i = 0;
Packit Service 603f59
	    }
Packit Service 603f59
	    if (!*wa)
Packit Service 603f59
		break;
Packit Service 603f59
	}
Packit Service 603f59
	if (sn)
Packit Service 603f59
	    (void) free((FREE_P *)sn);
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_nwad() - enter nwad structure
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
static int
Packit Service 603f59
enter_nwad(n, sp, ep, s, he)
Packit Service 603f59
	struct nwad *n;			/* pointer to partially completed
Packit Service 603f59
					 * nwad (less port) */
Packit Service 603f59
	int sp;				/* starting port number */
Packit Service 603f59
	int ep;				/* ending port number */
Packit Service 603f59
	char *s;			/* string that states the address */
Packit Service 603f59
	struct hostent *he;		/* pointer to hostent struct from which
Packit Service 603f59
					 * network address came */
Packit Service 603f59
{
Packit Service 603f59
	int ac;
Packit Service 603f59
	unsigned char *ap;
Packit Service 603f59
	static int na = 0;
Packit Service 603f59
	struct nwad nc;
Packit Service 603f59
	struct nwad *np;
Packit Service 603f59
/*
Packit Service 603f59
 * Allocate space for the argument specification.
Packit Service 603f59
 */
Packit Service 603f59
	if (strlen(s)) {
Packit Service 603f59
	    if (!(n->arg = mkstrcpy(s, (MALLOC_S *)NULL))) {
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: no space for Internet argument: -i ", Pn);
Packit Service 603f59
		safestrprt(s, stderr, 1);
Packit Service 603f59
		Exit(1);
Packit Service 603f59
	    }
Packit Service 603f59
	} else
Packit Service 603f59
	    n->arg = (char *)NULL;
Packit Service 603f59
/*
Packit Service 603f59
 * Loop through all hostent addresses.
Packit Service 603f59
 */
Packit Service 603f59
	for (ac = 1, nc = *n;;) {
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * Test address specification -- it must contain at least one of:
Packit Service 603f59
	 * protocol, Internet address or port.  If correct, link into search
Packit Service 603f59
	 * list.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (!nc.proto
Packit Service 603f59
	    &&  !nc.a[0] && !nc.a[1] && !nc.a[2] && !nc.a[3]
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	    &&  (nc.af != AF_INET6
Packit Service 603f59
	    ||   (!nc.a[4]  && !nc.a[5]  && !nc.a[6]  && !nc.a[7]
Packit Service 603f59
	    &&    !nc.a[8]  && !nc.a[9]  && !nc.a[10] && !nc.a[11]
Packit Service 603f59
	    &&    !nc.a[12] && !nc.a[13] && !nc.a[14] && !nc.a[15]))
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
	    &&  sp == -1) {
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: incomplete Internet address specification: -i ", Pn);
Packit Service 603f59
		safestrprt(s, stderr, 1);
Packit Service 603f59
		return(1);
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Limit the network address chain length to MAXNWAD for reasons of
Packit Service 603f59
	 * search efficiency.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (na >= MAXNWAD) {
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: network address limit (%d) exceeded: -i ",
Packit Service 603f59
		    Pn, MAXNWAD);
Packit Service 603f59
		safestrprt(s, stderr, 1);
Packit Service 603f59
		return(1);
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Allocate space for the address specification.
Packit Service 603f59
	 */
Packit Service 603f59
	    if ((np = (struct nwad *)malloc(sizeof(struct nwad))) == NULL) {
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: no space for network address from: -i ", Pn);
Packit Service 603f59
		safestrprt(s, stderr, 1);
Packit Service 603f59
		return(1);
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Construct and link the address specification.
Packit Service 603f59
	 */
Packit Service 603f59
	    *np = nc;
Packit Service 603f59
	    np->sport = sp;
Packit Service 603f59
	    np->eport = ep;
Packit Service 603f59
	    np->f = 0;
Packit Service 603f59
	    np->next = Nwad;
Packit Service 603f59
	    Nwad = np;
Packit Service 603f59
	    na++;
Packit Service 603f59
	/*
Packit Service 603f59
	 * If the network address came from gethostbyname(), advance to
Packit Service 603f59
	 * the next address; otherwise quit.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (!he)
Packit Service 603f59
		break;
Packit Service 603f59
	    if (!(ap = (unsigned char *)he->h_addr_list[ac++]))
Packit Service 603f59
		break;
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	    {
Packit Service 603f59
		int i;
Packit Service 603f59
Packit Service 603f59
		for (i = 0;
Packit Service 603f59
		     (i < (he->h_length - 1)) && (i < (MAX_AF_ADDR - 1));
Packit Service 603f59
		     i++)
Packit Service 603f59
		{
Packit Service 603f59
		    nc.a[i] = *ap++;
Packit Service 603f59
		}
Packit Service 603f59
		nc.a[i] = *ap;
Packit Service 603f59
	    }
Packit Service 603f59
#else	/* !defined(HASIPv6) */
Packit Service 603f59
	    nc.a[0] = *ap++;
Packit Service 603f59
	    nc.a[1] = *ap++;
Packit Service 603f59
	    nc.a[2] = *ap++;
Packit Service 603f59
	    nc.a[3] = *ap;
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
	}
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
#if	defined(HASTCPUDPSTATE)
Packit Service 603f59
/*
Packit Service 603f59
 * enter_state_spec() -- enter TCP and UDP state specifications
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_state_spec(ss)
Packit Service 603f59
	char *ss;			/* state specification string */
Packit Service 603f59
{
Packit Service 603f59
	char *cp, *ne, *ns, *pr;
Packit Service 603f59
	int err, d, f, i, tx, x;
Packit Service 603f59
	size_t len;
Packit Service 603f59
	static char *ssc = (char *)NULL;
Packit Service 603f59
	char *ty;
Packit Service 603f59
/*
Packit Service 603f59
 * Check the protocol specification.
Packit Service 603f59
 */
Packit Service 603f59
	if (!strncasecmp(ss, "tcp:", 4)) {
Packit Service 603f59
	    pr = "TCP";
Packit Service 603f59
	    tx = 0;
Packit Service 603f59
	}
Packit Service 603f59
Packit Service 603f59
#if	!defined(USE_LIB_PRINT_TCPTPI)
Packit Service 603f59
	else if (!strncasecmp(ss, "UDP:", 4)) {
Packit Service 603f59
	    pr = "UDP";
Packit Service 603f59
	    tx = 1;
Packit Service 603f59
	}
Packit Service 603f59
Packit Service 603f59
#endif	/* !defined(USE_LIB_PRINT_TCPTPI) */
Packit Service 603f59
Packit Service 603f59
	else {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: unknown -s protocol: \"%s\"\n",
Packit Service 603f59
		Pn, ss);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	cp = ss + 4;
Packit Service 603f59
	if (!*cp) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no %s state names in: %s\n",
Packit Service 603f59
		Pn, pr, ss);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	(void) build_IPstates();
Packit Service 603f59
	if (!(tx ? UdpSt : TcpSt)) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no %s state names available: %s\n",
Packit Service 603f59
		Pn, pr, ss);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Allocate the inclusion and exclusion tables for the protocol.
Packit Service 603f59
 */
Packit Service 603f59
	if (tx) {
Packit Service 603f59
	    if (UdpNstates) {
Packit Service 603f59
		if (!UdpStI) {
Packit Service 603f59
		    if (!(UdpStI = (unsigned char *)calloc((MALLOC_S)UdpNstates,
Packit Service 603f59
				   sizeof(unsigned char))))
Packit Service 603f59
		    {
Packit Service 603f59
			ty = "UDP state inclusion";
Packit Service 603f59
Packit Service 603f59
no_IorX_space:
Packit Service 603f59
Packit Service 603f59
			(void) fprintf(stderr, "%s: no %s table space\n",
Packit Service 603f59
			    Pn, ty);
Packit Service 603f59
			Exit(1);
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
		if (!UdpStX) {
Packit Service 603f59
		    if (!(UdpStX = (unsigned char *)calloc((MALLOC_S)UdpNstates,
Packit Service 603f59
				   sizeof(unsigned char))))
Packit Service 603f59
		    {
Packit Service 603f59
			ty = "UDP state exclusion";
Packit Service 603f59
			goto no_IorX_space;
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	} else {
Packit Service 603f59
	    if (TcpNstates) {
Packit Service 603f59
		if (!TcpStI) {
Packit Service 603f59
		    if (!(TcpStI = (unsigned char *)calloc((MALLOC_S)TcpNstates,
Packit Service 603f59
				   sizeof(unsigned char))))
Packit Service 603f59
		    {
Packit Service 603f59
			ty = "TCP state inclusion";
Packit Service 603f59
			goto no_IorX_space;
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
		if (!TcpStX) {
Packit Service 603f59
		    if (!(TcpStX = (unsigned char *)calloc((MALLOC_S)TcpNstates,
Packit Service 603f59
				   sizeof(unsigned char))))
Packit Service 603f59
		    {
Packit Service 603f59
			ty = "TCP state exclusion";
Packit Service 603f59
			goto no_IorX_space;
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Convert the state names in the rest of the string to state indexes and
Packit Service 603f59
 * record them in the appropriate inclusion or exclusion table.
Packit Service 603f59
 */
Packit Service 603f59
	if (ssc)
Packit Service 603f59
	    (void) free((MALLOC_P *)ssc);
Packit Service 603f59
	if (!(ssc = mkstrcpy(cp, (MALLOC_S *)NULL))) {
Packit Service 603f59
	    (void) fprintf(stderr,
Packit Service 603f59
		"%s: no temporary state argument space for: %s\n", Pn, ss);
Packit Service 603f59
	    Exit(1);
Packit Service 603f59
	}
Packit Service 603f59
	cp = ssc;
Packit Service 603f59
	err = 0;
Packit Service 603f59
	while (*cp) {
Packit Service 603f59
	
Packit Service 603f59
	/*
Packit Service 603f59
	 * Determine inclusion or exclusion for this state name.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (*cp == '^') {
Packit Service 603f59
		x = 1;
Packit Service 603f59
		cp++;
Packit Service 603f59
	    } else
Packit Service 603f59
		x = 0;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Find the end of the state name.  Make sure it is non-null in length
Packit Service 603f59
	 * and terminated with '\0'.
Packit Service 603f59
	 */
Packit Service 603f59
	    ns = cp;
Packit Service 603f59
	    while (*cp && (*cp != ',')) {
Packit Service 603f59
		cp++;
Packit Service 603f59
	    }
Packit Service 603f59
	    ne = cp;
Packit Service 603f59
	    if (*cp) {
Packit Service 603f59
		*cp = '\0';
Packit Service 603f59
		cp++;
Packit Service 603f59
	    }
Packit Service 603f59
	    if (!(len = (size_t)(ne - ns))) {
Packit Service 603f59
		(void) fprintf(stderr, "%s: NULL %s state name in: %s\n",
Packit Service 603f59
		    Pn, pr, ss);
Packit Service 603f59
		err = 1;
Packit Service 603f59
		continue;
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Find the state name in the appropriate table.
Packit Service 603f59
	 */
Packit Service 603f59
	    f = 0;
Packit Service 603f59
	    if (tx) {
Packit Service 603f59
		if (UdpSt) {
Packit Service 603f59
		    for (i = 0; i < UdpNstates; i++) {
Packit Service 603f59
			if (!strcasecmp(ns, UdpSt[i])) {
Packit Service 603f59
			    f = 1;
Packit Service 603f59
			    break;
Packit Service 603f59
			}
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
	    } else {
Packit Service 603f59
		if (TcpSt) {
Packit Service 603f59
		    for (i = 0; i < TcpNstates; i++) {
Packit Service 603f59
			if (!strcasecmp(ns, TcpSt[i])) {
Packit Service 603f59
			    f = 1;
Packit Service 603f59
			    break;
Packit Service 603f59
			}
Packit Service 603f59
		    }
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    if (!f) {
Packit Service 603f59
		(void) fprintf(stderr, "%s: unknown %s state name: %s\n",
Packit Service 603f59
		    Pn, pr, ns);
Packit Service 603f59
		err = 1;
Packit Service 603f59
		continue;
Packit Service 603f59
	    }
Packit Service 603f59
	/*
Packit Service 603f59
	 * Set the inclusion or exclusion status in the appropriate table.
Packit Service 603f59
	 */
Packit Service 603f59
	    d = 0;
Packit Service 603f59
	    if (x) {
Packit Service 603f59
		if (tx) {
Packit Service 603f59
		    if (!UdpStX[i]) {
Packit Service 603f59
			UdpStX[i] = 1;
Packit Service 603f59
			UdpStXn++;
Packit Service 603f59
		    } else
Packit Service 603f59
			d = 1;
Packit Service 603f59
		} else {
Packit Service 603f59
		    if (!TcpStX[i]) {
Packit Service 603f59
			TcpStX[i] = 1;
Packit Service 603f59
			TcpStXn++;
Packit Service 603f59
		    } else
Packit Service 603f59
			d = 1;
Packit Service 603f59
		}
Packit Service 603f59
	    } else {
Packit Service 603f59
		if (tx) {
Packit Service 603f59
		    if (!UdpStI[i]) {
Packit Service 603f59
			UdpStI[i] = 1;
Packit Service 603f59
			UdpStIn++;
Packit Service 603f59
		    } else
Packit Service 603f59
			d = 1;
Packit Service 603f59
		} else {
Packit Service 603f59
		    if (!TcpStI[i]) {
Packit Service 603f59
			TcpStI[i] = 1;
Packit Service 603f59
			TcpStIn++;
Packit Service 603f59
		    } else
Packit Service 603f59
			d = 1;
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    if (d) {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Report a duplicate.
Packit Service 603f59
	     */
Packit Service 603f59
		(void) fprintf(stderr, "%s: duplicate %s %sclusion: %s\n",
Packit Service 603f59
		    Pn, pr,
Packit Service 603f59
		    x ? "ex" : "in",
Packit Service 603f59
		    ns);
Packit Service 603f59
		err = 1;
Packit Service 603f59
	    }
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Release any temporary space and return.
Packit Service 603f59
 */
Packit Service 603f59
	if (ssc) {
Packit Service 603f59
	    (void) free((MALLOC_P *)ssc);
Packit Service 603f59
	    ssc = (char *)NULL;
Packit Service 603f59
	}
Packit Service 603f59
	return(err);
Packit Service 603f59
}
Packit Service 603f59
#endif	/* defined(HASTCPUDPSTATE) */
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_str_lst() - enter a string on a list
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_str_lst(opt, s, lp, incl, excl)
Packit Service 603f59
	char *opt;			/* option name */
Packit Service 603f59
	char *s;			/* string to enter */
Packit Service 603f59
	struct str_lst **lp;		/* string's list */
Packit Service 603f59
	int *incl;			/* included count */
Packit Service 603f59
	int *excl;			/* excluded count */
Packit Service 603f59
{
Packit Service 603f59
	char *cp;
Packit Service 603f59
	short i, x;
Packit Service 603f59
	MALLOC_S len;
Packit Service 603f59
	struct str_lst *lpt;
Packit Service 603f59
Packit Service 603f59
	if (!s || *s == '-' || *s == '+') {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: missing %s option value\n",
Packit Service 603f59
		Pn, opt);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	if (*s == '^') {
Packit Service 603f59
	    i = 0;
Packit Service 603f59
	    x = 1;
Packit Service 603f59
	    s++;
Packit Service 603f59
	} else {
Packit Service 603f59
	    i = 1;
Packit Service 603f59
	    x = 0;
Packit Service 603f59
	}
Packit Service 603f59
	if (!(cp = mkstrcpy(s, &len))) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no string copy space: ", Pn);
Packit Service 603f59
	    safestrprt(s, stderr, 1);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	if ((lpt = (struct str_lst *)malloc(sizeof(struct str_lst))) == NULL) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no list space: ", Pn);
Packit Service 603f59
	    safestrprt(s, stderr, 1);
Packit Service 603f59
	    (void) free((FREE_P *)cp);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	lpt->f = 0;
Packit Service 603f59
	lpt->str = cp;
Packit Service 603f59
	lpt->len = (int)len;
Packit Service 603f59
	lpt->x = x;
Packit Service 603f59
	if (i)
Packit Service 603f59
	    *incl += 1;
Packit Service 603f59
	if (x)
Packit Service 603f59
	    *excl += 1;
Packit Service 603f59
	lpt->next = *lp;
Packit Service 603f59
	*lp = lpt;
Packit Service 603f59
	return(0);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * enter_uid() - enter User Identifier for searching
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
int
Packit Service 603f59
enter_uid(us)
Packit Service 603f59
	char *us;			/* User IDentifier string pointer */
Packit Service 603f59
{
Packit Service 603f59
	int err, i, j, lnml, nn;
Packit Service 603f59
	unsigned char excl;
Packit Service 603f59
	MALLOC_S len;
Packit Service 603f59
	char lnm[LOGINML+1], *lp;
Packit Service 603f59
	struct passwd *pw;
Packit Service 603f59
	char *s, *st;
Packit Service 603f59
	uid_t uid;
Packit Service 603f59
Packit Service 603f59
	if (!us) {
Packit Service 603f59
	    (void) fprintf(stderr, "%s: no UIDs specified\n", Pn);
Packit Service 603f59
	    return(1);
Packit Service 603f59
	}
Packit Service 603f59
	for (err = 0, s = us; *s;) {
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * Assemble next User IDentifier.
Packit Service 603f59
	 */
Packit Service 603f59
	    for (excl = i = j = lnml = nn = uid = 0, st = s;
Packit Service 603f59
		 *s && *s != ',';
Packit Service 603f59
		 i++, s++)
Packit Service 603f59
	    {
Packit Service 603f59
		if (lnml >= LOGINML) {
Packit Service 603f59
		    while (*s && *s != ',') {
Packit Service 603f59
			s++;
Packit Service 603f59
			lnml++;
Packit Service 603f59
		    }
Packit Service 603f59
		    (void) fprintf(stderr,
Packit Service 603f59
			"%s: -u login name > %d characters: ", Pn,
Packit Service 603f59
			    (int)LOGINML);
Packit Service 603f59
		    safestrprtn(st, lnml, stderr, 1);
Packit Service 603f59
		    err = j = 1;
Packit Service 603f59
		    break;
Packit Service 603f59
		}
Packit Service 603f59
		if (i == 0 && *s == '^') {
Packit Service 603f59
		    excl = 1;
Packit Service 603f59
		    continue;
Packit Service 603f59
		}
Packit Service 603f59
		lnm[lnml++] = *s;
Packit Service 603f59
		if (nn)
Packit Service 603f59
		    continue;
Packit Service 603f59
Packit Service 603f59
#if	defined(__STDC__)
Packit Service 603f59
		if (isdigit((unsigned char)*s))
Packit Service 603f59
#else	/* !defined(__STDC__) */
Packit Service 603f59
		if (isascii(*s) && isdigit((unsigned char)*s))
Packit Service 603f59
#endif	/* defined(__STDC__) */
Packit Service 603f59
Packit Service 603f59
		    uid = (uid * 10) + *s - '0';
Packit Service 603f59
		else
Packit Service 603f59
		    nn++;
Packit Service 603f59
	    }
Packit Service 603f59
	    if (*s)
Packit Service 603f59
		s++;
Packit Service 603f59
	    if (j)
Packit Service 603f59
		continue;
Packit Service 603f59
	    if (nn) {
Packit Service 603f59
	       lnm[lnml++] = '\0';
Packit Service 603f59
		if ((pw = getpwnam(lnm)) == NULL) {
Packit Service 603f59
		    (void) fprintf(stderr, "%s: can't get UID for ", Pn);
Packit Service 603f59
		    safestrprt(lnm, stderr, 1);
Packit Service 603f59
		    err = 1;
Packit Service 603f59
		    continue;
Packit Service 603f59
		} else
Packit Service 603f59
		    uid = pw->pw_uid;
Packit Service 603f59
	    }
Packit Service 603f59
Packit Service 603f59
#if	defined(HASSECURITY) && !defined(HASNOSOCKSECURITY)
Packit Service 603f59
	/*
Packit Service 603f59
	 * If the security mode is enabled, only the root user may list files
Packit Service 603f59
	 * belonging to user IDs other than the real user ID of this lsof
Packit Service 603f59
	 * process.  If HASNOSOCKSECURITY is also defined, then anyone may
Packit Service 603f59
	 * list anyone else's socket files.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (Myuid && uid != Myuid) {
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: ID %d request rejected because of security mode.\n",
Packit Service 603f59
		    Pn, uid);
Packit Service 603f59
		err = 1;
Packit Service 603f59
		continue;
Packit Service 603f59
	    }
Packit Service 603f59
#endif	/* defined(HASSECURITY)  && !defined(HASNOSOCKSECURITY) */
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * Avoid entering duplicates.
Packit Service 603f59
	 */
Packit Service 603f59
	    for (i = j = 0; i < Nuid; i++) {
Packit Service 603f59
		if (uid != Suid[i].uid)
Packit Service 603f59
		    continue;
Packit Service 603f59
		if (Suid[i].excl == excl) {
Packit Service 603f59
		    j = 1;
Packit Service 603f59
		    continue;
Packit Service 603f59
		}
Packit Service 603f59
		(void) fprintf(stderr,
Packit Service 603f59
		    "%s: UID %d has been included and excluded.\n",
Packit Service 603f59
			Pn, (int)uid);
Packit Service 603f59
		err = j = 1;
Packit Service 603f59
		break;
Packit Service 603f59
	    }
Packit Service 603f59
	    if (j)
Packit Service 603f59
		continue;
Packit Service 603f59
	/*
Packit Service 603f59
	 * Allocate space for User IDentifier.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (Nuid >= Mxuid) {
Packit Service 603f59
		Mxuid += UIDINCR;
Packit Service 603f59
		len = (MALLOC_S)(Mxuid * sizeof(struct seluid));
Packit Service 603f59
		if (!Suid)
Packit Service 603f59
		    Suid = (struct seluid *)malloc(len);
Packit Service 603f59
		else
Packit Service 603f59
		    Suid = (struct seluid *)realloc((MALLOC_P *)Suid, len);
Packit Service 603f59
		if (!Suid) {
Packit Service 603f59
		    (void) fprintf(stderr, "%s: no space for UIDs", Pn);
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
	    }
Packit Service 603f59
	    if (nn) {
Packit Service 603f59
		if (!(lp = mkstrcpy(lnm, (MALLOC_S *)NULL))) {
Packit Service 603f59
		    (void) fprintf(stderr, "%s: no space for login: ", Pn);
Packit Service 603f59
		    safestrprt(lnm, stderr, 1);
Packit Service 603f59
		    Exit(1);
Packit Service 603f59
		}
Packit Service 603f59
		Suid[Nuid].lnm = lp;
Packit Service 603f59
	    } else
Packit Service 603f59
		Suid[Nuid].lnm = (char *)NULL;
Packit Service 603f59
	    Suid[Nuid].uid = uid;
Packit Service 603f59
	    Suid[Nuid++].excl = excl;
Packit Service 603f59
	    if (excl)
Packit Service 603f59
		Nuidexcl++;
Packit Service 603f59
	    else
Packit Service 603f59
		Nuidincl++;
Packit Service 603f59
	}
Packit Service 603f59
	return(err);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * isIPv4addr() - is host name an IPv4 address
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
static char *
Packit Service 603f59
isIPv4addr(hn, a, al)
Packit Service 603f59
	char *hn;			/* host name */
Packit Service 603f59
	unsigned char *a;		/* address receptor */
Packit Service 603f59
	int al;				/* address receptor length */
Packit Service 603f59
{
Packit Service 603f59
	int dc = 0;			/* dot count */
Packit Service 603f59
	int i;				/* temorary index */
Packit Service 603f59
	int ov[MIN_AF_ADDR];		/* octet values */
Packit Service 603f59
	int ovx = 0;			/* ov[] index */
Packit Service 603f59
/*
Packit Service 603f59
 * The host name must begin with a number and the return octet value
Packit Service 603f59
 * arguments must be acceptable.
Packit Service 603f59
 */
Packit Service 603f59
	if ((*hn < '0') || (*hn > '9'))
Packit Service 603f59
	    return((char *)NULL);
Packit Service 603f59
	if (!a || (al < MIN_AF_ADDR))
Packit Service 603f59
	    return((char *)NULL);
Packit Service 603f59
/*
Packit Service 603f59
 * Start the first octet assembly, then parse tge remainder of the host
Packit Service 603f59
 * name for four octets, separated by dots.
Packit Service 603f59
 */
Packit Service 603f59
	ov[0] = (int)(*hn++ - '0');
Packit Service 603f59
	while (*hn && (*hn != ':')) {
Packit Service 603f59
	    if (*hn == '.') {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Count a dot.  Make sure a preceding octet value has been
Packit Service 603f59
	     * assembled.  Don't assemble more than MIN_AF_ADDR octets.
Packit Service 603f59
	     */
Packit Service 603f59
		dc++;
Packit Service 603f59
		if ((ov[ovx] < 0) || (ov[ovx] > 255))
Packit Service 603f59
		    return((char *)NULL);
Packit Service 603f59
		if (++ovx > (MIN_AF_ADDR - 1))
Packit Service 603f59
		    return((char *)NULL);
Packit Service 603f59
		ov[ovx] = -1;
Packit Service 603f59
	    } else if ((*hn >= '0') && (*hn <= '9')) {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * Assemble an octet.
Packit Service 603f59
	     */
Packit Service 603f59
		if (ov[ovx] < 0)
Packit Service 603f59
		    ov[ovx] = (int)(*hn - '0');
Packit Service 603f59
		else
Packit Service 603f59
		    ov[ovx] = (ov[ovx] * 10) + (int)(*hn - '0');
Packit Service 603f59
	    } else {
Packit Service 603f59
Packit Service 603f59
	    /*
Packit Service 603f59
	     * A non-address character has been detected.
Packit Service 603f59
	     */
Packit Service 603f59
		return((char *)NULL);
Packit Service 603f59
	    }
Packit Service 603f59
	    hn++;
Packit Service 603f59
	}
Packit Service 603f59
/*
Packit Service 603f59
 * Make sure there were three dots and four non-null octets.
Packit Service 603f59
 */
Packit Service 603f59
	if ((dc != 3)
Packit Service 603f59
	||  (ovx != (MIN_AF_ADDR - 1))
Packit Service 603f59
	||  (ov[ovx] < 0) || (ov[ovx] > 255))
Packit Service 603f59
	    return((char *)NULL);
Packit Service 603f59
/*
Packit Service 603f59
 * Copy the octets as unsigned characters and return the ending host name
Packit Service 603f59
 * character position.
Packit Service 603f59
 */
Packit Service 603f59
	for (i = 0; i < MIN_AF_ADDR; i++) {
Packit Service 603f59
	     a[i] = (unsigned char)ov[i];
Packit Service 603f59
	}
Packit Service 603f59
	return(hn);
Packit Service 603f59
}
Packit Service 603f59
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * lkup_hostnm() - look up host name
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
static struct hostent *
Packit Service 603f59
lkup_hostnm(hn, n)
Packit Service 603f59
	char *hn;			/* host name */
Packit Service 603f59
	struct nwad *n;			/* network address destination */
Packit Service 603f59
{
Packit Service 603f59
	unsigned char *ap;
Packit Service 603f59
	struct hostent *he;
Packit Service 603f59
	int ln;
Packit Service 603f59
/*
Packit Service 603f59
 * Get hostname structure pointer.  Return NULL if there is none.
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	he = gethostbyname2(hn, n->af);
Packit Service 603f59
#else	/* !defined(HASIPv6) */
Packit Service 603f59
	he = gethostbyname(hn);
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
	if (!he)
Packit Service 603f59
	    return(he);
Packit Service 603f59
/*
Packit Service 603f59
 * Copy first hostname structure address to destination structure.
Packit Service 603f59
 */
Packit Service 603f59
Packit Service 603f59
#if	defined(HASIPv6)
Packit Service 603f59
	if (n->af != he->h_addrtype)
Packit Service 603f59
	    return((struct hostent *)NULL);
Packit Service 603f59
	if (n->af == AF_INET6) {
Packit Service 603f59
Packit Service 603f59
	/*
Packit Service 603f59
	 * Copy an AF_INET6 address.
Packit Service 603f59
	 */
Packit Service 603f59
	    if (he->h_length > MAX_AF_ADDR)
Packit Service 603f59
		return((struct hostent *)NULL);
Packit Service 603f59
	    (void) memcpy((void *)&n->a[0], (void *)he->h_addr, he->h_length);
Packit Service 603f59
	    if ((ln = MAX_AF_ADDR - he->h_length) > 0)
Packit Service 603f59
		zeromem((char *)&n->a[he->h_length], ln);
Packit Service 603f59
	    return(he);
Packit Service 603f59
	}
Packit Service 603f59
#endif	/* defined(HASIPv6) */
Packit Service 603f59
Packit Service 603f59
/*
Packit Service 603f59
 * Copy an AF_INET address.
Packit Service 603f59
 */
Packit Service 603f59
	if (he->h_length != 4)
Packit Service 603f59
	    return((struct hostent *)NULL);
Packit Service 603f59
	ap = (unsigned char *)he->h_addr;
Packit Service 603f59
	n->a[0] = *ap++;
Packit Service 603f59
	n->a[1] = *ap++;
Packit Service 603f59
	n->a[2] = *ap++;
Packit Service 603f59
	n->a[3] = *ap;
Packit Service 603f59
	if ((ln = MAX_AF_ADDR - 4) > 0)
Packit Service 603f59
	    zeromem((char *)&n->a[4], ln);
Packit Service 603f59
	return(he);
Packit Service 603f59
}