#ifndef lint
static char copyright[] =
"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: arg.c,v 1.50 2011/09/07 19:13:49 abe Exp $";
#endif
#include "lsof.h"
#define CMDRXINCR 32
static int NCmdRxA = 0;
_PROTOTYPE(static int ckfd_range,(char *first, char *dash, char *last, int *lo, int *hi));
_PROTOTYPE(static int enter_fd_lst,(char *nm, int lo, int hi, int excl));
_PROTOTYPE(static int enter_nwad,(struct nwad *n, int sp, int ep, char *s, struct hostent *he));
_PROTOTYPE(static struct hostent *lkup_hostnm,(char *hn, struct nwad *n));
_PROTOTYPE(static char *isIPv4addr,(char *hn, unsigned char *a, int al));
static int
ckfd_range(first, dash, last, lo, hi)
char *first;
char *dash;
char *last;
int *lo;
int *hi;
{
char *cp;
if (first >= dash || dash >= last) {
(void) fprintf(stderr, "%s: illegal FD range for -d: ", Pn);
safestrprt(first, stderr, 1);
return(1);
}
for (cp = first, *lo = 0; *cp && cp < dash; cp++) {
if (!isdigit((unsigned char)*cp)) {
FD_range_nondigit:
(void) fprintf(stderr, "%s: non-digit in -d FD range: ", Pn);
safestrprt(first, stderr, 1);
return(1);
}
*lo = (*lo * 10) + (int)(*cp - '0');
}
for (cp = dash+1, *hi = 0; *cp && cp < last; cp++) {
if (!isdigit((unsigned char)*cp))
goto FD_range_nondigit;
*hi = (*hi * 10) + (int)(*cp - '0');
}
if (*lo >= *hi) {
(void) fprintf(stderr, "%s: -d FD range's low >= its high: ", Pn);
safestrprt(first, stderr, 1);
return(1);
}
return(0);
}
int
ck_file_arg(i, ac, av, fv, rs, sbp)
int i;
int ac;
char *av[];
int fv;
int rs;
struct stat *sbp;
{
char *ap, *fnm, *fsnm, *path;
short err = 0;
int fsm, ftype, j, k;
MALLOC_S l;
struct mounts *mp;
static struct mounts **mmp = (struct mounts **)NULL;
int mx, nm;
static int nma = 0;
struct stat sb;
struct sfile *sfp;
short ss = 0;
#if defined(CKFA_EXPDEV)
dev_t dev, rdev;
#endif
#if defined(HASPROCFS)
unsigned char ad, an;
int pfsnl = -1;
pid_t pid;
struct procfsid *pfi;
#endif
for (; i < ac; i++) {
if (rs && (ac == 1) && (i == 0))
path = av[i];
else {
if (!(path = Readlink(av[i]))) {
ErrStat = 1;
continue;
}
}
j = k = strlen(path);
while ((k > 1) && (path[k-1] == '/')) {
k--;
}
if (k < j) {
if (path != av[i])
path[k] = '\0';
else {
if (!(ap = (char *)malloc((MALLOC_S)(k + 1)))) {
(void) fprintf(stderr, "%s: no space for copy of %s\n",
Pn, path);
Exit(1);
}
(void) strncpy(ap, path, k);
ap[k] = '\0';
path = ap;
}
}
for (ftype = 1, mp = readmnt(), nm = 0;
(fv != 1) && mp;
mp = mp->next)
{
fsm = 0;
if (strcmp(mp->dir, path) == 0)
fsm++;
else if (fv == 2 || (mp->fs_mode & S_IFMT) == S_IFBLK) {
if (mp->fsnmres && strcmp(mp->fsnmres, path) == 0)
fsm++;
}
if (!fsm)
continue;
ftype = 0;
for (mx = 0; mx < nm; mx++) {
if (strcmp(mp->dir, mmp[mx]->dir) == 0
&& mp->dev == mmp[mx]->dev
&& mp->rdev == mmp[mx]->rdev
&& mp->inode == mmp[mx]->inode)
break;
}
if (mx < nm)
continue;
if (nm >= nma) {
nma += 5;
l = (MALLOC_S)(nma * sizeof(struct mounts *));
if (mmp)
mmp = (struct mounts **)realloc((MALLOC_P *)mmp, l);
else
mmp = (struct mounts **)malloc(l);
if (!mmp) {
(void) fprintf(stderr,
"%s: no space for mount pointers\n", Pn);
Exit(1);
}
}
mmp[nm++] = mp;
}
if (fv == 2 && nm == 0) {
(void) fprintf(stderr, "%s: not a file system: ", Pn);
safestrprt(av[i], stderr, 1);
ErrStat = 1;
continue;
}
mx = 0;
do {
if (!(sfp = (struct sfile *)malloc(sizeof(struct sfile)))) {
(void) fprintf(stderr, "%s: no space for files\n", Pn);
Exit(1);
}
sfp->next = Sfile;
Sfile = sfp;
sfp->f = 0;
if ((sfp->type = ftype)) {
fnm = path;
fsnm = (char *)NULL;
if (sbp && (ac == 1))
sb = *sbp;
else {
if (statsafely(fnm, &sb) != 0) {
int en = errno;
(void) fprintf(stderr, "%s: status error on ", Pn);
safestrprt(fnm, stderr, 0);
(void) fprintf(stderr, ": %s\n", strerror(en));
Sfile = sfp->next;
(void) free((FREE_P *)sfp);
ErrStat = 1;
continue;
}
#if defined(HASSPECDEVD)
(void) HASSPECDEVD(fnm, &sb);
#endif
}
sfp->i = (INODETYPE)sb.st_ino;
sfp->mode = sb.st_mode & S_IFMT;
#if defined(CKFA_EXPDEV)
sfp->dev = expdev(sb.st_dev);
sfp->rdev = expdev(sb.st_rdev);
#else
sfp->dev = sb.st_dev;
sfp->rdev = sb.st_rdev;
#endif
#if defined(CKFA_MPXCHAN)
sfp->ch = getchan(path);
#endif
} else {
mp = mmp[mx++];
ss++;
#if defined(HASPROCFS)
if (mp == Mtprocfs) {
Sfile = sfp->next;
(void) free((FREE_P *)sfp);
Procsrch = 1;
continue;
}
#endif
fnm = mp->dir;
fsnm = mp->fsname;
sfp->dev = mp->dev;
sfp->rdev = mp->rdev;
sfp->i = mp->inode;
sfp->mode = mp->mode & S_IFMT;
}
ss = 1;
if (!fnm || fnm == path) {
sfp->name = fnm;
#if defined(HASPROCFS)
an = 0;
#endif
} else {
if (!(sfp->name = mkstrcpy(fnm, (MALLOC_S *)NULL))) {
(void) fprintf(stderr,
"%s: no space for file name: ", Pn);
safestrprt(fnm, stderr, 1);
Exit(1);
}
#if defined(HASPROCFS)
an = 1;
#endif
}
if (!fsnm || fsnm == path) {
sfp->devnm = fsnm;
#if defined(HASPROCFS)
ad = 0;
#endif
} else {
if (!(sfp->devnm = mkstrcpy(fsnm, (MALLOC_S *)NULL))) {
(void) fprintf(stderr,
"%s: no space for file system name: ", Pn);
safestrprt(fsnm, stderr, 1);
Exit(1);
}
#if defined(HASPROCFS)
ad = 1;
#endif
}
if (!(sfp->aname = mkstrcpy(av[i], (MALLOC_S *)NULL))) {
(void) fprintf(stderr,
"%s: no space for argument file name: ", Pn);
safestrprt(av[i], stderr, 1);
Exit(1);
}
#if defined(HASPROCFS)
if (!Mtprocfs || Procsrch)
continue;
# if defined(HASFSTYPE) && HASFSTYPE==1
if (strcmp(sb.st_fstype, HASPROCFS) != 0)
continue;
# endif
if (pfsnl == -1)
pfsnl = strlen(Mtprocfs->dir);
if (!pfsnl)
continue;
if (strncmp(Mtprocfs->dir, path, pfsnl) != 0)
continue;
if (path[pfsnl] != '/')
# if defined(HASPINODEN)
pid = 0;
# else
continue;
# endif
else {
for (j = pfsnl+1; path[j]; j++) {
if (!isdigit((unsigned char)path[j]))
break;
}
if (path[j] || (j - pfsnl - 1) < 1
|| (sfp->mode & S_IFMT) != S_IFREG)
# if defined(HASPINODEN)
pid = 0;
# else
continue;
# endif
else
pid = atoi(&path[pfsnl+1]);
}
if (!(pfi = (struct procfsid *)malloc((MALLOC_S)
sizeof(struct procfsid))))
{
(void) fprintf(stderr, "%s: no space for %s ID: ",
Pn, Mtprocfs->dir);
safestrprt(path, stderr, 1);
Exit(1);
}
pfi->pid = pid;
pfi->f = 0;
pfi->nm = sfp->aname;
pfi->next = Procfsid;
Procfsid = pfi;
# if defined(HASPINODEN)
pfi->inode = (INODETYPE)sfp->i;
# endif
Sfile = sfp->next;
if (ad)
(void) free((FREE_P *)sfp->devnm);
if (an)
(void) free((FREE_P *)sfp->name);
(void) free((FREE_P *)sfp);
#endif
} while (mx < nm);
}
if (!ss)
err = 1;
return((int)err);
}
#if defined(HASDCACHE)
int
ctrl_dcache(c)
char *c;
{
int rc = 0;
if (!c) {
(void) fprintf(stderr,
"%s: no device cache option control string\n", Pn);
return(1);
}
switch (*c) {
case '?':
if (*(c+1) != '\0') {
(void) fprintf(stderr, "%s: nothing should follow -D?\n", Pn);
return(1);
}
DChelp = 1;
return(0);
case 'b':
case 'B':
if (Setuidroot
#if !defined(WILLDROPGID)
|| Myuid
#endif
)
rc = 1;
else
DCstate = 1;
break;
case 'r':
case 'R':
if (Setuidroot && *(c+1))
rc = 1;
else
DCstate = 2;
break;
case 'u':
case 'U':
if (Setuidroot
#if !defined(WILLDROPGID)
|| Myuid
#endif
)
rc = 1;
else
DCstate = 3;
break;
case 'i':
case 'I':
if (*(c+1) == '\0') {
DCstate = 0;
return(0);
}
default:
(void) fprintf(stderr, "%s: unknown -D option: ", Pn);
safestrprt(c, stderr, 1);
return(1);
}
if (rc) {
(void) fprintf(stderr, "%s: -D option restricted to root: ", Pn);
safestrprt(c, stderr, 1);
return(1);
}
for (c++; *c && (*c == ' ' || *c == '\t'); c++)
;
if (strlen(c)) {
if (!(DCpathArg = mkstrcpy(c, (MALLOC_S *)NULL))) {
(void) fprintf(stderr, "%s: no space for -D path: ", Pn);
safestrprt(c, stderr, 1);
Exit(1);
}
}
return(0);
}
#endif
int
enter_cmd_rx(x)
char *x;
{
int bmod = 0;
int bxmod = 0;
int i, re;
int imod = 0;
int xmod = 0;
int co = REG_NOSUB|REG_EXTENDED;
char reb[256], *xb, *xe, *xm;
MALLOC_S xl;
char *xp = (char *)NULL;
if (!*x || (*x != '/')) {
(void) fprintf(stderr, "%s: regexp doesn't begin with '/': ", Pn);
if (x)
safestrprt(x, stderr, 1);
return(1);
}
xb = x + 1;
for (xe = xb; *xe; xe++) {
if (*xe == '/')
break;
}
if (*xe != '/') {
(void) fprintf(stderr, "%s: regexp doesn't end with '/': ", Pn);
safestrprt(x, stderr, 1);
return(1);
}
for (i = 0, xm = xe + 1; *xm; xm++) {
switch(*xm) {
case 'b':
if (++bmod > 1) {
if (bmod == 2) {
(void) fprintf(stderr,
"%s: b regexp modifier already used: ", Pn);
safestrprt(x, stderr, 1);
}
i = 1;
} else if (xmod) {
if (++bxmod == 1) {
(void) fprintf(stderr,
"%s: b and x regexp modifiers conflict: ", Pn);
safestrprt(x, stderr, 1);
}
i = 1;
} else
co &= ~REG_EXTENDED;
break;
case 'i':
if (++imod > 1) {
if (imod == 2) {
(void) fprintf(stderr,
"%s: i regexp modifier already used: ", Pn);
safestrprt(x, stderr, 1);
}
i = 1;
} else
co |= REG_ICASE;
break;
case 'x':
if (++xmod > 1) {
if (xmod == 2) {
(void) fprintf(stderr,
"%s: x regexp modifier already used: ", Pn);
safestrprt(x, stderr, 1);
}
i = 1;
} else if (bmod) {
if (++bxmod == 1) {
(void) fprintf(stderr,
"%s: b and x regexp modifiers conflict: ", Pn);
safestrprt(x, stderr, 1);
}
i = 1;
} else
co |= REG_EXTENDED;
break;
default:
(void) fprintf(stderr, "%s: invalid regexp modifier: %c\n",
Pn, (int)*xm);
i = 1;
}
}
if (i)
return(1);
xl = (MALLOC_S)(xe - xb);
if (!(xp = (char *)malloc(xl + 1))) {
(void) fprintf(stderr, "%s: no regexp space for: ", Pn);
safestrprt(x, stderr, 1);
Exit(1);
}
(void) strncpy(xp, xb, xl);
xp[(int)xl] = '\0';
if (NCmdRxA >= NCmdRxU) {
NCmdRxA += CMDRXINCR;
xl = (MALLOC_S)(NCmdRxA * sizeof(lsof_rx_t));
if (CmdRx)
CmdRx = (lsof_rx_t *)realloc((MALLOC_P *)CmdRx, xl);
else
CmdRx = (lsof_rx_t *)malloc(xl);
if (!CmdRx) {
(void) fprintf(stderr, "%s: no space for regexp: ", Pn);
safestrprt(x, stderr, 1);
Exit(1);
}
}
i = NCmdRxU;
CmdRx[i].exp = xp;
if ((re = regcomp(&CmdRx[i].cx, xp, co))) {
(void) fprintf(stderr, "%s: regexp error: ", Pn);
safestrprt(x, stderr, 0);
(void) regerror(re, &CmdRx[i].cx, &reb[0], sizeof(reb));
(void) fprintf(stderr, ": %s\n", reb);
if (xp) {
(void) free((FREE_P *)xp);
xp = (char *)NULL;
}
return(1);
}
CmdRx[i].mc = 0;
CmdRx[i].exp = xp;
NCmdRxU++;
return(0);
}
#if defined(HASEOPT)
int
enter_efsys(e, rdlnk)
char *e;
int rdlnk;
{
char *ec;
efsys_list_t *ep;
int i;
char *path;
if (!e || (*e != '/')) {
if (!Fwarn)
(void) fprintf(stderr,
"%s: -e not followed by a file system path: \"%s\"\n",
Pn, e);
return(1);
}
if (!(ec = mkstrcpy(e, (MALLOC_S *)NULL))) {
(void) fprintf(stderr, "%s: no space for -e string: ", Pn);
safestrprt(e, stderr, 1);
Exit(1);
}
if (rdlnk)
path = ec;
else {
if (!(path = Readlink(ec)))
return(1);
}
for (i = (int)strlen(path); (i > 1) && (path[i - 1] == '/'); i--) {
path[i - 1] = '\0';
}
for (ep = Efsysl; ep; ep = ep->next) {
if (!strcmp(ep->path, path))
return(0);
}
if (!(ep = (efsys_list_t *)malloc((MALLOC_S)(sizeof(efsys_list_t))))) {
(void) fprintf(stderr, "%s: no space for \"-e %s\" entry\n",
Pn, e);
Exit(1);
}
ep->path = path;
ep->pathl = i;
ep->rdlnk = rdlnk;
ep->mp = (struct mounts *)NULL;
if (!(ep->next = Efsysl))
Efsysl = ep;
return(0);
}
#endif
int
enter_fd(f)
char *f;
{
char c, *cp1, *cp2, *dash;
int err, excl, hi, lo;
char *fc;
if (!f || (strlen(f) + 1) < 2) {
(void) fprintf(stderr, "%s: no file descriptor specified\n", Pn);
return(1);
}
if (!(fc = mkstrcpy(f, (MALLOC_S *)NULL))) {
(void) fprintf(stderr, "%s: no space for fd string: ", Pn);
safestrprt(f, stderr, 1);
Exit(1);
}
for (cp1 = fc, err = 0; *cp1;) {
if (*cp1 == '^') {
excl = 1;
cp1++;
} else
excl = 0;
for (cp2 = cp1, dash = (char *)NULL; *cp2 && *cp2 != ','; cp2++) {
if (*cp2 == '-')
dash = cp2;
}
if ((c = *cp2) != '\0')
*cp2 = '\0';
if (cp2 > cp1) {
if (dash) {
if (ckfd_range(cp1, dash, cp2, &lo, &hi))
err = 1;
else {
if (enter_fd_lst((char *)NULL, lo, hi, excl))
err = 1;
}
} else {
if (enter_fd_lst(cp1, 0, 0, excl))
err = 1;
}
}
if (c == '\0')
break;
cp1 = cp2 + 1;
}
(void) free((FREE_P *)fc);
return(err);
}
static int
enter_fd_lst(nm, lo, hi, excl)
char *nm;
int lo;
int hi;
int excl;
{
char buf[256], *cp;
int n;
struct fd_lst *f, *ft;
if (FdlTy >= 0) {
if (FdlTy != excl) {
if (!Fwarn) {
if (nm) {
(void) snpf(buf, sizeof(buf) - 1, "%s%s",
excl ? "^" : "", nm);
} else {
if (lo != hi) {
(void) snpf(buf, sizeof(buf) - 1, "%s%d-%d",
excl ? "^" : "", lo, hi);
} else {
(void) snpf(buf, sizeof(buf) - 1, "%s%d",
excl ? "^" : "", lo);
}
}
buf[sizeof(buf) - 1] = '\0';
(void) fprintf(stderr,
"%s: %s in an %s -d list: %s\n", Pn,
excl ? "exclude" : "include",
FdlTy ? "exclude" : "include",
buf);
}
return(1);
}
}
if (!(f = (struct fd_lst *)malloc((MALLOC_S)sizeof(struct fd_lst)))) {
(void) fprintf(stderr, "%s: no space for FD list entry\n", Pn);
Exit(1);
}
if (nm) {
for (cp = nm, n = 0; *cp; cp++) {
if (!isdigit((unsigned char)*cp))
break;
n = (n * 10) + (int)(*cp - '0');
}
if (*cp) {
if (!(f->nm = mkstrcpy(nm, (MALLOC_S *)NULL))) {
(void) fprintf(stderr,
"%s: no space for copy of: %s\n", Pn, nm);
Exit(1);
}
lo = 1;
hi = 0;
} else {
f->nm = (char *)NULL;
lo = hi = n;
}
} else
f->nm = (char *)NULL;
for (ft = Fdl; ft; ft = ft->next) {
if (f->nm) {
if (!ft->nm || strcmp(f->nm, ft->nm))
continue;
} else if ((lo != ft->lo) || (hi != ft->hi))
continue;
(void) free((FREE_P *)f);
return(0);
}
f->hi = hi;
f->lo = lo;
f->next = Fdl;
Fdl = f;
FdlTy = excl;
return(0);
}
#define EDDEFFNL 128
int
enter_dir(d, descend)
char *d;
int descend;
{
char *av[2];
dev_t ddev;
DIR *dfp;
char *dn = (char *)NULL;
MALLOC_S dnl, dnamlen;
struct DIRTYPE *dp;
int en, sl;
int fct = 0;
char *fp = (char *)NULL;
MALLOC_S fpl = (MALLOC_S)0;
MALLOC_S fpli = (MALLOC_S)0;
struct stat sb;
if (!d || !*d || *d == '+' || *d == '-') {
if (!Fwarn)
(void) fprintf(stderr,
"%s: +d not followed by a directory path\n", Pn);
return(1);
}
if (!(dn = Readlink(d)))
return(1);
if (statsafely(dn, &sb)) {
if (!Fwarn) {
en = errno;
(void) fprintf(stderr, "%s: WARNING: can't stat(", Pn);
safestrprt(dn, stderr, 0);
(void) fprintf(stderr, "): %s\n", strerror(en));
}
if (dn && dn != d) {
(void) free((FREE_P *)dn);
dn = (char *)NULL;
}
return(1);
}
if ((sb.st_mode & S_IFMT) != S_IFDIR) {
if (!Fwarn) {
(void) fprintf(stderr, "%s: WARNING: not a directory: ", Pn);
safestrprt(dn, stderr, 1);
}
if (dn && dn != d) {
(void) free((FREE_P *)dn);
dn = (char *)NULL;
}
return(1);
}
#if defined(HASSPECDEVD)
(void) HASSPECDEVD(dn, &sb);
#endif
ddev = sb.st_dev;
Dstkn = Dstkx = 0;
Dstk = (char **)NULL;
(void) stkdir(dn);
av[0] = (dn == d) ? mkstrcpy(dn, (MALLOC_S *)NULL) : dn;
av[1] = (char *)NULL;
dn = (char *)NULL;
if (!ck_file_arg(0, 1, av, 1, 1, &sb)) {
av[0] = (char *)NULL;
fct++;
}
while (--Dstkx >= 0) {
if (!(dn = Dstk[Dstkx]))
continue;
Dstk[Dstkx] = (char *)NULL;
if (!(dfp = OpenDir(dn))) {
if (!Fwarn) {
if ((en = errno) != ENOENT) {
(void) fprintf(stderr,
"%s: WARNING: can't opendir(", Pn);
safestrprt(dn, stderr, 0);
(void) fprintf(stderr, "): %s\n", strerror(en));
}
}
(void) free((FREE_P *)dn);
dn = (char *)NULL;
continue;
}
dnl = strlen(dn);
sl = ((dnl > 0) && (*(dn + dnl - 1) == '/')) ? 0 : 1;
fpli = (MALLOC_S)(dnl + sl + EDDEFFNL + 1);
if ((int)fpli > (int)fpl) {
fpl = fpli;
if (!fp)
fp = (char *)malloc(fpl);
else
fp = (char *)realloc(fp, fpl);
if (!fp) {
(void) fprintf(stderr,
"%s: no space for path to entries in directory: %s\n",
Pn, dn);
Exit(1);
}
}
(void) snpf(fp, (size_t)fpl, "%s%s", dn, sl ? "/" : "");
(void) free((FREE_P *)dn);
dn = (char *)NULL;
for (dp = ReadDir(dfp); dp; dp = ReadDir(dfp)) {
if (!dp->d_ino)
continue;
#if defined(HASDNAMLEN)
dnamlen = (MALLOC_S)dp->d_namlen;
#else
dnamlen = (MALLOC_S)strlen(dp->d_name);
#endif
if (!dnamlen)
continue;
if (dnamlen <= 2 && dp->d_name[0] == '.') {
if (dnamlen == 1)
continue;
if (dp->d_name[1] == '.')
continue;
}
fpli = (MALLOC_S)(dnamlen - (fpl - dnl - sl - 1));
if ((int)fpli > 0) {
fpl += fpli;
if (!(fp = (char *)realloc(fp, fpl))) {
(void) fprintf(stderr, "%s: no space for: ", Pn);
safestrprt(dn, stderr, 0);
putc('/', stderr);
safestrprtn(dp->d_name, dnamlen, stderr, 1);
Exit(1);
}
}
(void) strncpy(fp + dnl + sl, dp->d_name, dnamlen);
fp[dnl + sl + dnamlen] = '\0';
if (lstatsafely(fp, &sb)) {
if ((en = errno) != ENOENT) {
if (!Fwarn) {
(void) fprintf(stderr,
"%s: WARNING: can't lstat(", Pn);
safestrprt(fp, stderr, 0);
(void) fprintf(stderr, "): %s\n", strerror(en));
}
}
continue;
}
#if defined(HASSPECDEVD)
(void) HASSPECDEVD(fp, &sb);
#endif
if (!(Fxover & XO_FILESYS)) {
if (sb.st_dev != ddev)
continue;
}
if ((sb.st_mode & S_IFMT) == S_IFLNK) {
if (Fxover & XO_SYMLINK) {
if (statsafely(fp, &sb)) {
if ((en = errno) != ENOENT) {
if (!Fwarn) {
(void) fprintf(stderr,
"%s: WARNING: can't stat(", Pn);
safestrprt(fp, stderr, 0);
(void) fprintf(stderr,
") symbolc link: %s\n", strerror(en));
}
}
continue;
}
} else
continue;
}
if (av[0]) {
(void) free((FREE_P *)av[0]);
av[0] = (char *)NULL;
}
av[0] = mkstrcpy(fp, (MALLOC_S *)NULL);
if ((sb.st_mode & S_IFMT) == S_IFDIR && descend)
stkdir(av[0]);
if (!ck_file_arg(0, 1, av, 1, 1, &sb)) {
av[0] = (char *)NULL;
fct++;
}
}
(void) CloseDir(dfp);
if (dn && dn != d) {
(void) free((FREE_P *)dn);
dn = (char *)NULL;
}
}
if (dn && dn != d) {
(void) free((FREE_P *)dn);
dn = (char *)NULL;
}
if (av[0] && av[0] != fp) {
(void) free((FREE_P *)av[0]);
av[0] = (char *)NULL;
}
if (fp) {
(void) free((FREE_P *)fp);
fp = (char *)NULL;
}
if (Dstk) {
(void) free((FREE_P *)Dstk);
Dstk = (char **)NULL;
}
if (!fct) {
if (!Fwarn) {
(void) fprintf(stderr,
"%s: WARNING: no files found in directory: ", Pn);
safestrprt(d, stderr, 1);
}
return(1);
}
return(0);
}
int
enter_id(ty, p)
enum IDType ty;
char *p;
{
char *cp;
int err, i, id, j, mx, n, ni, nx, x;
struct int_lst *s;
if (!p) {
(void) fprintf(stderr, "%s: no process%s ID specified\n",
Pn, (ty == PGID) ? " group" : "");
return(1);
}
switch (ty) {
case PGID:
mx = Mxpgid;
n = Npgid;
ni = Npgidi;
nx = Npgidx;
s = Spgid;
break;
case PID:
mx = Mxpid;
n = Npid;
ni = Npidi;
nx = Npidx;
s = Spid;
break;
default:
(void) fprintf(stderr, "%s: enter_id \"", Pn);
safestrprt(p, stderr, 0);
(void) fprintf(stderr, "\", invalid type: %d\n", ty);
Exit(1);
}
for (cp = p, err = 0; *cp;) {
for (i = id = x = 0; *cp && *cp != ','; cp++) {
if (!i) {
i = 1;
if (*cp == '^') {
x = 1;
continue;
}
}
#if defined(__STDC__)
if (!isdigit((unsigned char)*cp))
#else
if (!isascii(*cp) || ! isdigit((unsigned char)*cp))
#endif
{
(void) fprintf(stderr, "%s: illegal process%s ID: ",
Pn, (ty == PGID) ? " group" : "");
safestrprt(p, stderr, 1);
return(1);
}
id = (id * 10) + *cp - '0';
}
if (*cp)
cp++;
for (i = j = 0; i < n; i++) {
if (id == s[i].i) {
if (x == s[i].x) {
j = 1;
continue;
}
(void) fprintf(stderr,
"%s: P%sID %d has been included and excluded.\n",
Pn,
(ty == PGID) ? "G" : "",
id);
err = j = 1;
break;
}
}
if (j)
continue;
if (n >= mx) {
mx += IDINCR;
if (!s)
s = (struct int_lst *)malloc(
(MALLOC_S)(sizeof(struct int_lst) * mx));
else
s = (struct int_lst *)realloc((MALLOC_P *)s,
(MALLOC_S)(sizeof(struct int_lst) * mx));
if (!s) {
(void) fprintf(stderr, "%s: no space for %d process%s IDs",
Pn, mx, (ty == PGID) ? " group" : "");
Exit(1);
}
}
s[n].f = 0;
s[n].i = id;
s[n++].x = x;
if (x)
nx++;
else
ni++;
}
if (ty == PGID) {
Mxpgid = mx;
Npgid = n;
Npgidi = ni;
Npgidx = nx;
Spgid = s;
} else {
Mxpid = mx;
Npid = Npuns = n;
Npidi = ni;
Npidx = nx;
Spid = s;
}
return(err);
}
int
enter_network_address(na)
char *na;
{
int ae, i, pr;
int ep = -1;
int ft = 0;
struct hostent *he = (struct hostent *)NULL;
char *hn = (char *)NULL;
MALLOC_S l;
struct nwad n;
char *p, *wa;
int pt = 0;
int pu = 0;
struct servent *se, *se1;
char *sn = (char *)NULL;
int sp = -1;
MALLOC_S snl = 0;
#if defined(HASIPv6)
char *cp;
#endif
if (!na) {
(void) fprintf(stderr, "%s: no network address specified\n", Pn);
return(1);
}
zeromem((char *)&n, sizeof(n));
wa = na;
if ((*wa == '4') || (*wa == '6')) {
if (*wa == '4')
ft = 4;
else if (*wa == '6') {
#if defined(HASIPv6)
ft = 6;
#else
(void) fprintf(stderr, "%s: IPv6 not supported: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
#endif
}
wa++;
if (!*wa) {
if (!Fnet) {
Fnet = 1;
FnetTy = ft;
} else {
if (FnetTy) {
if (FnetTy != ft)
FnetTy = 0;
} else
FnetTy = ft;
}
return(0);
}
} else if (Fnet)
ft = FnetTy;
switch (ft) {
case 4:
n.af = AF_INET;
break;
#if defined(HASIPv6)
case 6:
n.af = AF_INET6;
break;
#endif
}
if (*wa && *wa != '@' && *wa != ':') {
for (p = wa; *wa && *wa != '@' && *wa != ':'; wa++)
;
if ((l = wa - p)) {
if (!(n.proto = mkstrcat(p, l, (char *)NULL, -1, (char *)NULL,
-1, (MALLOC_S *)NULL)))
{
(void) fprintf(stderr,
"%s: no space for protocol name from: -i ", Pn);
safestrprt(na, stderr, 1);
nwad_exit:
if (n.proto)
(void) free((FREE_P *)n.proto);
if (hn)
(void) free((FREE_P *)hn);
if (sn)
(void) free((FREE_P *)sn);
return(1);
}
if ((strcasecmp(n.proto, "tcp") != 0)
&& (strcasecmp(n.proto, "udp") != 0)
&& (strcasecmp(n.proto, "udplite") != 0))
{
(void) fprintf(stderr,
"%s: unknown protocol name (%s) in: -i ", Pn, n.proto);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
for (p = n.proto; *p; p++) {
if (*p >= 'A' && *p <= 'Z')
*p = *p - 'A' + 'a';
}
}
}
if (*wa == '@') {
wa++;
if (!*wa || *wa == ':') {
#if defined(HASIPv6)
unacc_address:
#endif
(void) fprintf(stderr,
"%s: unacceptable Internet address in: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
if ((p = isIPv4addr(wa, n.a, sizeof(n.a)))) {
if (ft == 6) {
(void) fprintf(stderr,
"%s: IPv4 addresses are prohibited: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
wa = p;
n.af = AF_INET;
} else if (*wa == '[') {
#if defined(HASIPv6)
if (ft == 4) {
(void) fprintf(stderr,
"%s: IPv6 addresses are prohibited: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
if (!(cp = strrchr(++wa, ']')))
goto unacc_address;
*cp = '\0';
i = inet_pton(AF_INET6, wa, (void *)&n.a);
*cp = ']';
if (i != 1)
goto unacc_address;
for (ae = i = 0; i < MAX_AF_ADDR; i++) {
if ((ae |= n.a[i]))
break;
}
if (!ae)
goto unacc_address;
if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)&n.a[0])) {
if (ft == 6) {
(void) fprintf(stderr,
"%s: IPv4 addresses are prohibited: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
for (i = 0; i < 4; i++) {
n.a[i] = n.a[i+12];
}
n.af = AF_INET;
} else
n.af = AF_INET6;
wa = cp + 1;
#else
(void) fprintf(stderr,
"%s: unsupported IPv6 address in: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
#endif
} else {
for (p = wa; *p && *p != ':'; p++)
;
if ((l = p - wa)) {
if (!(hn = mkstrcat(wa, l, (char *)NULL, -1, (char *)NULL,
-1, (MALLOC_S *)NULL)))
{
(void) fprintf(stderr,
"%s: no space for host name: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
#if defined(HASIPv6)
if (!ft)
n.af = AF_INET6;
if (!(he = lkup_hostnm(hn, &n)) && !ft) {
n.af = AF_INET;
he = lkup_hostnm(hn, &n);
}
#else
if (!ft)
n.af = AF_INET;
he = lkup_hostnm(hn, &n);
#endif
if (!he) {
fprintf(stderr, "%s: unknown host name (%s) in: -i ",
Pn, hn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
}
wa = p;
}
}
if (!*wa)
goto nwad_enter;
if (*wa != ':' || *(wa + 1) == '\0') {
unacc_port:
(void) fprintf(stderr,
"%s: unacceptable port specification in: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
for (++wa; wa && *wa; wa++) {
for (ep = pr = sp = 0; *wa; wa++) {
if (*wa < '0' || *wa > '9') {
for (p = wa; *wa && *wa != ','; wa++)
;
if (!(l = wa - p)) {
(void) fprintf(stderr,
"%s: invalid service name: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
if (sn) {
if (l > snl) {
sn = (char *)realloc((MALLOC_P *)sn, l + 1);
snl = l;
}
} else {
sn = (char *)malloc(l + 1);
snl = l;
}
if (!sn) {
(void) fprintf(stderr,
"%s: no space for service name: -i ", Pn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
(void) strncpy(sn, p, l);
*(sn + l) = '\0';
if (n.proto) {
if (!(se = getservbyname(sn, n.proto))) {
(void) fprintf(stderr,
"%s: unknown service %s for %s in: -i ",
Pn, sn, n.proto);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
pt = (int)ntohs(se->s_port);
} else {
if((se = getservbyname(sn, "tcp")))
pt = (int)ntohs(se->s_port);
if ((se1 = getservbyname(sn, "udp")))
pu = (int)ntohs(se1->s_port);
if (!se && !se1) {
(void) fprintf(stderr,
"%s: unknown service %s in: -i ", Pn, sn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
if (se && se1 && pt != pu) {
(void) fprintf(stderr,
"%s: TCP=%d and UDP=%d %s ports conflict;\n",
Pn, pt, pu, sn);
(void) fprintf(stderr,
" specify \"tcp:%s\" or \"udp:%s\": -i ",
sn, sn);
safestrprt(na, stderr, 1);
goto nwad_exit;
}
if (!se && se1)
pt = pu;
}
if (pr)
ep = pt;
else {
sp = pt;
if (*wa == '-')
pr++;
}
} else {
for (; *wa && *wa != ','; wa++) {
if (*wa == '-') {
if (pr)
goto unacc_port;
pr++;
break;
}
if (*wa < '0' || *wa > '9')
goto unacc_port;
if (pr)
ep = (ep * 10) + *wa - '0';
else
sp = (sp * 10) + *wa - '0';
}
}
if (!*wa || *wa == ',')
break;
if (pr)
continue;
goto unacc_port;
}
if (!pr)
ep = sp;
if (ep < sp)
goto unacc_port;
nwad_enter:
for (i = 1; i;) {
if (enter_nwad(&n, sp, ep, na, he))
goto nwad_exit;
#if defined(HASIPv6)
if (hn && (n.af == AF_INET6) && (ft != 6)) {
n.af = AF_INET;
if ((he = lkup_hostnm(hn, &n)))
continue;
}
#endif
i = 0;
}
if (!*wa)
break;
}
if (sn)
(void) free((FREE_P *)sn);
return(0);
}
static int
enter_nwad(n, sp, ep, s, he)
struct nwad *n;
int sp;
int ep;
char *s;
struct hostent *he;
{
int ac;
unsigned char *ap;
static int na = 0;
struct nwad nc;
struct nwad *np;
if (strlen(s)) {
if (!(n->arg = mkstrcpy(s, (MALLOC_S *)NULL))) {
(void) fprintf(stderr,
"%s: no space for Internet argument: -i ", Pn);
safestrprt(s, stderr, 1);
Exit(1);
}
} else
n->arg = (char *)NULL;
for (ac = 1, nc = *n;;) {
if (!nc.proto
&& !nc.a[0] && !nc.a[1] && !nc.a[2] && !nc.a[3]
#if defined(HASIPv6)
&& (nc.af != AF_INET6
|| (!nc.a[4] && !nc.a[5] && !nc.a[6] && !nc.a[7]
&& !nc.a[8] && !nc.a[9] && !nc.a[10] && !nc.a[11]
&& !nc.a[12] && !nc.a[13] && !nc.a[14] && !nc.a[15]))
#endif
&& sp == -1) {
(void) fprintf(stderr,
"%s: incomplete Internet address specification: -i ", Pn);
safestrprt(s, stderr, 1);
return(1);
}
if (na >= MAXNWAD) {
(void) fprintf(stderr,
"%s: network address limit (%d) exceeded: -i ",
Pn, MAXNWAD);
safestrprt(s, stderr, 1);
return(1);
}
if ((np = (struct nwad *)malloc(sizeof(struct nwad))) == NULL) {
(void) fprintf(stderr,
"%s: no space for network address from: -i ", Pn);
safestrprt(s, stderr, 1);
return(1);
}
*np = nc;
np->sport = sp;
np->eport = ep;
np->f = 0;
np->next = Nwad;
Nwad = np;
na++;
if (!he)
break;
if (!(ap = (unsigned char *)he->h_addr_list[ac++]))
break;
#if defined(HASIPv6)
{
int i;
for (i = 0;
(i < (he->h_length - 1)) && (i < (MAX_AF_ADDR - 1));
i++)
{
nc.a[i] = *ap++;
}
nc.a[i] = *ap;
}
#else
nc.a[0] = *ap++;
nc.a[1] = *ap++;
nc.a[2] = *ap++;
nc.a[3] = *ap;
#endif
}
return(0);
}
#if defined(HASTCPUDPSTATE)
int
enter_state_spec(ss)
char *ss;
{
char *cp, *ne, *ns, *pr;
int err, d, f, i, tx, x;
size_t len;
static char *ssc = (char *)NULL;
char *ty;
if (!strncasecmp(ss, "tcp:", 4)) {
pr = "TCP";
tx = 0;
}
#if !defined(USE_LIB_PRINT_TCPTPI)
else if (!strncasecmp(ss, "UDP:", 4)) {
pr = "UDP";
tx = 1;
}
#endif
else {
(void) fprintf(stderr, "%s: unknown -s protocol: \"%s\"\n",
Pn, ss);
return(1);
}
cp = ss + 4;
if (!*cp) {
(void) fprintf(stderr, "%s: no %s state names in: %s\n",
Pn, pr, ss);
return(1);
}
(void) build_IPstates();
if (!(tx ? UdpSt : TcpSt)) {
(void) fprintf(stderr, "%s: no %s state names available: %s\n",
Pn, pr, ss);
return(1);
}
if (tx) {
if (UdpNstates) {
if (!UdpStI) {
if (!(UdpStI = (unsigned char *)calloc((MALLOC_S)UdpNstates,
sizeof(unsigned char))))
{
ty = "UDP state inclusion";
no_IorX_space:
(void) fprintf(stderr, "%s: no %s table space\n",
Pn, ty);
Exit(1);
}
}
if (!UdpStX) {
if (!(UdpStX = (unsigned char *)calloc((MALLOC_S)UdpNstates,
sizeof(unsigned char))))
{
ty = "UDP state exclusion";
goto no_IorX_space;
}
}
}
} else {
if (TcpNstates) {
if (!TcpStI) {
if (!(TcpStI = (unsigned char *)calloc((MALLOC_S)TcpNstates,
sizeof(unsigned char))))
{
ty = "TCP state inclusion";
goto no_IorX_space;
}
}
if (!TcpStX) {
if (!(TcpStX = (unsigned char *)calloc((MALLOC_S)TcpNstates,
sizeof(unsigned char))))
{
ty = "TCP state exclusion";
goto no_IorX_space;
}
}
}
}
if (ssc)
(void) free((MALLOC_P *)ssc);
if (!(ssc = mkstrcpy(cp, (MALLOC_S *)NULL))) {
(void) fprintf(stderr,
"%s: no temporary state argument space for: %s\n", Pn, ss);
Exit(1);
}
cp = ssc;
err = 0;
while (*cp) {
if (*cp == '^') {
x = 1;
cp++;
} else
x = 0;
ns = cp;
while (*cp && (*cp != ',')) {
cp++;
}
ne = cp;
if (*cp) {
*cp = '\0';
cp++;
}
if (!(len = (size_t)(ne - ns))) {
(void) fprintf(stderr, "%s: NULL %s state name in: %s\n",
Pn, pr, ss);
err = 1;
continue;
}
f = 0;
if (tx) {
if (UdpSt) {
for (i = 0; i < UdpNstates; i++) {
if (!strcasecmp(ns, UdpSt[i])) {
f = 1;
break;
}
}
}
} else {
if (TcpSt) {
for (i = 0; i < TcpNstates; i++) {
if (!strcasecmp(ns, TcpSt[i])) {
f = 1;
break;
}
}
}
}
if (!f) {
(void) fprintf(stderr, "%s: unknown %s state name: %s\n",
Pn, pr, ns);
err = 1;
continue;
}
d = 0;
if (x) {
if (tx) {
if (!UdpStX[i]) {
UdpStX[i] = 1;
UdpStXn++;
} else
d = 1;
} else {
if (!TcpStX[i]) {
TcpStX[i] = 1;
TcpStXn++;
} else
d = 1;
}
} else {
if (tx) {
if (!UdpStI[i]) {
UdpStI[i] = 1;
UdpStIn++;
} else
d = 1;
} else {
if (!TcpStI[i]) {
TcpStI[i] = 1;
TcpStIn++;
} else
d = 1;
}
}
if (d) {
(void) fprintf(stderr, "%s: duplicate %s %sclusion: %s\n",
Pn, pr,
x ? "ex" : "in",
ns);
err = 1;
}
}
if (ssc) {
(void) free((MALLOC_P *)ssc);
ssc = (char *)NULL;
}
return(err);
}
#endif
int
enter_str_lst(opt, s, lp, incl, excl)
char *opt;
char *s;
struct str_lst **lp;
int *incl;
int *excl;
{
char *cp;
short i, x;
MALLOC_S len;
struct str_lst *lpt;
if (!s || *s == '-' || *s == '+') {
(void) fprintf(stderr, "%s: missing %s option value\n",
Pn, opt);
return(1);
}
if (*s == '^') {
i = 0;
x = 1;
s++;
} else {
i = 1;
x = 0;
}
if (!(cp = mkstrcpy(s, &len))) {
(void) fprintf(stderr, "%s: no string copy space: ", Pn);
safestrprt(s, stderr, 1);
return(1);
}
if ((lpt = (struct str_lst *)malloc(sizeof(struct str_lst))) == NULL) {
(void) fprintf(stderr, "%s: no list space: ", Pn);
safestrprt(s, stderr, 1);
(void) free((FREE_P *)cp);
return(1);
}
lpt->f = 0;
lpt->str = cp;
lpt->len = (int)len;
lpt->x = x;
if (i)
*incl += 1;
if (x)
*excl += 1;
lpt->next = *lp;
*lp = lpt;
return(0);
}
int
enter_uid(us)
char *us;
{
int err, i, j, lnml, nn;
unsigned char excl;
MALLOC_S len;
char lnm[LOGINML+1], *lp;
struct passwd *pw;
char *s, *st;
uid_t uid;
if (!us) {
(void) fprintf(stderr, "%s: no UIDs specified\n", Pn);
return(1);
}
for (err = 0, s = us; *s;) {
for (excl = i = j = lnml = nn = uid = 0, st = s;
*s && *s != ',';
i++, s++)
{
if (lnml >= LOGINML) {
while (*s && *s != ',') {
s++;
lnml++;
}
(void) fprintf(stderr,
"%s: -u login name > %d characters: ", Pn,
(int)LOGINML);
safestrprtn(st, lnml, stderr, 1);
err = j = 1;
break;
}
if (i == 0 && *s == '^') {
excl = 1;
continue;
}
lnm[lnml++] = *s;
if (nn)
continue;
#if defined(__STDC__)
if (isdigit((unsigned char)*s))
#else
if (isascii(*s) && isdigit((unsigned char)*s))
#endif
uid = (uid * 10) + *s - '0';
else
nn++;
}
if (*s)
s++;
if (j)
continue;
if (nn) {
lnm[lnml++] = '\0';
if ((pw = getpwnam(lnm)) == NULL) {
(void) fprintf(stderr, "%s: can't get UID for ", Pn);
safestrprt(lnm, stderr, 1);
err = 1;
continue;
} else
uid = pw->pw_uid;
}
#if defined(HASSECURITY) && !defined(HASNOSOCKSECURITY)
if (Myuid && uid != Myuid) {
(void) fprintf(stderr,
"%s: ID %d request rejected because of security mode.\n",
Pn, uid);
err = 1;
continue;
}
#endif
for (i = j = 0; i < Nuid; i++) {
if (uid != Suid[i].uid)
continue;
if (Suid[i].excl == excl) {
j = 1;
continue;
}
(void) fprintf(stderr,
"%s: UID %d has been included and excluded.\n",
Pn, (int)uid);
err = j = 1;
break;
}
if (j)
continue;
if (Nuid >= Mxuid) {
Mxuid += UIDINCR;
len = (MALLOC_S)(Mxuid * sizeof(struct seluid));
if (!Suid)
Suid = (struct seluid *)malloc(len);
else
Suid = (struct seluid *)realloc((MALLOC_P *)Suid, len);
if (!Suid) {
(void) fprintf(stderr, "%s: no space for UIDs", Pn);
Exit(1);
}
}
if (nn) {
if (!(lp = mkstrcpy(lnm, (MALLOC_S *)NULL))) {
(void) fprintf(stderr, "%s: no space for login: ", Pn);
safestrprt(lnm, stderr, 1);
Exit(1);
}
Suid[Nuid].lnm = lp;
} else
Suid[Nuid].lnm = (char *)NULL;
Suid[Nuid].uid = uid;
Suid[Nuid++].excl = excl;
if (excl)
Nuidexcl++;
else
Nuidincl++;
}
return(err);
}
static char *
isIPv4addr(hn, a, al)
char *hn;
unsigned char *a;
int al;
{
int dc = 0;
int i;
int ov[MIN_AF_ADDR];
int ovx = 0;
if ((*hn < '0') || (*hn > '9'))
return((char *)NULL);
if (!a || (al < MIN_AF_ADDR))
return((char *)NULL);
ov[0] = (int)(*hn++ - '0');
while (*hn && (*hn != ':')) {
if (*hn == '.') {
dc++;
if ((ov[ovx] < 0) || (ov[ovx] > 255))
return((char *)NULL);
if (++ovx > (MIN_AF_ADDR - 1))
return((char *)NULL);
ov[ovx] = -1;
} else if ((*hn >= '0') && (*hn <= '9')) {
if (ov[ovx] < 0)
ov[ovx] = (int)(*hn - '0');
else
ov[ovx] = (ov[ovx] * 10) + (int)(*hn - '0');
} else {
return((char *)NULL);
}
hn++;
}
if ((dc != 3)
|| (ovx != (MIN_AF_ADDR - 1))
|| (ov[ovx] < 0) || (ov[ovx] > 255))
return((char *)NULL);
for (i = 0; i < MIN_AF_ADDR; i++) {
a[i] = (unsigned char)ov[i];
}
return(hn);
}
static struct hostent *
lkup_hostnm(hn, n)
char *hn;
struct nwad *n;
{
unsigned char *ap;
struct hostent *he;
int ln;
#if defined(HASIPv6)
he = gethostbyname2(hn, n->af);
#else
he = gethostbyname(hn);
#endif
if (!he)
return(he);
#if defined(HASIPv6)
if (n->af != he->h_addrtype)
return((struct hostent *)NULL);
if (n->af == AF_INET6) {
if (he->h_length > MAX_AF_ADDR)
return((struct hostent *)NULL);
(void) memcpy((void *)&n->a[0], (void *)he->h_addr, he->h_length);
if ((ln = MAX_AF_ADDR - he->h_length) > 0)
zeromem((char *)&n->a[he->h_length], ln);
return(he);
}
#endif
if (he->h_length != 4)
return((struct hostent *)NULL);
ap = (unsigned char *)he->h_addr;
n->a[0] = *ap++;
n->a[1] = *ap++;
n->a[2] = *ap++;
n->a[3] = *ap;
if ((ln = MAX_AF_ADDR - 4) > 0)
zeromem((char *)&n->a[4], ln);
return(he);
}