/* * print.c - common print support functions for lsof */ /* * Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana * 47907. All rights reserved. * * Written by Victor A. Abell * * This software is not subject to any license of the American Telephone * and Telegraph Company or the Regents of the University of California. * * Permission is granted to anyone to use this software for any purpose on * any computer system, and to alter it and redistribute it freely, subject * to the following restrictions: * * 1. Neither the authors nor Purdue University are responsible for any * consequences of the use of this software. * * 2. The origin of this software must not be misrepresented, either by * explicit claim or by omission. Credit to the authors and Purdue * University must appear in documentation and sources. * * 3. Altered versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 4. This notice may not be removed or altered. */ #ifndef lint static char copyright[] = "@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n"; static char *rcsid = "$Id: print.c,v 1.55 2013/01/02 17:14:59 abe Exp $"; #endif #include "lsof.h" /* * Local definitions, structures and function prototypes */ #define HCINC 64 /* host cache size increase chunk */ #define PORTHASHBUCKETS 128 /* port hash bucket count * !!MUST BE A POWER OF 2!! */ #define PORTTABTHRESH 10 /* threshold at which we will switch * from using getservbyport() to * getservent() -- see lkup_port() * and fill_porttab() */ struct hostcache { unsigned char a[MAX_AF_ADDR]; /* numeric address */ int af; /* address family -- e.g., AF_INET * or AF_INET6 */ char *name; /* name */ }; struct porttab { int port; MALLOC_S nl; /* name length (excluding '\0') */ int ss; /* service name status, 0 = lookup not * yet performed */ char *name; struct porttab *next; }; #if defined(HASNORPC_H) static struct porttab **Pth[2] = { NULL, NULL }; /* port hash buckets: * Pth[0] for TCP service names * Pth[1] for UDP service names */ #else /* !defined(HASNORPC_H) */ static struct porttab **Pth[4] = { NULL, NULL, NULL, NULL }; /* port hash buckets: * Pth[0] for TCP service names * Pth[1] for UDP service names * Pth[2] for TCP portmap info * Pth[3] for UDP portmap info */ #endif /* defined(HASNORPC_H) */ #define HASHPORT(p) (((((int)(p)) * 31415) >> 3) & (PORTHASHBUCKETS - 1)) #if !defined(HASNORPC_H) _PROTOTYPE(static void fill_portmap,(void)); _PROTOTYPE(static void update_portmap,(struct porttab *pt, char *pn)); #endif /* !defined(HASNORPC_H) */ _PROTOTYPE(static void fill_porttab,(void)); _PROTOTYPE(static char *lkup_port,(int p, int pr, int src)); _PROTOTYPE(static char *lkup_svcnam,(int h, int p, int pr, int ss)); _PROTOTYPE(static int printinaddr,(void)); /* * endnm() - locate end of Namech */ char * endnm(sz) size_t *sz; /* returned remaining size */ { register char *s; register size_t tsz; for (s = Namech, tsz = Namechl; *s; s++, tsz--) ; *sz = tsz; return(s); } #if !defined(HASNORPC_H) /* * fill_portmap() -- fill the RPC portmap program name table via a conversation * with the portmapper * * The following copyright notice acknowledges that this function was adapted * from getrpcportnam() of the source code of the OpenBSD netstat program. */ /* * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ static void fill_portmap() { char buf[128], *cp, *nm; CLIENT *c; int h, port, pr; MALLOC_S nl; struct pmaplist *p = (struct pmaplist *)NULL; struct porttab *pt; struct rpcent *r; struct TIMEVAL_LSOF tm; #if !defined(CAN_USE_CLNT_CREATE) struct hostent *he; struct sockaddr_in ia; int s = RPC_ANYSOCK; #endif /* !defined(CAN_USE_CLNT_CREATE) */ /* * Construct structures for communicating with the portmapper. */ #if !defined(CAN_USE_CLNT_CREATE) zeromem(&ia, sizeof(ia)); ia.sin_family = AF_INET; if ((he = gethostbyname("localhost"))) MEMMOVE((caddr_t)&ia.sin_addr, he->h_addr, he->h_length); ia.sin_port = htons(PMAPPORT); #endif /* !defined(CAN_USE_CLNT_CREATE) */ tm.tv_sec = 60; tm.tv_usec = 0; /* * Get an RPC client handle. Then ask for a dump of the port map. */ #if defined(CAN_USE_CLNT_CREATE) if (!(c = clnt_create("localhost", PMAPPROG, PMAPVERS, "tcp"))) #else /* !defined(CAN_USE_CLNT_CREATE) */ if (!(c = clnttcp_create(&ia, PMAPPROG, PMAPVERS, &s, 0, 0))) #endif /* defined(CAN_USE_CLNT_CREATE) */ return; if (clnt_call(c, PMAPPROC_DUMP, XDR_VOID, NULL, XDR_PMAPLIST, (caddr_t)&p, tm) != RPC_SUCCESS) { clnt_destroy(c); return; } /* * Loop through the port map dump, creating portmap table entries from TCP * and UDP members. */ for (; p; p = p->pml_next) { /* * Determine the port map entry's protocol; ignore all but TCP and UDP. */ if (p->pml_map.pm_prot == IPPROTO_TCP) pr = 2; else if (p->pml_map.pm_prot == IPPROTO_UDP) pr = 3; else continue; /* * See if there's already a portmap entry for this port. If there is, * ignore this entry. */ h = HASHPORT((port = (int)p->pml_map.pm_port)); for (pt = Pth[pr][h]; pt; pt = pt->next) { if (pt->port == port) break; } if (pt) continue; /* * Save the registration name or number. */ cp = (char *)NULL; if ((r = (struct rpcent *)getrpcbynumber(p->pml_map.pm_prog))) { if (r->r_name && strlen(r->r_name)) cp = r->r_name; } if (!cp) { (void) snpf(buf, sizeof(buf), "%lu", (unsigned long)p->pml_map.pm_prog); cp = buf; } if (!strlen(cp)) continue; /* * Allocate space for the portmap name entry and copy it there. */ if (!(nm = mkstrcpy(cp, &nl))) { (void) fprintf(stderr, "%s: can't allocate space for portmap entry: ", Pn); safestrprt(cp, stderr, 1); Exit(1); } if (!nl) { (void) free((FREE_P *)nm); continue; } /* * Allocate and fill a porttab struct entry for the portmap table. * Link it to the head of its hash bucket, and make it the new head. */ if (!(pt = (struct porttab *)malloc(sizeof(struct porttab)))) { (void) fprintf(stderr, "%s: can't allocate porttab entry for portmap: ", Pn); safestrprt(nm, stderr, 1); Exit(1); } pt->name = nm; pt->nl = nl; pt->port = port; pt->next = Pth[pr][h]; pt->ss = 0; Pth[pr][h] = pt; } clnt_destroy(c); } #endif /* !defined(HASNORPC_H) */ /* * fill_porttab() -- fill the TCP and UDP service name port table with a * getservent() scan */ static void fill_porttab() { int h, p, pr; MALLOC_S nl; char *nm; struct porttab *pt; struct servent *se; (void) endservent(); /* * Scan the services data base for TCP and UDP entries that have a non-null * name associated with them. */ (void) setservent(1); while ((se = getservent())) { if (!se->s_name || !se->s_proto) continue; if (strcasecmp(se->s_proto, "TCP") == 0) pr = 0; else if (strcasecmp(se->s_proto, "UDP") == 0) pr = 1; else continue; if (!se->s_name || !strlen(se->s_name)) continue; p = ntohs(se->s_port); /* * See if a port->service entry is already cached for this port and * prototcol. If it is, leave it alone. */ h = HASHPORT(p); for (pt = Pth[pr][h]; pt; pt = pt->next) { if (pt->port == p) break; } if (pt) continue; /* * Add a new entry to the cache for this port and protocol. */ if (!(nm = mkstrcpy(se->s_name, &nl))) { (void) fprintf(stderr, "%s: can't allocate %d bytes for port %d name: %s\n", Pn, (int)(nl + 1), p, se->s_name); Exit(1); } if (!nl) { (void) free((FREE_P *)nm); continue; } if (!(pt = (struct porttab *)malloc(sizeof(struct porttab)))) { (void) fprintf(stderr, "%s: can't allocate porttab entry for port %d: %s\n", Pn, p, se->s_name); Exit(1); } pt->name = nm; pt->nl = nl - 1; pt->port = p; pt->next = Pth[pr][h]; pt->ss = 0; Pth[pr][h] = pt; } (void) endservent(); } /* * gethostnm() - get host name */ char * gethostnm(ia, af) unsigned char *ia; /* Internet address */ int af; /* address family -- e.g., AF_INET * or AF_INET6 */ { int al = MIN_AF_ADDR; char hbuf[256]; static struct hostcache *hc = (struct hostcache *)NULL; static int hcx = 0; char *hn, *np; struct hostent *he = (struct hostent *)NULL; int i, j; MALLOC_S len; static int nhc = 0; /* * Search cache. */ #if defined(HASIPv6) if (af == AF_INET6) al = MAX_AF_ADDR; #endif /* defined(HASIPv6) */ for (i = 0; i < hcx; i++) { if (af != hc[i].af) continue; for (j = 0; j < al; j++) { if (ia[j] != hc[i].a[j]) break; } if (j >= al) return(hc[i].name); } /* * If -n has been specified, construct a numeric address. Otherwise, look up * host name by address. If that fails, or if there is no name in the returned * hostent structure, construct a numeric version of the address. */ if (Fhost) he = gethostbyaddr((char *)ia, al, af); if (!he || !he->h_name) { #if defined(HASIPv6) if (af == AF_INET6) { /* * Since IPv6 numeric addresses use `:' as a separator, enclose * them in brackets. */ hbuf[0] = '['; if (!inet_ntop(af, ia, hbuf + 1, sizeof(hbuf) - 3)) { (void) snpf(&hbuf[1], (sizeof(hbuf) - 1), "can't format IPv6 address]"); } else { len = strlen(hbuf); (void) snpf(&hbuf[len], sizeof(hbuf) - len, "]"); } } else #endif /* defined(HASIPv6) */ if (af == AF_INET) (void) snpf(hbuf, sizeof(hbuf), "%u.%u.%u.%u", ia[0], ia[1], ia[2], ia[3]); else (void) snpf(hbuf, sizeof(hbuf), "(unknown AF value: %d)", af); hn = hbuf; } else hn = (char *)he->h_name; /* * Allocate space for name and copy name to it. */ if (!(np = mkstrcpy(hn, (MALLOC_S *)NULL))) { (void) fprintf(stderr, "%s: no space for host name: ", Pn); safestrprt(hn, stderr, 1); Exit(1); } /* * Add address/name entry to cache. Allocate cache space in HCINC chunks. */ if (hcx >= nhc) { nhc += HCINC; len = (MALLOC_S)(nhc * sizeof(struct hostcache)); if (!hc) hc = (struct hostcache *)malloc(len); else hc = (struct hostcache *)realloc((MALLOC_P *)hc, len); if (!hc) { (void) fprintf(stderr, "%s: no space for host cache\n", Pn); Exit(1); } } hc[hcx].af = af; for (i = 0; i < al; i++) { hc[hcx].a[i] = ia[i]; } hc[hcx++].name = np; return(np); } /* * lkup_port() - look up port for protocol */ static char * lkup_port(p, pr, src) int p; /* port number */ int pr; /* protocol index: 0 = tcp, 1 = udp */ int src; /* port source: 0 = local * 1 = foreign */ { int h, nh; MALLOC_S nl; char *nm, *pn; static char pb[128]; static int pm = 0; struct porttab *pt; /* * If the hash buckets haven't been allocated, do so. */ if (!Pth[0]) { #if defined(HASNORPC_H) nh = 2; #else /* !defined(HASNORPC_H) */ nh = FportMap ? 4 : 2; #endif /* defined(HASNORPC_H) */ for (h = 0; h < nh; h++) { if (!(Pth[h] = (struct porttab **)calloc(PORTHASHBUCKETS, sizeof(struct porttab *)))) { (void) fprintf(stderr, "%s: can't allocate %d bytes for %s %s hash buckets\n", Pn, (int)(2 * (PORTHASHBUCKETS * sizeof(struct porttab *))), (h & 1) ? "UDP" : "TCP", (h > 1) ? "portmap" : "port"); Exit(1); } } } #if !defined(HASNORPC_H) /* * If we're looking up program names for portmapped ports, make sure the * portmap table has been loaded. */ if (FportMap && !pm) { (void) fill_portmap(); pm++; } #endif /* !defined(HASNORPC_H) */ /* * Hash the port and see if its name has been cached. Look for a local * port first in the portmap, if portmap searching is enabled. */ h = HASHPORT(p); #if !defined(HASNORPC_H) if (!src && FportMap) { for (pt = Pth[pr+2][h]; pt; pt = pt->next) { if (pt->port != p) continue; if (!pt->ss) { pn = Fport ? lkup_svcnam(h, p, pr, 0) : (char *)NULL; if (!pn) { (void) snpf(pb, sizeof(pb), "%d", p); pn = pb; } (void) update_portmap(pt, pn); } return(pt->name); } } #endif /* !defined(HASNORPC_H) */ for (pt = Pth[pr][h]; pt; pt = pt->next) { if (pt->port == p) return(pt->name); } /* * Search for a possible service name, unless the -P option has been specified. * * If there is no service name, return a %d conversion. * * Don't cache %d conversions; a zero port number is a %d conversion that * is represented by "*". */ pn = Fport ? lkup_svcnam(h, p, pr, 1) : (char *)NULL; if (!pn || !strlen(pn)) { if (p) { (void) snpf(pb, sizeof(pb), "%d", p); return(pb); } else return("*"); } /* * Allocate a new porttab entry for the TCP or UDP service name. */ if (!(pt = (struct porttab *)malloc(sizeof(struct porttab)))) { (void) fprintf(stderr, "%s: can't allocate porttab entry for port %d\n", Pn, p); Exit(1); } /* * Allocate space for the name; copy it to the porttab entry; and link the * porttab entry to its hash bucket. * * Return a pointer to the name. */ if (!(nm = mkstrcpy(pn, &nl))) { (void) fprintf(stderr, "%s: can't allocate space for port name: ", Pn); safestrprt(pn, stderr, 1); Exit(1); } pt->name = nm; pt->nl = nl; pt->port = p; pt->next = Pth[pr][h]; pt->ss = 0; Pth[pr][h] = pt; return(nm); } /* * lkup_svcnam() - look up service name for port */ static char * lkup_svcnam(h, p, pr, ss) int h; /* porttab hash index */ int p; /* port number */ int pr; /* protocol: 0 = TCP, 1 = UDP */ int ss; /* search status: 1 = Pth[pr][h] * already searched */ { static int fl[PORTTABTHRESH]; static int fln = 0; static int gsbp = 0; int i; struct porttab *pt; static int ptf = 0; struct servent *se; /* * Do nothing if -P has been specified. */ if (!Fport) return((char *)NULL); for (;;) { /* * Search service name cache, if it hasn't already been done. * Return the name of a match. */ if (!ss) { for (pt = Pth[pr][h]; pt; pt = pt->next) { if (pt->port == p) return(pt->name); } } /* * If fill_porttab() has been called, there is no service name. * * Do PORTTABTHRES getservbport() calls, remembering the failures, so they * won't be repeated. * * After PORTABTHRESH getservbyport() calls, call fill_porttab() once, */ if (ptf) break; if (gsbp < PORTTABTHRESH) { for (i = 0; i < fln; i++) { if (fl[i] == p) return((char *)NULL); } gsbp++; if ((se = getservbyport(htons(p), pr ? "udp" : "tcp"))) return(se->s_name); if (fln < PORTTABTHRESH) fl[fln++] = p; return((char *)NULL); } (void) fill_porttab(); ptf++; ss = 0; } return((char *)NULL); } /* * print_file() - print file */ void print_file() { char buf[128]; char *cp = (char *)NULL; dev_t dev; int devs, len; if (PrPass && !Hdr) { /* * Print the header line if this is the second pass and the * header hasn't already been printed. */ (void) printf("%-*.*s %*s", CmdColW, CmdColW, CMDTTL, PidColW, PIDTTL); #if defined(HASTASKS) if (TaskPrtFl) (void) printf(" %*s", TidColW, TIDTTL); #endif /* defined(HASTASKS) */ #if defined(HASZONES) if (Fzone) (void) printf(" %-*s", ZoneColW, ZONETTL); #endif /* defined(HASZONES) */ #if defined(HASSELINUX) if (Fcntx) (void) printf(" %-*s", CntxColW, CNTXTTL); #endif /* defined(HASSELINUX) */ #if defined(HASPPID) if (Fppid) (void) printf(" %*s", PpidColW, PPIDTTL); #endif /* defined(HASPPID) */ if (Fpgid) (void) printf(" %*s", PgidColW, PGIDTTL); (void) printf(" %*s %*s %*s", UserColW, USERTTL, FdColW - 2, FDTTL, TypeColW, TYPETTL); #if defined(HASFSTRUCT) if (Fsv) { # if !defined(HASNOFSADDR) if (Fsv & FSV_FA) (void) printf(" %*s", FsColW, FSTTL); # endif /* !defined(HASNOFSADDR) */ # if !defined(HASNOFSCOUNT) if (Fsv & FSV_CT) (void) printf(" %*s", FcColW, FCTTL); # endif /* !defined(HASNOFSCOUNT) */ # if !defined(HASNOFSFLAGS) if (Fsv & FSV_FG) (void) printf(" %*s", FgColW, FGTTL); # endif /* !defined(HASNOFSFLAGS) */ # if !defined(HASNOFSNADDR) if (Fsv & FSV_NI) (void) printf(" %*s", NiColW, NiTtl); # endif /* !defined(HASNOFSNADDR) */ } #endif /* defined(HASFSTRUCT) */ (void) printf(" %*s", DevColW, DEVTTL); if (Foffset) (void) printf(" %*s", SzOffColW, OFFTTL); else if (Fsize) (void) printf(" %*s", SzOffColW, SZTTL); else (void) printf(" %*s", SzOffColW, SZOFFTTL); if (Fnlink) (void) printf(" %*s", NlColW, NLTTL); (void) printf(" %*s %s\n", NodeColW, NODETTL, NMTTL); Hdr++; } /* * Size or print the command. */ cp = (Lp->cmd && *Lp->cmd != '\0') ? Lp->cmd : "(unknown)"; if (!PrPass) { len = safestrlen(cp, 2); if (CmdLim && (len > CmdLim)) len = CmdLim; if (len > CmdColW) CmdColW = len; } else safestrprtn(cp, CmdColW, stdout, 2); /* * Size or print the process ID. */ if (!PrPass) { (void) snpf(buf, sizeof(buf), "%d", Lp->pid); if ((len = strlen(buf)) > PidColW) PidColW = len; } else (void) printf(" %*d", PidColW, Lp->pid); #if defined(HASTASKS) /* * Size or print task ID. */ if (!PrPass) { if (Lp->tid) { (void) snpf(buf, sizeof(buf), "%d", Lp->tid); if ((len = strlen(buf)) > TidColW) TidColW = len; TaskPrtFl = 1; } } else if (TaskPrtFl) { if (Lp->tid) (void) printf(" %*d", TidColW, Lp->tid); else (void) printf(" %*s", TidColW, ""); } #endif /* defined(HASTASKS) */ #if defined(HASZONES) /* * Size or print the zone. */ if (Fzone) { if (!PrPass) { if (Lp->zn) { if ((len = strlen(Lp->zn)) > ZoneColW) ZoneColW = len; } } else (void) printf(" %-*s", ZoneColW, Lp->zn ? Lp->zn : ""); } #endif /* defined(HASZONES) */ #if defined(HASSELINUX) /* * Size or print the context. */ if (Fcntx) { if (!PrPass) { if (Lp->cntx) { if ((len = strlen(Lp->cntx)) > CntxColW) CntxColW = len; } } else (void) printf(" %-*s", CntxColW, Lp->cntx ? Lp->cntx : ""); } #endif /* defined(HASSELINUX) */ #if defined(HASPPID) if (Fppid) { /* * Size or print the parent process ID. */ if (!PrPass) { (void) snpf(buf, sizeof(buf), "%d", Lp->ppid); if ((len = strlen(buf)) > PpidColW) PpidColW = len; } else (void) printf(" %*d", PpidColW, Lp->ppid); } #endif /* defined(HASPPID) */ if (Fpgid) { /* * Size or print the process group ID. */ if (!PrPass) { (void) snpf(buf, sizeof(buf), "%d", Lp->pgid); if ((len = strlen(buf)) > PgidColW) PgidColW = len; } else (void) printf(" %*d", PgidColW, Lp->pgid); } /* * Size or print the user ID or login name. */ if (!PrPass) { if ((len = strlen(printuid((UID_ARG)Lp->uid, NULL))) > UserColW) UserColW = len; } else (void) printf(" %*.*s", UserColW, UserColW, printuid((UID_ARG)Lp->uid, NULL)); /* * Size or print the file descriptor, access mode and lock status. */ if (!PrPass) { (void) snpf(buf, sizeof(buf), "%s%c%c", Lf->fd, (Lf->lock == ' ') ? Lf->access : (Lf->access == ' ') ? '-' : Lf->access, Lf->lock); if ((len = strlen(buf)) > FdColW) FdColW = len; } else (void) printf(" %*.*s%c%c", FdColW - 2, FdColW - 2, Lf->fd, (Lf->lock == ' ') ? Lf->access : (Lf->access == ' ') ? '-' : Lf->access, Lf->lock); /* * Size or print the type. */ if (!PrPass) { if ((len = strlen(Lf->type)) > TypeColW) TypeColW = len; } else (void) printf(" %*.*s", TypeColW, TypeColW, Lf->type); #if defined(HASFSTRUCT) /* * Size or print the file structure address, file usage count, and node * ID (address). */ if (Fsv) { # if !defined(HASNOFSADDR) if (Fsv & FSV_FA) { cp = (Lf->fsv & FSV_FA) ? print_kptr(Lf->fsa, buf, sizeof(buf)) : ""; if (!PrPass) { if ((len = strlen(cp)) > FsColW) FsColW = len; } else (void) printf(" %*.*s", FsColW, FsColW, cp); } # endif /* !defined(HASNOFSADDR) */ # if !defined(HASNOFSCOUNT) if (Fsv & FSV_CT) { if (Lf->fsv & FSV_CT) { (void) snpf(buf, sizeof(buf), "%ld", Lf->fct); cp = buf; } else cp = ""; if (!PrPass) { if ((len = strlen(cp)) > FcColW) FcColW = len; } else (void) printf(" %*.*s", FcColW, FcColW, cp); } # endif /* !defined(HASNOFSCOUNT) */ # if !defined(HASNOFSFLAGS) if (Fsv & FSV_FG) { if ((Lf->fsv & FSV_FG) && (FsvFlagX || Lf->ffg || Lf->pof)) cp = print_fflags(Lf->ffg, Lf->pof); else cp = ""; if (!PrPass) { if ((len = strlen(cp)) > FgColW) FgColW = len; } else (void) printf(" %*.*s", FgColW, FgColW, cp); } # endif /* !defined(HASNOFSFLAGS) */ # if !defined(HASNOFSNADDR) if (Fsv & FSV_NI) { cp = (Lf->fsv & FSV_NI) ? print_kptr(Lf->fna, buf, sizeof(buf)) : ""; if (!PrPass) { if ((len = strlen(cp)) > NiColW) NiColW = len; } else (void) printf(" %*.*s", NiColW, NiColW, cp); } # endif /* !defined(HASNOFSNADDR) */ } #endif /* defined(HASFSTRUCT) */ /* * Size or print the device information. */ if (Lf->rdev_def) { dev = Lf->rdev; devs = 1; } else if (Lf->dev_def) { dev = Lf->dev; devs = 1; } else devs = 0; if (devs) { #if defined(HASPRINTDEV) cp = HASPRINTDEV(Lf, &dev); #else /* !defined(HASPRINTDEV) */ (void) snpf(buf, sizeof(buf), "%u,%u", GET_MAJ_DEV(dev), GET_MIN_DEV(dev)); cp = buf; #endif /* defined(HASPRINTDEV) */ } if (!PrPass) { if (devs) len = strlen(cp); else if (Lf->dev_ch) len = strlen(Lf->dev_ch); else len = 0; if (len > DevColW) DevColW = len; } else { if (devs) (void) printf(" %*.*s", DevColW, DevColW, cp); else { if (Lf->dev_ch) (void) printf(" %*.*s", DevColW, DevColW, Lf->dev_ch); else (void) printf(" %*.*s", DevColW, DevColW, ""); } } /* * Size or print the size or offset. */ if (!PrPass) { if (Lf->sz_def) { #if defined(HASPRINTSZ) cp = HASPRINTSZ(Lf); #else /* !defined(HASPRINTSZ) */ (void) snpf(buf, sizeof(buf), SzOffFmt_d, Lf->sz); cp = buf; #endif /* defined(HASPRINTSZ) */ len = strlen(cp); } else if (Lf->off_def) { #if defined(HASPRINTOFF) cp = HASPRINTOFF(Lf, 0); #else /* !defined(HASPRINTOFF) */ (void) snpf(buf, sizeof(buf), SzOffFmt_0t, Lf->off); cp = buf; #endif /* defined(HASPRINTOFF) */ len = strlen(cp); if (OffDecDig && len > (OffDecDig + 2)) { #if defined(HASPRINTOFF) cp = HASPRINTOFF(Lf, 1); #else /* !defined(HASPRINTOFF) */ (void) snpf(buf, sizeof(buf), SzOffFmt_x, Lf->off); cp = buf; #endif /* defined(HASPRINTOFF) */ len = strlen(cp); } } else len = 0; if (len > SzOffColW) SzOffColW = len; } else { putchar(' '); if (Lf->sz_def) #if defined(HASPRINTSZ) (void) printf("%*.*s", SzOffColW, SzOffColW, HASPRINTSZ(Lf)); #else /* !defined(HASPRINTSZ) */ (void) printf(SzOffFmt_dv, SzOffColW, Lf->sz); #endif /* defined(HASPRINTSZ) */ else if (Lf->off_def) { #if defined(HASPRINTOFF) cp = HASPRINTOFF(Lf, 0); #else /* !defined(HASPRINTOFF) */ (void) snpf(buf, sizeof(buf), SzOffFmt_0t, Lf->off); cp = buf; #endif /* defined(HASPRINTOFF) */ if (OffDecDig && (int)strlen(cp) > (OffDecDig + 2)) { #if defined(HASPRINTOFF) cp = HASPRINTOFF(Lf, 1); #else /* !defined(HASPRINTOFF) */ (void) snpf(buf, sizeof(buf), SzOffFmt_x, Lf->off); cp = buf; #endif /* defined(HASPRINTOFF) */ } (void) printf("%*.*s", SzOffColW, SzOffColW, cp); } else (void) printf("%*.*s", SzOffColW, SzOffColW, ""); } /* * Size or print the link count. */ if (Fnlink) { if (Lf->nlink_def) { (void) snpf(buf, sizeof(buf), " %ld", Lf->nlink); cp = buf; } else cp = ""; if (!PrPass) { if ((len = strlen(cp)) > NlColW) NlColW = len; } else (void) printf(" %*s", NlColW, cp); } /* * Size or print the inode information. */ switch (Lf->inp_ty) { case 1: #if defined(HASPRINTINO) cp = HASPRINTINO(Lf); #else /* !defined(HASPRINTINO) */ (void) snpf(buf, sizeof(buf), InodeFmt_d, Lf->inode); cp = buf; #endif /* defined(HASPRINTINO) */ break; case 2: if (Lf->iproto[0]) cp = Lf->iproto; else cp = ""; break; case 3: (void) snpf(buf, sizeof(buf), InodeFmt_x, Lf->inode); cp = buf; break; default: cp = ""; } if (!PrPass) { if ((len = strlen(cp)) > NodeColW) NodeColW = len; } else { (void) printf(" %*.*s", NodeColW, NodeColW, cp); } /* * If this is the second pass, print the name column. (It doesn't need * to be sized.) */ if (PrPass) { putchar(' '); #if defined(HASPRINTNM) HASPRINTNM(Lf); #else /* !defined(HASPRINTNM) */ printname(1); #endif /* defined(HASPRINTNM) */ } } /* * printinaddr() - print Internet addresses */ static int printinaddr() { int i, len, src; char *host, *port; int nl = Namechl - 1; char *np = Namech; char pbuf[32]; /* * Process local network address first. If there's a foreign address, * separate it from the local address with "->". */ for (i = 0, *np = '\0'; i < 2; i++) { if (!Lf->li[i].af) continue; host = port = (char *)NULL; if (i) { /* * If this is the foreign address, insert the separator. */ if (nl < 2) addr_too_long: { (void) snpf(Namech, Namechl, "network addresses too long"); return(1); } (void) snpf(np, nl, "->"); np += 2; nl -= 2; } /* * Convert the address to a host name. */ #if defined(HASIPv6) if ((Lf->li[i].af == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&Lf->li[i].ia.a6)) || (Lf->li[i].af == AF_INET && Lf->li[i].ia.a4.s_addr == INADDR_ANY)) host ="*"; else host = gethostnm((unsigned char *)&Lf->li[i].ia, Lf->li[i].af); #else /* !defined(HASIPv6) */ if (Lf->li[i].ia.a4.s_addr == INADDR_ANY) host ="*"; else host = gethostnm((unsigned char *)&Lf->li[i].ia, Lf->li[i].af); #endif /* defined(HASIPv6) */ /* * Process the port number. */ if (Lf->li[i].p > 0) { if (Fport #if !defined(HASNORPC_H) || FportMap #endif /* defined(HASNORPC_H) */ ) { /* * If converting port numbers to service names, or looking * up portmap program names and numbers, do so by protocol. * * Identify the port source as local if: 1) it comes from the * local entry (0) of the file's Internet address array; or * 2) it comes from the foreign entry (1), and the foreign * Internet address matches the local one; or 3) it is the * loopback address 127.0.0.1. (Test 2 may not always work * -- e.g., on hosts with multiple interfaces.) */ #if !defined(HASNORPC_H) if ((src = i) && FportMap) { # if defined(HASIPv6) if (Lf->li[0].af == AF_INET6) { if (IN6_IS_ADDR_LOOPBACK(&Lf->li[i].ia.a6) || IN6_ARE_ADDR_EQUAL(&Lf->li[0].ia.a6, &Lf->li[1].ia.a6) ) src = 0; } else # endif /* defined(HASIPv6) */ if (Lf->li[0].af == AF_INET) { if (Lf->li[i].ia.a4.s_addr == htonl(INADDR_LOOPBACK) || Lf->li[0].ia.a4.s_addr == Lf->li[1].ia.a4.s_addr ) src = 0; } } #endif /* !defined(HASNORPC_H) */ if (strcasecmp(Lf->iproto, "TCP") == 0) port = lkup_port(Lf->li[i].p, 0, src); else if (strcasecmp(Lf->iproto, "UDP") == 0) port = lkup_port(Lf->li[i].p, 1, src); } if (!port) { (void) snpf(pbuf, sizeof(pbuf), "%d", Lf->li[i].p); port = pbuf; } } else if (Lf->li[i].p == 0) port = "*"; /* * Enter the host name. */ if (host) { if ((len = strlen(host)) > nl) goto addr_too_long; if (len) { (void) snpf(np, nl, "%s", host); np += len; nl -= len; } } /* * Enter the port number, preceded by a colon. */ if (port) { if (((len = strlen(port)) + 1) >= nl) goto addr_too_long; (void) snpf(np, nl, ":%s", port); np += len + 1; nl -= len - 1; } } if (Namech[0]) { safestrprt(Namech, stdout, 0); return(1); } return(0); } /* * print_init() - initialize for printing */ void print_init() { /* * Preset standard values. */ PrPass = (Ffield || Fterse) ? 1 : 0; LastPid = -1; TaskPrtFl = 0; /* * Size columns by their titles. */ CmdColW = strlen(CMDTTL); DevColW = strlen(DEVTTL); FdColW = strlen(FDTTL); if (Fnlink) NlColW = strlen(NLTTL); NmColW = strlen(NMTTL); NodeColW = strlen(NODETTL); PgidColW = strlen(PGIDTTL); PidColW = strlen(PIDTTL); PpidColW = strlen(PPIDTTL); if (Fsize) SzOffColW = strlen(SZTTL); else if (Foffset) SzOffColW = strlen(OFFTTL); else SzOffColW = strlen(SZOFFTTL); #if defined(HASTASKS) TidColW = strlen(TIDTTL); #endif /* defined(HASTASKS) */ TypeColW = strlen(TYPETTL); UserColW = strlen(USERTTL); #if defined(HASFSTRUCT) # if !defined(HASNOFSADDR) FsColW = strlen(FSTTL); # endif /* !defined(HASNOFSADDR) */ # if !defined(HASNOFSCOUNT) FcColW = strlen(FCTTL); # endif /* !defined(HASNOFSCOUNT) */ # if !defined(HASNOFSFLAGS) FgColW = strlen(FGTTL); # endif /* !defined(HASNOFSFLAGS) */ # if !defined(HASNOFSNADDR) NiColW = strlen(NiTtl); # endif /* !defined(HASNOFSNADDR) */ #endif /* defined(HASFSTRUCT) */ #if defined(HASSELINUX) if (Fcntx) CntxColW = strlen(CNTXTTL); #endif /* defined(HASSELINUX) */ #if defined(HASZONES) if (Fzone) ZoneColW = strlen(ZONETTL); #endif /* defined(HASZONES) */ } #if !defined(HASPRIVPRIPP) /* * printiproto() - print Internet protocol name */ void printiproto(p) int p; /* protocol number */ { int i; static int m = -1; char *s; switch (p) { #if defined(IPPROTO_TCP) case IPPROTO_TCP: s = "TCP"; break; #endif /* defined(IPPROTO_TCP) */ #if defined(IPPROTO_UDP) case IPPROTO_UDP: s = "UDP"; break; #endif /* defined(IPPROTO_UDP) */ #if defined(IPPROTO_IP) # if !defined(IPPROTO_HOPOPTS) || IPPROTO_IP!=IPPROTO_HOPOPTS case IPPROTO_IP: s = "IP"; break; # endif /* !defined(IPPROTO_HOPOPTS) || IPPROTO_IP!=IPPROTO_HOPOPTS */ #endif /* defined(IPPROTO_IP) */ #if defined(IPPROTO_ICMP) case IPPROTO_ICMP: s = "ICMP"; break; #endif /* defined(IPPROTO_ICMP) */ #if defined(IPPROTO_ICMPV6) case IPPROTO_ICMPV6: s = "ICMPV6"; break; #endif /* defined(IPPROTO_ICMPV6) */ #if defined(IPPROTO_IGMP) case IPPROTO_IGMP: s = "IGMP"; break; #endif /* defined(IPPROTO_IGMP) */ #if defined(IPPROTO_GGP) case IPPROTO_GGP: s = "GGP"; break; #endif /* defined(IPPROTO_GGP) */ #if defined(IPPROTO_EGP) case IPPROTO_EGP: s = "EGP"; break; #endif /* defined(IPPROTO_EGP) */ #if defined(IPPROTO_PUP) case IPPROTO_PUP: s = "PUP"; break; #endif /* defined(IPPROTO_PUP) */ #if defined(IPPROTO_IDP) case IPPROTO_IDP: s = "IDP"; break; #endif /* defined(IPPROTO_IDP) */ #if defined(IPPROTO_ND) case IPPROTO_ND: s = "ND"; break; #endif /* defined(IPPROTO_ND) */ #if defined(IPPROTO_RAW) case IPPROTO_RAW: s = "RAW"; break; #endif /* defined(IPPROTO_RAW) */ #if defined(IPPROTO_HELLO) case IPPROTO_HELLO: s = "HELLO"; break; #endif /* defined(IPPROTO_HELLO) */ #if defined(IPPROTO_PXP) case IPPROTO_PXP: s = "PXP"; break; #endif /* defined(IPPROTO_PXP) */ #if defined(IPPROTO_RAWIP) case IPPROTO_RAWIP: s = "RAWIP"; break; #endif /* defined(IPPROTO_RAWIP) */ #if defined(IPPROTO_RAWIF) case IPPROTO_RAWIF: s = "RAWIF"; break; #endif /* defined(IPPROTO_RAWIF) */ #if defined(IPPROTO_HOPOPTS) case IPPROTO_HOPOPTS: s = "HOPOPTS"; break; #endif /* defined(IPPROTO_HOPOPTS) */ #if defined(IPPROTO_IPIP) case IPPROTO_IPIP: s = "IPIP"; break; #endif /* defined(IPPROTO_IPIP) */ #if defined(IPPROTO_ST) case IPPROTO_ST: s = "ST"; break; #endif /* defined(IPPROTO_ST) */ #if defined(IPPROTO_PIGP) case IPPROTO_PIGP: s = "PIGP"; break; #endif /* defined(IPPROTO_PIGP) */ #if defined(IPPROTO_RCCMON) case IPPROTO_RCCMON: s = "RCCMON"; break; #endif /* defined(IPPROTO_RCCMON) */ #if defined(IPPROTO_NVPII) case IPPROTO_NVPII: s = "NVPII"; break; #endif /* defined(IPPROTO_NVPII) */ #if defined(IPPROTO_ARGUS) case IPPROTO_ARGUS: s = "ARGUS"; break; #endif /* defined(IPPROTO_ARGUS) */ #if defined(IPPROTO_EMCON) case IPPROTO_EMCON: s = "EMCON"; break; #endif /* defined(IPPROTO_EMCON) */ #if defined(IPPROTO_XNET) case IPPROTO_XNET: s = "XNET"; break; #endif /* defined(IPPROTO_XNET) */ #if defined(IPPROTO_CHAOS) case IPPROTO_CHAOS: s = "CHAOS"; break; #endif /* defined(IPPROTO_CHAOS) */ #if defined(IPPROTO_MUX) case IPPROTO_MUX: s = "MUX"; break; #endif /* defined(IPPROTO_MUX) */ #if defined(IPPROTO_MEAS) case IPPROTO_MEAS: s = "MEAS"; break; #endif /* defined(IPPROTO_MEAS) */ #if defined(IPPROTO_HMP) case IPPROTO_HMP: s = "HMP"; break; #endif /* defined(IPPROTO_HMP) */ #if defined(IPPROTO_PRM) case IPPROTO_PRM: s = "PRM"; break; #endif /* defined(IPPROTO_PRM) */ #if defined(IPPROTO_TRUNK1) case IPPROTO_TRUNK1: s = "TRUNK1"; break; #endif /* defined(IPPROTO_TRUNK1) */ #if defined(IPPROTO_TRUNK2) case IPPROTO_TRUNK2: s = "TRUNK2"; break; #endif /* defined(IPPROTO_TRUNK2) */ #if defined(IPPROTO_LEAF1) case IPPROTO_LEAF1: s = "LEAF1"; break; #endif /* defined(IPPROTO_LEAF1) */ #if defined(IPPROTO_LEAF2) case IPPROTO_LEAF2: s = "LEAF2"; break; #endif /* defined(IPPROTO_LEAF2) */ #if defined(IPPROTO_RDP) case IPPROTO_RDP: s = "RDP"; break; #endif /* defined(IPPROTO_RDP) */ #if defined(IPPROTO_IRTP) case IPPROTO_IRTP: s = "IRTP"; break; #endif /* defined(IPPROTO_IRTP) */ #if defined(IPPROTO_TP) case IPPROTO_TP: s = "TP"; break; #endif /* defined(IPPROTO_TP) */ #if defined(IPPROTO_BLT) case IPPROTO_BLT: s = "BLT"; break; #endif /* defined(IPPROTO_BLT) */ #if defined(IPPROTO_NSP) case IPPROTO_NSP: s = "NSP"; break; #endif /* defined(IPPROTO_NSP) */ #if defined(IPPROTO_INP) case IPPROTO_INP: s = "INP"; break; #endif /* defined(IPPROTO_INP) */ #if defined(IPPROTO_SEP) case IPPROTO_SEP: s = "SEP"; break; #endif /* defined(IPPROTO_SEP) */ #if defined(IPPROTO_3PC) case IPPROTO_3PC: s = "3PC"; break; #endif /* defined(IPPROTO_3PC) */ #if defined(IPPROTO_IDPR) case IPPROTO_IDPR: s = "IDPR"; break; #endif /* defined(IPPROTO_IDPR) */ #if defined(IPPROTO_XTP) case IPPROTO_XTP: s = "XTP"; break; #endif /* defined(IPPROTO_XTP) */ #if defined(IPPROTO_DDP) case IPPROTO_DDP: s = "DDP"; break; #endif /* defined(IPPROTO_DDP) */ #if defined(IPPROTO_CMTP) case IPPROTO_CMTP: s = "CMTP"; break; #endif /* defined(IPPROTO_CMTP) */ #if defined(IPPROTO_TPXX) case IPPROTO_TPXX: s = "TPXX"; break; #endif /* defined(IPPROTO_TPXX) */ #if defined(IPPROTO_IL) case IPPROTO_IL: s = "IL"; break; #endif /* defined(IPPROTO_IL) */ #if defined(IPPROTO_IPV6) case IPPROTO_IPV6: s = "IPV6"; break; #endif /* defined(IPPROTO_IPV6) */ #if defined(IPPROTO_SDRP) case IPPROTO_SDRP: s = "SDRP"; break; #endif /* defined(IPPROTO_SDRP) */ #if defined(IPPROTO_ROUTING) case IPPROTO_ROUTING: s = "ROUTING"; break; #endif /* defined(IPPROTO_ROUTING) */ #if defined(IPPROTO_FRAGMENT) case IPPROTO_FRAGMENT: s = "FRAGMNT"; break; #endif /* defined(IPPROTO_FRAGMENT) */ #if defined(IPPROTO_IDRP) case IPPROTO_IDRP: s = "IDRP"; break; #endif /* defined(IPPROTO_IDRP) */ #if defined(IPPROTO_RSVP) case IPPROTO_RSVP: s = "RSVP"; break; #endif /* defined(IPPROTO_RSVP) */ #if defined(IPPROTO_GRE) case IPPROTO_GRE: s = "GRE"; break; #endif /* defined(IPPROTO_GRE) */ #if defined(IPPROTO_MHRP) case IPPROTO_MHRP: s = "MHRP"; break; #endif /* defined(IPPROTO_MHRP) */ #if defined(IPPROTO_BHA) case IPPROTO_BHA: s = "BHA"; break; #endif /* defined(IPPROTO_BHA) */ #if defined(IPPROTO_ESP) case IPPROTO_ESP: s = "ESP"; break; #endif /* defined(IPPROTO_ESP) */ #if defined(IPPROTO_AH) case IPPROTO_AH: s = "AH"; break; #endif /* defined(IPPROTO_AH) */ #if defined(IPPROTO_INLSP) case IPPROTO_INLSP: s = "INLSP"; break; #endif /* defined(IPPROTO_INLSP) */ #if defined(IPPROTO_SWIPE) case IPPROTO_SWIPE: s = "SWIPE"; break; #endif /* defined(IPPROTO_SWIPE) */ #if defined(IPPROTO_NHRP) case IPPROTO_NHRP: s = "NHRP"; break; #endif /* defined(IPPROTO_NHRP) */ #if defined(IPPROTO_NONE) case IPPROTO_NONE: s = "NONE"; break; #endif /* defined(IPPROTO_NONE) */ #if defined(IPPROTO_DSTOPTS) case IPPROTO_DSTOPTS: s = "DSTOPTS"; break; #endif /* defined(IPPROTO_DSTOPTS) */ #if defined(IPPROTO_AHIP) case IPPROTO_AHIP: s = "AHIP"; break; #endif /* defined(IPPROTO_AHIP) */ #if defined(IPPROTO_CFTP) case IPPROTO_CFTP: s = "CFTP"; break; #endif /* defined(IPPROTO_CFTP) */ #if defined(IPPROTO_SATEXPAK) case IPPROTO_SATEXPAK: s = "SATEXPK"; break; #endif /* defined(IPPROTO_SATEXPAK) */ #if defined(IPPROTO_KRYPTOLAN) case IPPROTO_KRYPTOLAN: s = "KRYPTOL"; break; #endif /* defined(IPPROTO_KRYPTOLAN) */ #if defined(IPPROTO_RVD) case IPPROTO_RVD: s = "RVD"; break; #endif /* defined(IPPROTO_RVD) */ #if defined(IPPROTO_IPPC) case IPPROTO_IPPC: s = "IPPC"; break; #endif /* defined(IPPROTO_IPPC) */ #if defined(IPPROTO_ADFS) case IPPROTO_ADFS: s = "ADFS"; break; #endif /* defined(IPPROTO_ADFS) */ #if defined(IPPROTO_SATMON) case IPPROTO_SATMON: s = "SATMON"; break; #endif /* defined(IPPROTO_SATMON) */ #if defined(IPPROTO_VISA) case IPPROTO_VISA: s = "VISA"; break; #endif /* defined(IPPROTO_VISA) */ #if defined(IPPROTO_IPCV) case IPPROTO_IPCV: s = "IPCV"; break; #endif /* defined(IPPROTO_IPCV) */ #if defined(IPPROTO_CPNX) case IPPROTO_CPNX: s = "CPNX"; break; #endif /* defined(IPPROTO_CPNX) */ #if defined(IPPROTO_CPHB) case IPPROTO_CPHB: s = "CPHB"; break; #endif /* defined(IPPROTO_CPHB) */ #if defined(IPPROTO_WSN) case IPPROTO_WSN: s = "WSN"; break; #endif /* defined(IPPROTO_WSN) */ #if defined(IPPROTO_PVP) case IPPROTO_PVP: s = "PVP"; break; #endif /* defined(IPPROTO_PVP) */ #if defined(IPPROTO_BRSATMON) case IPPROTO_BRSATMON: s = "BRSATMN"; break; #endif /* defined(IPPROTO_BRSATMON) */ #if defined(IPPROTO_WBMON) case IPPROTO_WBMON: s = "WBMON"; break; #endif /* defined(IPPROTO_WBMON) */ #if defined(IPPROTO_WBEXPAK) case IPPROTO_WBEXPAK: s = "WBEXPAK"; break; #endif /* defined(IPPROTO_WBEXPAK) */ #if defined(IPPROTO_EON) case IPPROTO_EON: s = "EON"; break; #endif /* defined(IPPROTO_EON) */ #if defined(IPPROTO_VMTP) case IPPROTO_VMTP: s = "VMTP"; break; #endif /* defined(IPPROTO_VMTP) */ #if defined(IPPROTO_SVMTP) case IPPROTO_SVMTP: s = "SVMTP"; break; #endif /* defined(IPPROTO_SVMTP) */ #if defined(IPPROTO_VINES) case IPPROTO_VINES: s = "VINES"; break; #endif /* defined(IPPROTO_VINES) */ #if defined(IPPROTO_TTP) case IPPROTO_TTP: s = "TTP"; break; #endif /* defined(IPPROTO_TTP) */ #if defined(IPPROTO_IGP) case IPPROTO_IGP: s = "IGP"; break; #endif /* defined(IPPROTO_IGP) */ #if defined(IPPROTO_DGP) case IPPROTO_DGP: s = "DGP"; break; #endif /* defined(IPPROTO_DGP) */ #if defined(IPPROTO_TCF) case IPPROTO_TCF: s = "TCF"; break; #endif /* defined(IPPROTO_TCF) */ #if defined(IPPROTO_IGRP) case IPPROTO_IGRP: s = "IGRP"; break; #endif /* defined(IPPROTO_IGRP) */ #if defined(IPPROTO_OSPFIGP) case IPPROTO_OSPFIGP: s = "OSPFIGP"; break; #endif /* defined(IPPROTO_OSPFIGP) */ #if defined(IPPROTO_SRPC) case IPPROTO_SRPC: s = "SRPC"; break; #endif /* defined(IPPROTO_SRPC) */ #if defined(IPPROTO_LARP) case IPPROTO_LARP: s = "LARP"; break; #endif /* defined(IPPROTO_LARP) */ #if defined(IPPROTO_MTP) case IPPROTO_MTP: s = "MTP"; break; #endif /* defined(IPPROTO_MTP) */ #if defined(IPPROTO_AX25) case IPPROTO_AX25: s = "AX25"; break; #endif /* defined(IPPROTO_AX25) */ #if defined(IPPROTO_IPEIP) case IPPROTO_IPEIP: s = "IPEIP"; break; #endif /* defined(IPPROTO_IPEIP) */ #if defined(IPPROTO_MICP) case IPPROTO_MICP: s = "MICP"; break; #endif /* defined(IPPROTO_MICP) */ #if defined(IPPROTO_SCCSP) case IPPROTO_SCCSP: s = "SCCSP"; break; #endif /* defined(IPPROTO_SCCSP) */ #if defined(IPPROTO_ETHERIP) case IPPROTO_ETHERIP: s = "ETHERIP"; break; #endif /* defined(IPPROTO_ETHERIP) */ #if defined(IPPROTO_ENCAP) # if !defined(IPPROTO_IPIP) || IPPROTO_IPIP!=IPPROTO_ENCAP case IPPROTO_ENCAP: s = "ENCAP"; break; # endif /* !defined(IPPROTO_IPIP) || IPPROTO_IPIP!=IPPROTO_ENCAP */ #endif /* defined(IPPROTO_ENCAP) */ #if defined(IPPROTO_APES) case IPPROTO_APES: s = "APES"; break; #endif /* defined(IPPROTO_APES) */ #if defined(IPPROTO_GMTP) case IPPROTO_GMTP: s = "GMTP"; break; #endif /* defined(IPPROTO_GMTP) */ #if defined(IPPROTO_DIVERT) case IPPROTO_DIVERT: s = "DIVERT"; break; #endif /* defined(IPPROTO_DIVERT) */ default: s = (char *)NULL; } if (s) (void) snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL-1, s); else { if (m < 0) { for (i = 0, m = 1; i < IPROTOL-2; i++) m *= 10; } if (m > p) (void) snpf(Lf->iproto, sizeof(Lf->iproto), "%d?", p); else (void) snpf(Lf->iproto, sizeof(Lf->iproto), "*%d?", p % (m/10)); } } #endif /* !defined(HASPRIVPRIPP) */ /* * printname() - print output name field */ void printname(nl) int nl; /* NL status */ { #if defined(HASNCACHE) char buf[MAXPATHLEN]; char *cp; int fp; #endif /* defined(HASNCACHE) */ int ps = 0; if (Lf->nm && Lf->nm[0]) { /* * Print the name characters, if there are some. */ safestrprt(Lf->nm, stdout, 0); ps++; if (!Lf->li[0].af && !Lf->li[1].af) goto print_nma; } if (Lf->li[0].af || Lf->li[1].af) { if (ps) putchar(' '); /* * If the file has Internet addresses, print them. */ if (printinaddr()) ps++; goto print_nma; } if (((Lf->ntype == N_BLK) || (Lf->ntype == N_CHR)) && Lf->dev_def && Lf->rdev_def && printdevname(&Lf->dev, &Lf->rdev, 0, Lf->ntype)) { /* * If this is a block or character device and it has a name, print it. */ ps++; goto print_nma; } if (Lf->is_com) { /* * If this is a common node, print that fact. */ (void) fputs("COMMON: ", stdout); ps++; goto print_nma; } #if defined(HASPRIVNMCACHE) if (HASPRIVNMCACHE(Lf)) { ps++; goto print_nma; } #endif /* defined(HASPRIVNMCACHE) */ if (Lf->lmi_srch) { struct mounts *mp; /* * Do a deferred local mount info table search for the file system * (mounted) directory name and inode number, and mounted device name. */ for (mp = readmnt(); mp; mp = mp->next) { if (Lf->dev == mp->dev) { Lf->fsdir = mp->dir; Lf->fsdev = mp->fsname; #if defined(HASFSINO) Lf->fs_ino = mp->inode; #endif /* defined(HASFSINO) */ break; } } Lf->lmi_srch = 0; } if (Lf->fsdir || Lf->fsdev) { /* * Print the file system directory name, device name, and * possible path name components. */ #if !defined(HASNCACHE) || HASNCACHE<2 if (Lf->fsdir) { safestrprt(Lf->fsdir, stdout, 0); ps++; } #endif /* !defined(HASNCACHE) || HASNCACHE<2 */ #if defined(HASNCACHE) # if HASNCACHE<2 if (Lf->na) { if (NcacheReload) { # if defined(NCACHELDPFX) NCACHELDPFX # endif /* defined(NCACHELDPFX) */ (void) ncache_load(); # if defined(NCACHELDSFX) NCACHELDSFX # endif /* defined(NCACHELDSFX) */ NcacheReload = 0; } if ((cp = ncache_lookup(buf, sizeof(buf), &fp))) { char *cp1; if (*cp == '\0') goto print_nma; if (fp && Lf->fsdir) { if (*cp != '/') { cp1 = strrchr(Lf->fsdir, '/'); if (cp1 == (char *)NULL || *(cp1 + 1) != '\0') putchar('/'); } } else (void) fputs(" -- ", stdout); safestrprt(cp, stdout, 0); ps++; goto print_nma; } } # else /* HASNCACHE>1 */ if (NcacheReload) { # if defined(NCACHELDPFX) NCACHELDPFX # endif /* defined(NCACHELDPFX) */ (void) ncache_load(); # if defined(NCACHELDSFX) NCACHELDSFX # endif /* defined(NCACHELDSFX) */ NcacheReload = 0; } if ((cp = ncache_lookup(buf, sizeof(buf), &fp))) { if (fp) { safestrprt(cp, stdout, 0); ps++; } else { if (Lf->fsdir) { safestrprt(Lf->fsdir, stdout, 0); ps++; } if (*cp) { (void) fputs(" -- ", stdout); safestrprt(cp, stdout, 0); ps++; } } goto print_nma; } if (Lf->fsdir) { safestrprt(Lf->fsdir, stdout, 0); ps++; } # endif /* HASNCACHE<2 */ #endif /* defined(HASNCACHE) */ if (Lf->fsdev) { if (Lf->fsdir) (void) fputs(" (", stdout); else (void) putchar('('); safestrprt(Lf->fsdev, stdout, 0); (void) putchar(')'); ps++; } } /* * Print the NAME column addition, if there is one. If there isn't * make sure a NL is printed, as requested. */ print_nma: if (Lf->nma) { if (ps) putchar(' '); safestrprt(Lf->nma, stdout, 0); ps++; } /* * If this file has TCP/IP state information, print it. */ if (!Ffield && Ftcptpi && (Lf->lts.type >= 0 #if defined(HASTCPTPIQ) || ((Ftcptpi & TCPTPI_QUEUES) && (Lf->lts.rqs || Lf->lts.sqs)) #endif /* defined(HASTCPTPIQ) */ #if defined(HASTCPTPIW) || ((Ftcptpi & TCPTPI_WINDOWS) && (Lf->lts.rws || Lf->lts.wws)) #endif /* defined(HASTCPTPIW) */ )) { if (ps) putchar(' '); (void) print_tcptpi(0); } if (nl) putchar('\n'); } /* * printrawaddr() - print raw socket address */ void printrawaddr(sa) struct sockaddr *sa; /* socket address */ { char *ep; size_t sz; ep = endnm(&sz); (void) snpf(ep, sz, "%u/%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", sa->sa_family, (unsigned char)sa->sa_data[0], (unsigned char)sa->sa_data[1], (unsigned char)sa->sa_data[2], (unsigned char)sa->sa_data[3], (unsigned char)sa->sa_data[4], (unsigned char)sa->sa_data[5], (unsigned char)sa->sa_data[6], (unsigned char)sa->sa_data[7], (unsigned char)sa->sa_data[8], (unsigned char)sa->sa_data[9], (unsigned char)sa->sa_data[10], (unsigned char)sa->sa_data[11], (unsigned char)sa->sa_data[12], (unsigned char)sa->sa_data[13]); } /* * printsockty() - print socket type */ char * printsockty(ty) int ty; /* socket type -- e.g., from so_type */ { static char buf[64]; char *cp; switch (ty) { #if defined(SOCK_STREAM) case SOCK_STREAM: cp = "STREAM"; break; #endif /* defined(SOCK_STREAM) */ #if defined(SOCK_STREAM) case SOCK_DGRAM: cp = "DGRAM"; break; #endif /* defined(SOCK_DGRAM) */ #if defined(SOCK_RAW) case SOCK_RAW: cp = "RAW"; break; #endif /* defined(SOCK_RAW) */ #if defined(SOCK_RDM) case SOCK_RDM: cp = "RDM"; break; #endif /* defined(SOCK_RDM) */ #if defined(SOCK_SEQPACKET) case SOCK_SEQPACKET: cp = "SEQPACKET"; break; #endif /* defined(SOCK_SEQPACKET) */ default: (void) snpf(buf, sizeof(buf), "SOCK_%#x", ty); return(buf); } (void) snpf(buf, sizeof(buf), "SOCK_%s", cp); return(buf); } /* * printuid() - print User ID or login name */ char * printuid(uid, ty) UID_ARG uid; /* User IDentification number */ int *ty; /* returned UID type pointer (NULL * (if none wanted). If non-NULL * then: *ty = 0 = login name * = 1 = UID number */ { int i; struct passwd *pw; struct stat sb; static struct stat sbs; static struct uidcache { uid_t uid; char nm[LOGINML+1]; struct uidcache *next; } **uc = (struct uidcache **)NULL; struct uidcache *up, *upn; static char user[USERPRTL+1]; if (Futol) { if (CkPasswd) { /* * Get the mtime and ctime of /etc/passwd, as required. */ if (stat("/etc/passwd", &sb) != 0) { (void) fprintf(stderr, "%s: can't stat(/etc/passwd): %s\n", Pn, strerror(errno)); Exit(1); } } /* * Define the UID cache, if necessary. */ if (!uc) { if (!(uc = (struct uidcache **)calloc(UIDCACHEL, sizeof(struct uidcache *)))) { (void) fprintf(stderr, "%s: no space for %d byte UID cache hash buckets\n", Pn, (int)(UIDCACHEL * (sizeof(struct uidcache *)))); Exit(1); } if (CkPasswd) { sbs = sb; CkPasswd = 0; } } /* * If it's time to check /etc/passwd and if its the mtime/ctime has * changed, destroy the existing UID cache. */ if (CkPasswd) { if (sbs.st_mtime != sb.st_mtime || sbs.st_ctime != sb.st_ctime) { for (i = 0; i < UIDCACHEL; i++) { if ((up = uc[i])) { do { upn = up->next; (void) free((FREE_P *)up); } while ((up = upn) != (struct uidcache *)NULL); uc[i] = (struct uidcache *)NULL; } } sbs = sb; } CkPasswd = 0; } /* * Search the UID cache. */ i = (int)((((unsigned long)uid * 31415L) >> 7) & (UIDCACHEL - 1)); for (up = uc[i]; up; up = up->next) { if (up->uid == (uid_t)uid) { if (ty) *ty = 0; return(up->nm); } } /* * The UID is not in the cache. * * Look up the login name from the UID for a new cache entry. */ if (!(pw = getpwuid((uid_t)uid))) { if (!Fwarn) { (void) fprintf(stderr, "%s: no pwd entry for UID %lu\n", Pn, (unsigned long)uid); } } else { /* * Allocate and fill a new cache entry. Link it to its hash bucket. */ if (!(upn = (struct uidcache *)malloc(sizeof(struct uidcache)))) { (void) fprintf(stderr, "%s: no space for UID cache entry for: %lu, %s)\n", Pn, (unsigned long)uid, pw->pw_name); Exit(1); } (void) strncpy(upn->nm, pw->pw_name, LOGINML); upn->nm[LOGINML] = '\0'; upn->uid = (uid_t)uid; upn->next = uc[i]; uc[i] = upn; if (ty) *ty = 0; return(upn->nm); } } /* * Produce a numeric conversion of the UID. */ (void) snpf(user, sizeof(user), "%*lu", USERPRTL, (unsigned long)uid); if (ty) *ty = 1; return(user); } /* * printunkaf() - print unknown address family */ void printunkaf(fam, ty) int fam; /* unknown address family */ int ty; /* output type: 0 = terse; 1 = full */ { char *p, *s; p = ""; switch (fam) { #if defined(AF_UNSPEC) case AF_UNSPEC: s = "UNSPEC"; break; #endif /* defined(AF_UNSPEC) */ #if defined(AF_UNIX) case AF_UNIX: s = "UNIX"; break; #endif /* defined(AF_UNIX) */ #if defined(AF_INET) case AF_INET: s = "INET"; break; #endif /* defined(AF_INET) */ #if defined(AF_INET6) case AF_INET6: s = "INET6"; break; #endif /* defined(AF_INET6) */ #if defined(AF_IMPLINK) case AF_IMPLINK: s = "IMPLINK"; break; #endif /* defined(AF_IMPLINK) */ #if defined(AF_PUP) case AF_PUP: s = "PUP"; break; #endif /* defined(AF_PUP) */ #if defined(AF_CHAOS) case AF_CHAOS: s = "CHAOS"; break; #endif /* defined(AF_CHAOS) */ #if defined(AF_NS) case AF_NS: s = "NS"; break; #endif /* defined(AF_NS) */ #if defined(AF_ISO) case AF_ISO: s = "ISO"; break; #endif /* defined(AF_ISO) */ #if defined(AF_NBS) # if !defined(AF_ISO) || AF_NBS!=AF_ISO case AF_NBS: s = "NBS"; break; # endif /* !defined(AF_ISO) || AF_NBS!=AF_ISO */ #endif /* defined(AF_NBS) */ #if defined(AF_ECMA) case AF_ECMA: s = "ECMA"; break; #endif /* defined(AF_ECMA) */ #if defined(AF_DATAKIT) case AF_DATAKIT: s = "DATAKIT"; break; #endif /* defined(AF_DATAKIT) */ #if defined(AF_CCITT) case AF_CCITT: s = "CCITT"; break; #endif /* defined(AF_CCITT) */ #if defined(AF_SNA) case AF_SNA: s = "SNA"; break; #endif /* defined(AF_SNA) */ #if defined(AF_DECnet) case AF_DECnet: s = "DECnet"; break; #endif /* defined(AF_DECnet) */ #if defined(AF_DLI) case AF_DLI: s = "DLI"; break; #endif /* defined(AF_DLI) */ #if defined(AF_LAT) case AF_LAT: s = "LAT"; break; #endif /* defined(AF_LAT) */ #if defined(AF_HYLINK) case AF_HYLINK: s = "HYLINK"; break; #endif /* defined(AF_HYLINK) */ #if defined(AF_APPLETALK) case AF_APPLETALK: s = "APPLETALK"; break; #endif /* defined(AF_APPLETALK) */ #if defined(AF_BSC) case AF_BSC: s = "BSC"; break; #endif /* defined(AF_BSC) */ #if defined(AF_DSS) case AF_DSS: s = "DSS"; break; #endif /* defined(AF_DSS) */ #if defined(AF_ROUTE) case AF_ROUTE: s = "ROUTE"; break; #endif /* defined(AF_ROUTE) */ #if defined(AF_RAW) case AF_RAW: s = "RAW"; break; #endif /* defined(AF_RAW) */ #if defined(AF_LINK) case AF_LINK: s = "LINK"; break; #endif /* defined(AF_LINK) */ #if defined(pseudo_AF_XTP) case pseudo_AF_XTP: p = "pseudo_"; s = "XTP"; break; #endif /* defined(pseudo_AF_XTP) */ #if defined(AF_RMP) case AF_RMP: s = "RMP"; break; #endif /* defined(AF_RMP) */ #if defined(AF_COIP) case AF_COIP: s = "COIP"; break; #endif /* defined(AF_COIP) */ #if defined(AF_CNT) case AF_CNT: s = "CNT"; break; #endif /* defined(AF_CNT) */ #if defined(pseudo_AF_RTIP) case pseudo_AF_RTIP: p = "pseudo_"; s = "RTIP"; break; #endif /* defined(pseudo_AF_RTIP) */ #if defined(AF_NETMAN) case AF_NETMAN: s = "NETMAN"; break; #endif /* defined(AF_NETMAN) */ #if defined(AF_INTF) case AF_INTF: s = "INTF"; break; #endif /* defined(AF_INTF) */ #if defined(AF_NETWARE) case AF_NETWARE: s = "NETWARE"; break; #endif /* defined(AF_NETWARE) */ #if defined(AF_NDD) case AF_NDD: s = "NDD"; break; #endif /* defined(AF_NDD) */ #if defined(AF_NIT) # if !defined(AF_ROUTE) || AF_ROUTE!=AF_NIT case AF_NIT: s = "NIT"; break; # endif /* !defined(AF_ROUTE) || AF_ROUTE!=AF_NIT */ #endif /* defined(AF_NIT) */ #if defined(AF_802) # if !defined(AF_RAW) || AF_RAW!=AF_802 case AF_802: s = "802"; break; # endif /* !defined(AF_RAW) || AF_RAW!=AF_802 */ #endif /* defined(AF_802) */ #if defined(AF_X25) case AF_X25: s = "X25"; break; #endif /* defined(AF_X25) */ #if defined(AF_CTF) case AF_CTF: s = "CTF"; break; #endif /* defined(AF_CTF) */ #if defined(AF_WAN) case AF_WAN: s = "WAN"; break; #endif /* defined(AF_WAN) */ #if defined(AF_OSINET) # if defined(AF_INET) && AF_INET!=AF_OSINET case AF_OSINET: s = "OSINET"; break; # endif /* defined(AF_INET) && AF_INET!=AF_OSINET */ #endif /* defined(AF_OSINET) */ #if defined(AF_GOSIP) case AF_GOSIP: s = "GOSIP"; break; #endif /* defined(AF_GOSIP) */ #if defined(AF_SDL) case AF_SDL: s = "SDL"; break; #endif /* defined(AF_SDL) */ #if defined(AF_IPX) case AF_IPX: s = "IPX"; break; #endif /* defined(AF_IPX) */ #if defined(AF_SIP) case AF_SIP: s = "SIP"; break; #endif /* defined(AF_SIP) */ #if defined(psuedo_AF_PIP) case psuedo_AF_PIP: p = "pseudo_"; s = "PIP"; break; #endif /* defined(psuedo_AF_PIP) */ #if defined(AF_OTS) case AF_OTS: s = "OTS"; break; #endif /* defined(AF_OTS) */ #if defined(pseudo_AF_BLUE) case pseudo_AF_BLUE: /* packets for Blue box */ p = "pseudo_"; s = "BLUE"; break; #endif /* defined(pseudo_AF_BLUE) */ #if defined(AF_NDRV) /* network driver raw access */ case AF_NDRV: s = "NDRV"; break; #endif /* defined(AF_NDRV) */ #if defined(AF_SYSTEM) /* kernel event messages */ case AF_SYSTEM: s = "SYSTEM"; break; #endif /* defined(AF_SYSTEM) */ #if defined(AF_USER) case AF_USER: s = "USER"; break; #endif /* defined(AF_USER) */ #if defined(pseudo_AF_KEY) case pseudo_AF_KEY: p = "pseudo_"; s = "KEY"; break; #endif /* defined(pseudo_AF_KEY) */ #if defined(AF_KEY) /* Security Association DB socket */ case AF_KEY: s = "KEY"; break; #endif /* defined(AF_KEY) */ #if defined(AF_NCA) /* NCA socket */ case AF_NCA: s = "NCA"; break; #endif /* defined(AF_NCA) */ #if defined(AF_POLICY) /* Security Policy DB socket */ case AF_POLICY: s = "POLICY"; break; #endif /* defined(AF_POLICY) */ #if defined(AF_PPP) /* PPP socket */ case AF_PPP: s = "PPP"; break; #endif /* defined(AF_PPP) */ default: if (!ty) (void) snpf(Namech, Namechl, "%#x", fam); else (void) snpf(Namech, Namechl, "no further information on family %#x", fam); return; } if (!ty) (void) snpf(Namech, Namechl, "%sAF_%s", p, s); else (void) snpf(Namech, Namechl, "no further information on %sAF_%s", p, s); return; } #if !defined(HASNORPC_H) /* * update_portmap() - update a portmap entry with its port number or service * name */ static void update_portmap(pt, pn) struct porttab *pt; /* porttab entry */ char *pn; /* port name */ { MALLOC_S al, nl; char *cp; if (pt->ss) return; if (!(al = strlen(pn))) { pt->ss = 1; return; } nl = al + pt->nl + 2; if (!(cp = (char *)malloc(nl + 1))) { (void) fprintf(stderr, "%s: can't allocate %d bytes for portmap name: %s[%s]\n", Pn, (int)(nl + 1), pn, pt->name); Exit(1); } (void) snpf(cp, nl + 1, "%s[%s]", pn, pt->name); (void) free((FREE_P *)pt->name); pt->name = cp; pt->nl = nl; pt->ss = 1; } #endif /* !defined(HASNORPC_H) */