summaryrefslogtreecommitdiff
path: root/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'print.c')
-rw-r--r--print.c2829
1 files changed, 2829 insertions, 0 deletions
diff --git a/print.c b/print.c
new file mode 100644
index 0000000..6d227bc
--- /dev/null
+++ b/print.c
@@ -0,0 +1,2829 @@
+/*
+ * 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) */