home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / lsof / lsof.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-01  |  77.8 KB  |  3,931 lines

  1. /*
  2.  *    lsof.c - list open files
  3.  */
  4.  
  5.  
  6. /*
  7.  *    Lsof lists files opened by processes of:
  8.  *
  9.  *        AIX 3.1.[357]        (#define _IBMR2)
  10.  *        Purdue DYNIX 3.0.12    (#define DYNIX)
  11.  *        Sequent DYNIX 3.0.12    (#define DYNIX, #define SEQUENT)
  12.  *        Sequent DYNIX 3.1.2    (#define DYNIX31)
  13.  *        HP-UX 7.x        (#define hpux, #define HPUX7)
  14.  *        HP-UX 8.x        (#define hpux, #define HPUX8)
  15.  *        NeXTStep 2.[01]        (#define NeXT)
  16.  *        SunOS 4.1.1        (#define sun)
  17.  */
  18.  
  19. /*
  20.  * Copyright 1991 Purdue Research Foundation, West Lafayette, Indiana
  21.  * 47907.  All rights reserved.
  22.  *
  23.  * Written by Victor A. Abell
  24.  *
  25.  * This software is not subject to any license of the American Telephone
  26.  * and Telegraph Company or the Regents of the University of California.
  27.  *
  28.  * Permission is granted to anyone to use this software for any purpose on
  29.  * any computer system, and to alter it and redistribute it freely, subject
  30.  * to the following restrictions:
  31.  *
  32.  * 1. Neither the author nor Purdue University are responsible for any
  33.  *    consequences of the use of this software.
  34.  *
  35.  * 2. The origin of this software must not be misrepresented, either by
  36.  *    explicit claim or by omission.  Credit to the author and Purdue
  37.  *    University must appear in documentation and sources.
  38.  *
  39.  * 3. Altered versions must be plainly marked as such, and must not be
  40.  *    misrepresented as being the original software.
  41.  *
  42.  * 4. This notice may not be removed or altered.
  43.  */
  44.  
  45. #if    !defined(lint)
  46. static char copyright[] =
  47. "@(#) Copyright 1991 Purdue Research Foundation.\nAll rights reserved.\n";
  48. #endif
  49.  
  50. static char Version[] = "1.0";
  51.  
  52.  
  53. /*
  54.  *    Usage:
  55.  *
  56.  *        lsof [-d] [-h] [-l] [-n] [-N] [-p l] [-s] [-t] [-u l] [-U] [names]
  57.  *
  58.  *    where:
  59.  *
  60.  *        -d    Issue error messages about unreadable /dev
  61.  *            subdirectories.
  62.  *
  63.  *        -h    List help.
  64.  *
  65.  *        -l    Do not convert User ID numbers to login names.
  66.  *
  67.  *        -n    List Internet network files.
  68.  *
  69.  *        -N    List NFS files.
  70.  *
  71.  *        -p l    List files for Process IDentifier list l -- comma
  72.  *            separated list of numbers.
  73.  *
  74.  *        -s    Do not display file size.
  75.  *
  76.  *        -t    List terse output -- i. e., Process ID numbers without
  77.  *            a header.
  78.  *
  79.  *        -u l    List files for user list l -- comma separated list of
  80.  *            login names or User IDentification numbers.
  81.  *
  82.  *        -U    List Unix domain sockets.
  83.  *
  84.  *        names    are the path names of file systems, mount points,
  85.  *            devices and files to locate.
  86.  */
  87.  
  88. #if    defined(NeXT) && !defined(MACH)
  89. /*
  90.  * The definition of MACH for the NeXT is required for proper header
  91.  * file configuration -- i. e., some header files have ``#ifdef MACH''
  92.  * statements that affect the size of kernel structures.
  93.  */
  94.  
  95. #define MACH    1
  96. #endif
  97.  
  98. #include <sys/types.h>
  99. #include <sys/param.h>
  100.  
  101. #include <ctype.h>
  102. #include <errno.h>
  103. #include <pwd.h>
  104. #include <setjmp.h>
  105. #include <stdio.h>
  106.  
  107. #include <sys/domain.h>
  108. #include <sys/mbuf.h>
  109. #include <sys/protosw.h>
  110. #include <sys/socket.h>
  111. #include <sys/socketvar.h>
  112. #include <sys/stat.h>
  113. #include <sys/time.h>
  114. #include <sys/un.h>
  115. #include <sys/unpcb.h>
  116. #include <sys/vfs.h>
  117. #include <sys/vnode.h>
  118. #include <net/route.h>
  119. #include <netinet/in.h>
  120. #include <netinet/in_pcb.h>
  121.  
  122. #if    defined(DYNIX31)
  123. #undef    SEQUENT
  124. #undef    DYNIX
  125. #define    DYNIX
  126. #endif
  127.  
  128. #if    defined(DYNIX)
  129. #include <mntent.h>
  130. #include <strings.h>
  131. #include <nlist.h>
  132. #include <nfs/nfs.h>
  133. #include <nfs/nfs_clnt.h>
  134. #include <nfs/rnode.h>
  135. #include <sys/dir.h>
  136. #include <sys/file.h>
  137. #include <sys/proc.h>
  138. #define KERNEL
  139. #include <sys/file.h>
  140. #include <sys/inode.h>
  141. #include <ufs/mount.h>
  142. #undef KERNEL
  143. #include <sys/user.h>
  144.  
  145. #if    !defined(DYNIX31)
  146. /*
  147.  * This is from sys/user.h.  It's ifdef KERNEL, though, and defining
  148.  * KERNEL for user.h breaks other things.
  149.  *
  150.  * Open-file table extension object structure.
  151.  */
  152.  
  153. struct  ofile_ext {
  154.     struct  ofile_ext *oe_next;             /* list of unused entries */
  155.     short           oe_nofile;              /* # ofile entries */
  156.     short           oe_refcnt;              /* # proc's sharing this ext */
  157.     short           oe_ccount;              /* # sharing proc's in memory */
  158.     swblk_t         oe_swaddr;              /* disk address when swapped */
  159.     sema_t          oe_mutex;               /* misc mutex */
  160.     struct  ofile   *oe_ofile;              /* array of open files */
  161. };
  162. #endif
  163.  
  164. #endif
  165.  
  166. #if    defined(hpux)
  167. #include <stdlib.h>
  168. #include <dirent.h>
  169. #include <mntent.h>
  170. #include <string.h>
  171. #include <nlist.h>
  172. #include <rpc/types.h>
  173. #include <nfs/nfs.h>
  174. #include <nfs/nfs_clnt.h>
  175. #include <nfs/rnode.h>
  176. #include <nfs/snode.h>
  177. #include <sys/file.h>
  178. #include <sys/inode.h>
  179.  
  180. #if    defined(HPUX8)
  181. #include <sys/pstat.h>
  182. #endif
  183.  
  184. #include <sys/resource.h>
  185. #include <sys/proc.h>
  186. #include <sys/vmmac.h>
  187. #include <sys/user.h>
  188.  
  189. /*
  190.  * This is from <sys/mount.h>, defined under the _KERNEL symbol.
  191.  * Unfortunately, defining _KERNEL causes <sys/mount.h> to include
  192.  * other header files not in <sys>.
  193.  */
  194.  
  195. struct mount {
  196.     struct    mount *m_hforw;  /* forward hash pointer */
  197.     struct    mount *m_hback;  /* backward hash pointer */
  198.     struct    mount *m_rhforw; /* forward hash pointer for real device */
  199.     struct    mount *m_rhback; /* backward hash pointer for real device */
  200.     struct vfs    *m_vfsp; /* vfs structure for this filesystem */
  201.     dev_t    m_dev;         /* device mounted */
  202.    };
  203. #endif
  204.  
  205. #if    defined(_IBMR2)
  206. #include <stdlib.h>
  207. #include <string.h>
  208. #include <dirent.h>
  209. #if    !defined(_KERNEL)
  210. #define _KERNEL    1
  211. #endif
  212. #include <sys/file.h>
  213. #undef    _KERNEL
  214. #include <sys/mntctl.h>
  215. #include <sys/sysmacros.h>
  216. #include <sys/vattr.h>
  217. #include <sys/vmount.h>
  218. #include <procinfo.h>
  219. #include <nfs/rnode.h>
  220.  
  221. /*
  222.  * AIX 3.1.[357] doesn't supply the necessary cdrnode.h.
  223.  */
  224.  
  225. struct cdrnode {
  226.     caddr_t        f1[4];
  227.     struct gnode    f2;
  228.     dev_t        f3;
  229.     ino_t        cn_inumber;    /* inode number */
  230.     caddr_t        f4;
  231.     cnt_t        f5[2];
  232.     u_short        f6;
  233.     uint        f7[2];
  234.     uchar        f8[3];
  235.     off_t        cn_size;    /* size of file in bytes */
  236. };
  237. #endif
  238.  
  239. #if    defined(NeXT)
  240. #include <c.h>
  241. #include <stdlib.h>
  242. #include <string.h>
  243. #include <mntent.h>
  244. #include <nlist.h>
  245. #include <signal.h>
  246. #include <kern/queue.h>
  247. #include <sys/policy.h>
  248. #if    !defined(NCPUS)
  249. #define NCPUS    1
  250. #endif
  251. #include <kern/task.h>
  252. #include <netinet/in.h>
  253. #include <rpc/rpc.h>
  254. #include <rpc/xdr.h>
  255. #include <nfs/nfs.h>
  256. #include <nfs/nfs_clnt.h>
  257. #include <nfs/rnode.h>
  258. #include <sys/dir.h>
  259. #include <sys/domain.h>
  260. #if    !defined(KERNEL)
  261. #define KERNEL
  262. #endif
  263. #include <sys/file.h>
  264. #undef  KERNEL
  265. #include <ufs/mount.h>
  266. #include <sys/protosw.h>
  267. #include <sys/socket.h>
  268. #include <sys/socketvar.h>
  269. #include <sys/stat.h>
  270. #include <sys/ucred.h>
  271. #include <sys/un.h>
  272. #include <sys/unpcb.h>
  273. #if    !defined(SHOW_UTT)
  274. #define SHOW_UTT
  275. #endif
  276. #include <sys/user.h>
  277. #undef    SHOW_UTT
  278. #include <sys/proc.h>
  279. #include <sys/vfs.h>
  280. #include <ufs/inode.h>
  281.  
  282. /*
  283.  * The following substitution compensates for the snode.h that NeXT does
  284.  * not supply in NeXTStep 2.0 or 2.1.  The value of interest is s_realvp.
  285.  */
  286.  
  287. struct snode {
  288.     struct    snode *s_next;        /* must be first */
  289.     struct    vnode s_vnode;        /* vnode associated with this snode */
  290.     struct    vnode *s_realvp;    /* vnode for the fs entry (if any) */
  291. };
  292. #endif
  293.  
  294. #if    defined(sun)
  295. #include <stdlib.h>
  296. #include <string.h>
  297. #include <dirent.h>
  298. #include <kvm.h>
  299. #include <mntent.h>
  300. #include <nlist.h>
  301. #include <signal.h>
  302. #include <rpc/types.h>
  303. #include <nfs/nfs.h>
  304. #include <nfs/rnode.h>
  305. #include <specfs/snode.h>
  306. #include <sys/proc.h>
  307. #include <sys/sysmacros.h>
  308. #include <sys/user.h>
  309. #include <tmpfs/tmpnode.h>
  310. #include <ufs/inode.h>
  311. #include <ufs/mount.h>
  312. #if    !defined(KERNEL)
  313. #define KERNEL    1
  314. #endif
  315. #include <sys/file.h>
  316. #include <specfs/fifonode.h>
  317. #undef    KERNEL
  318. #endif
  319.  
  320. extern int errno;
  321.  
  322. extern struct passwd *getpwnam(), *getpwuid();
  323.  
  324. #if    defined(DYNIX) || defined(sun)
  325. extern int nlist();
  326. #endif
  327.  
  328. extern char *optarg;
  329. extern int optind;
  330. extern char *sys_errlist[];
  331.  
  332. #define DEVINCR        1024    /* device table malloc() increment */
  333. #define IPROTOL        5    /* Internet protocol length */
  334. #define LOGINML        8    /* login name length */
  335. #define PIDINCR        10    /* PID table malloc() increment */
  336. #define STATTMO        5    /* stat() timeout in seconds */
  337. #define UIDINCR        10    /* UID table malloc() increment */
  338. #define USERPRTL    8
  339. #define V_REG        0    /* vnode is regular */
  340. #define V_FIFO        1    /* vnode is a FIFO */
  341. #define V_NFS        2    /* vnode is an NFS file system */
  342. #define V_STREAM    3    /* vnode is a stream */
  343. #define V_TMP        4    /* vnode is a tmpfs */
  344.  
  345. #if    defined(DYNIX)
  346. #define MALLOC_P    char
  347. #define FREE_P        MALLOC_P
  348. #define MALLOC_S    unsigned
  349. #define N_UNIX        "/dynix"
  350. #define QSORT_P        char
  351. #define STRNCPY_L    int
  352. #define SWAP        "/dev/drum"
  353. #define U_SIZE        sizeof(struct user)
  354.  
  355. #if    defined(DYNIX31)
  356. #define strchr        index
  357. #define strrchr        rindex
  358. #endif
  359.  
  360. #if    defined(SEQUENT)
  361. #define strchr        index
  362. #define strrchr        rindex
  363. #define    uid_t        int
  364. #define    unp_addr    unp_remaddr
  365. #endif
  366.  
  367. #endif
  368.  
  369. #if    defined(hpux)
  370. #define MALLOC_P    char
  371. #define FREE_P        void
  372. #define MALLOC_S    unsigned
  373. #define MOUNTED        MNT_MNTTAB
  374. #define N_UNIX        "/hp-ux"
  375. #define PROCSIZE    sizeof(struct proc)
  376. #define QSORT_P        void
  377. #define STRNCPY_L    size_t
  378. #define SWAP        "/dev/swap"
  379.  
  380. #if    defined(HPUX7)
  381. #define unp_addr    unp_locaddr
  382. /*
  383.  * HP-UX 7.x SWAP must be read in DEV_BSIZE chunks.
  384.  */
  385. #define U_SIZE        (((DEV_BSIZE+sizeof(struct user))/DEV_BSIZE)*DEV_BSIZE)
  386. #endif
  387.  
  388. #if    defined(HPUX8)
  389. #define    U_SIZE        sizeof(struct user)
  390. #endif
  391.  
  392. #endif
  393.  
  394. #if    defined(_IBMR2)
  395. #define MALLOC_P    void
  396. #define FREE_P        MALLOC_P
  397. #define MALLOC_S    size_t
  398. #define PROCSIZE    sizeof(struct procinfo)
  399. #define QSORT_P        void
  400. #define STRNCPY_L    int
  401. #define U_SIZE        sizeof(struct user)
  402. #endif
  403.  
  404. #if    defined(NeXT)
  405. #define MALLOC_P    void
  406. #define FREE_P        MALLOC_P
  407. #define MALLOC_S    size_t
  408. #define PROCSIZE    sizeof(struct proc)
  409. #define QSORT_P        void
  410. #define STRNCPY_L    int
  411. #define U_SIZE        sizeof(struct user)
  412. #if    !defined(VMUNIX)
  413. #define VMUNIX        "/mach"
  414. #endif
  415. #endif
  416.  
  417. #if    defined(sun)
  418. #define CLONEMAJ    37    /* major device number for clone device */
  419. #define MALLOC_P    char
  420. #define FREE_P        MALLOC_P
  421. #define MALLOC_S    unsigned
  422. #define N_UNIX        "/vmunix"
  423. #define PROCSIZE    sizeof(struct proc)
  424. #define QSORT_P        char
  425. #define STRNCPY_L    int
  426. #define U_SIZE        sizeof(struct user)
  427. #endif
  428.  
  429.  
  430. /*
  431.  * Global storage definitions
  432.  */
  433.  
  434. #if    defined(sun)
  435. struct clone {
  436.     struct dev *dp;        /* pointer to device entry in Devtp[] */
  437.     struct clone *next;
  438.  
  439. } *Clone = NULL;
  440. #endif
  441.  
  442. char *Command;            /* command name */
  443. dev_t Dev;            /* device number */
  444. char Devch[32];            /* alternate characters for device printing */
  445.  
  446. struct dev {
  447.     dev_t rdev;        /* device */
  448.     char *name;        /* name */
  449.  
  450. } *Devtp = NULL;        /* device table pointer */
  451.  
  452. char Fd[8];            /* file descriptor for printing */
  453. int Fdev = 0;            /* have device number flag */
  454. int Fdevmsg = 0;        /* -d flag status */
  455. int Fhelp = 0;            /* -h flag status */
  456. int Fnet = 0;            /* -n flag status */
  457. int Fnfs = 0;            /* -N flag status */
  458. int Fprint = 0;            /* print line flag */
  459. int Fsize = 1;            /* -s flag status */
  460. int Fterse = 0;            /* -t flag status */
  461. int Funix = 0;            /* -U flag status */
  462. int Futol = 1;            /* -l flag status */
  463. int Hdr = 0;            /* header print status */
  464. long Inode = -1l;        /* inode number
  465.                  *    -1: none (don't print anything)
  466.                  *    -2: blank (print spaces) */
  467. char Iproto[IPROTOL+1];        /* Internet protocol name */
  468.  
  469. #if    defined(sun)
  470. kvm_t *Kd;            /* kvm descriptor */
  471. #endif
  472.  
  473. int Kmem = -1;            /* /dev/kmem file descriptor */
  474.  
  475. struct l_vfs {
  476.  
  477.     struct vfs *addr;    /* kernel address */
  478.  
  479. #if    defined(DYNIX) || defined(hpux) || defined(_IBMR2)
  480.     dev_t dev;        /* device */
  481. #endif
  482.     char *dir;        /* mounted directory */
  483.     char *fsname;        /* file system name */
  484.  
  485. #if    defined(_IBMR2)
  486.     int vmt_flags;        /* vmount flags */
  487.     int vmt_gfstype;    /* vmount gfs type */
  488. #endif
  489.  
  490.     struct l_vfs *next;    /* next entry pointer */
  491. } *Lvfs = NULL;            /* local vfs structure table */
  492.  
  493. #if    defined(HPUX7)
  494. int Mem = -1;            /* /dev/mem file descriptor */
  495. #endif
  496.  
  497. char Lock = ' ';        /* lock status */
  498.  
  499. struct mounts {
  500.         dev_t dev;              /* st_dev */
  501.         char *dir;              /* directory */
  502.         char *fsname;           /* file system */
  503.     ino_t inode;        /* st_ino */
  504.  
  505. #if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT)
  506.     u_short mode;        /* st_mode */
  507. #endif
  508.  
  509. #if    defined(hpux) || defined(sun)
  510.     mode_t mode;        /* st_mode */
  511. #endif
  512.  
  513.         struct mounts *next;    /* forward link */
  514.     dev_t rdev;        /* st_rdev */
  515.  
  516. } *Mtab = NULL;                 /* mounted devices */
  517.  
  518. int Mxpid = 0;            /* maximum PID table entries */
  519. int Mxuid = 0;            /* maximum UID table entries */
  520. char Namech[1024];        /* name characters for printing */
  521. int Ndev = 0;            /* number of device table entries */
  522.  
  523. #if    defined(DYNIX)
  524. struct nlist Nl[] = {
  525.         { "_proc" },
  526. #define X_PROC          0
  527.         {"_nproc"},
  528. #define X_NPROC         1
  529.         {"_nfs_vnodeops"},
  530. #define X_NFS_OPS    2
  531.     { "" },
  532. };
  533. #endif
  534.  
  535. #if    defined(hpux)
  536. struct nlist Nl[] = {
  537.  
  538. #if    defined(hp9000s300)
  539.         {"_proc"},
  540. #define X_PROC          0
  541.         {"_nproc"},
  542. #define X_NPROC         1
  543.         {"_nfs_vnodeops"},
  544. #define X_NFS_OPS    2
  545.  
  546. #if    defined(HPUX7)
  547.     {"_Usrptmap"},
  548. #define X_USRPTMAP    3
  549.     {"_usrpt"},
  550. #define X_USRPT        4
  551. #endif
  552.  
  553. #endif
  554.  
  555. #if    defined(hp9000s800)
  556.     {"proc"},
  557. #define X_PROC          0
  558.     {"nproc"},
  559. #define X_NPROC         1
  560.         {"nfs_vnodeops"},
  561. #define X_NFS_OPS    2
  562.  
  563. #if    defined(HPUX7)
  564.     {"ubase"},
  565. #define X_UBASE        3
  566.     {"npids"},
  567. #define X_NPIDS        4
  568. #endif
  569.  
  570. #endif
  571.  
  572.     { "" }
  573. };
  574. #endif
  575.  
  576. #if    defined(NeXT)
  577.  
  578. static struct nlist Nl[] = {
  579.         { {"_allproc"},      0, 0, 0 },
  580. #define X_ALLPROC                               0
  581.         { {"_nfs_vnodeops"}, 0, 0, 0},
  582. #define X_NFS_OPS                               1
  583.         {  {""},             0, 0, 0  },
  584. };
  585. #endif
  586.  
  587. #if    defined(sun)
  588. struct nlist Nl[] = {
  589.         {"_nfs_vnodeops"},
  590. #define X_NFS_OPS    0
  591.     { "_tmp_vnodeops"},
  592. #define X_TMP_OPS    1
  593.     { "" }
  594. };
  595. #endif
  596.  
  597. int Npid = 0;            /* -p flag count */
  598. int Nuid = 0;            /* -u flag count */
  599.  
  600. #if    defined(HPUX7) && defined(hp9000s800)
  601. int npids;            /* number of PIDs (for uvadd()) */
  602. struct proc *proc;        /* process table address (for uvadd()) */
  603. #endif
  604.  
  605. #if    defined(hpux)
  606. long Procaddr;            /* kernel process table entry address */
  607. #endif
  608.  
  609. struct dev **Sdev = NULL;    /* pointer to device table pointers, sorted
  610.                  * by device */
  611.  
  612. struct sfile {
  613.     char *name;        /* file name */
  614.     char *devnm;        /* device name (optional) */
  615.     dev_t dev;        /* device */
  616.  
  617. #if    defined(_IBMR2)
  618.     chan_t ch;        /* channel (last path component, if numeric) */
  619. #endif
  620.  
  621.     u_short mode;        /* S_IFMT mode bits from stat() */
  622.     int type;        /* file type: 0 = file system
  623.                  *          1 = regular file */
  624.     ino_t i;        /* inode number */
  625.     int f;            /* file found flag */
  626.     struct sfile *next;    /* link to next entry */
  627.  
  628. } *Sfile = NULL;        /* chain of files to search for */
  629.  
  630. off_t Size;            /* file size */
  631. int Size_def;            /* file size is defined */
  632. int *Spid = NULL;        /* Process IDs to search for */
  633. int *Suid = NULL;        /* User IDs to search for */
  634.  
  635. #if    defined(DYNIX) || defined(hpux)
  636. int Swap = -1;            /* swap device file descriptor */
  637. #endif
  638.  
  639. int Pid;            /* Process ID */
  640. char *Pn;            /* program name */
  641.  
  642. jmp_buf Tmo_jbuf;        /* jump buffer for mount stat timeout */
  643.  
  644. char Type[8];            /* type for printing */
  645. char User[USERPRTL+1];        /* User ID */
  646.  
  647. #if    defined(HPUX7) && defined(hp9000s300)
  648. struct pte *Usrptmap;        /* user page table map pointer */
  649. struct pte *usrpt;        /* user page table pointer
  650.                  * (for bktomx from vmmac.h) */
  651. #endif
  652.  
  653. #if    defined(HPUX7) && defined(hp9000s800)
  654. struct user *ubase;        /* user area base (for uvadd()) */
  655. #endif
  656.  
  657. int Vtype;            /* vnode type (see V_* symbols) */
  658.  
  659.  
  660. int compdev(), getchan(), isfile(), kread(), readinode(),
  661.     readlink(), readrnode(), readvnode(), statsafely();
  662.  
  663. char *endnm(), isglocked();
  664.  
  665. struct l_vfs *readvfs();
  666.  
  667. void printchdevname(), printfile(), printinaddr(), printiproto(),
  668.      printline(), printsocket(), printuid(), printvnode(), readdev(),
  669.      readmnt(), stkdir();
  670.  
  671. #if    defined(DYNIX)
  672. char *malloc(), *realloc();
  673. int stattimeout();
  674. void completevfs();
  675. u_short ntohs();
  676. #endif
  677.  
  678. #if    defined(hpux)
  679. int readsnode();
  680. off_t lseek();
  681. void completevfs(), stattimeout();
  682. #endif
  683.  
  684. #if    defined(_IBMR2)
  685. int readcdrnode(), readgnode();
  686. void stattimeout();
  687. #endif
  688.  
  689. #if    defined(NeXT)
  690. int readsnode();
  691. void completevfs(), stattimeout();
  692. #endif
  693.  
  694. #if    defined(sun)
  695. int readfifonode(), readsnode(), readtnode();
  696. void completevfs(), stattimeout();
  697. #endif
  698.  
  699. /*
  700.  * Process structure redefinitions
  701.  */
  702.  
  703. #if    defined(_IBMR2)
  704. #define p_pid    pi_pid
  705. #define p_stat    pi_stat
  706. #define p_uid    pi_uid
  707. #endif
  708.  
  709. /*
  710.  * User structure redefinitions
  711.  */
  712.  
  713. #if    defined(NeXT)
  714. #define u_comm    uu_comm
  715. #define u_cdir    uu_cdir
  716. #endif
  717.  
  718.  
  719. /*
  720.  * main() - main program
  721.  */
  722.  
  723. main(argc, argv)
  724.     int argc;
  725.     char *argv[];
  726. {
  727.     int c;
  728.     int err = 0;
  729.     char *fnm;
  730.     int fprint;
  731.     char *fsnm;
  732.     int ftype;
  733.     int i;
  734.     int llen, llenx;
  735.     struct mounts *mp;
  736.     char *path;
  737.     char *s;
  738.     struct stat sb;
  739.     int selflg, selpid, seluid;
  740.     struct sfile *sfp;
  741.     char syml[MAXPATHLEN];
  742.     char *symlp;
  743.     char symlx[MAXPATHLEN];
  744.  
  745. #if    defined(DYNIX)
  746.     long kp;
  747.     int nf, np;
  748.     static struct ofile *ofp = NULL;
  749.     struct proc *p;
  750.     struct proc ps;
  751.     int px;
  752.     struct user *u;
  753.     struct ofile *uf;
  754.     unsigned ui;
  755.     struct user us;
  756.     static int xnf = 0;
  757.  
  758. #if    !defined(DYNIX31)
  759.     struct ofile_ext ofx;
  760. #endif
  761.  
  762. #if    defined(DYNIX31)
  763.     struct ofile_tab oft;
  764. #endif
  765.  
  766. #endif
  767.  
  768. #if    defined(hpux)
  769.  
  770. #if    defined(HPUX7)
  771.     int k;
  772.     char us[U_SIZE];    /* must read HP-UX SWAP in DEV_BSIZE chunks */
  773. #endif
  774.  
  775. #if    defined(HPUX8)
  776.     struct ofile_t *ofp;
  777.     struct ofile_t oft;
  778.     struct user us;
  779. #endif
  780.  
  781.     int j;
  782.     long kp;
  783.     int np;
  784.     struct proc *p;
  785.     struct proc ps;
  786.     int px;
  787.     struct user *u;
  788. #endif
  789.  
  790. #if    defined(_IBMR2)
  791.     int np;
  792.     struct procinfo *p;
  793.     struct user *u;
  794.     struct user us;
  795. #endif
  796.  
  797. #if    defined(NeXT)
  798.     MALLOC_S nb;
  799.     int nf;
  800.     struct proc *np, *p, *procp, ps;
  801.     static MALLOC_S pnb = 0;
  802.         struct task t;
  803.         struct file **uf = NULL;
  804.         struct utask *u, ut;
  805. #endif
  806.  
  807. #if    defined(sun)
  808.     int nf;
  809.     struct proc *p;
  810.     struct user *u;
  811.     struct file **uf;
  812.     unsigned ui;
  813.     static int xnf = 0;
  814.     static struct file **xuf = NULL;
  815. #endif
  816.  
  817. /*
  818.  * Save program name for messages.
  819.  */
  820.     if ((Pn = strrchr(argv[0], '/')) != NULL)
  821.         Pn++;
  822.     else
  823.         Pn = argv[0];
  824. /*
  825.  * Process arguments.
  826.  */
  827.     while ((c = getopt(argc, argv, "dhlnNp:stu:U")) != EOF) {
  828.         switch(c) {
  829.  
  830.         case 'd':
  831.             Fdevmsg = 1;
  832.             break;
  833.         case 'h':
  834.             Fhelp = 1;
  835.             break;
  836.         case 'l':
  837.             Futol = 0;
  838.             break;
  839.         case 'n':
  840.             Fnet = 1;
  841.             break;
  842.         case 'N':
  843.             Fnfs = 1;
  844.             break;
  845.         case 'p':
  846.             if (entpid(optarg))
  847.                 err++;
  848.             break;
  849.         case 's':
  850.             Fsize = 0;
  851.             break;
  852.         case 't':
  853.             Fterse = 1;
  854.             break;
  855.         case 'u':
  856.             if (entuid(optarg))
  857.                 err++;
  858.             break;
  859.         case 'U':
  860.             Funix = 1;
  861.             break;
  862.         case '?':
  863.             err++;
  864.             break;
  865.         default:
  866.             (void) fprintf(stderr, "%s: unknown option (%c)\n",
  867.                 Pn, c);
  868.             err++;
  869.         }
  870.     }
  871. /*
  872.  * Read the mount table and process any file names.
  873.  */
  874.     (void) readmnt();
  875.     for (i = optind; i < argc; i++) {
  876.  
  877.     /*
  878.      * Dereference a symbolic link.
  879.      */
  880.         if ((llen = readlink(argv[i], syml, sizeof(syml) - 1)) >= 0) {
  881.             syml[llen] = '\0';
  882.             if (argv[i][0] == '/' && syml[0] != '/') {
  883.                 llenx = (strrchr(argv[i], '/') - argv[i]) + 1;
  884.                 if ((llenx + llen + 1) > sizeof(symlx)) {
  885.                     (void) fprintf(stderr,
  886.                         "%s: sym link for %s too long\n",
  887.                         Pn, argv[i]);
  888.                     exit(1);
  889.                 }
  890.                 (void) strncpy(symlx, argv[i],
  891.                     (STRNCPY_L)llenx);
  892.                 (void) strcpy(&symlx[llenx], syml);
  893.                 symlp = symlx;
  894.                 llen += llenx;
  895.             } else
  896.                 symlp = syml;
  897.             if ((path = (char *)malloc((MALLOC_S)(llen + 1)))
  898.             == NULL) {
  899.                 (void) fprintf(stderr,
  900.                     "%s: no space for sym link of %s\n",
  901.                     Pn, argv[i]);
  902.                 exit(1);
  903.             }
  904.             (void) strcpy(path, symlp);
  905.         } else
  906.             path = argv[i];
  907.     /*
  908.      * Check for file system argument.
  909.      */
  910.         for (ftype = 1, mp = Mtab; mp; mp = mp->next) {
  911.             if (strcmp(mp->dir, path) == 0) {
  912.                 ftype = 0;
  913.                 fnm = path;
  914.                 fsnm = mp->fsname;
  915.                 break;
  916.             }
  917.             if (strcmp(mp->fsname, path) == 0) {
  918.                 ftype = 0;
  919.                 fnm = mp->dir;
  920.                 fsnm = path;
  921.                 break;
  922.             }
  923.         }
  924.         if (ftype) {
  925.             fnm = path;
  926.             fsnm = NULL;
  927.         } else {
  928.             sb.st_dev = mp->dev;
  929.             sb.st_ino = mp->inode;
  930.             sb.st_mode = mp->mode;
  931.             sb.st_rdev = mp->rdev;
  932.         }
  933.     /*
  934.      * Stat the argument to obtain its mode and device.
  935.      */
  936.  
  937.         if (ftype && statsafely(fnm, &sb, STATTMO) != 0) {
  938.             (void) fprintf(stderr, "%s: status error on %s: %s\n",
  939.                 Pn, fnm, sys_errlist[errno]);
  940.             err++;
  941.             continue;
  942.         }
  943.     /*
  944.      * Allocate an sfile structure and fill in the type, inode,
  945.      * find-flag and linkages.
  946.      */
  947.         if ((sfp = (struct sfile *)malloc(sizeof(struct sfile)))
  948.         == NULL) {
  949.             (void) fprintf(stderr, "%s: no space for files\n", Pn);
  950.             exit(1);
  951.         }
  952.         sfp->next = Sfile;
  953.         Sfile = sfp;
  954.         sfp->type = ftype;
  955.         sfp->i = sb.st_ino;
  956.         sfp->f = 0;
  957.     /*
  958.      * Store the file name and file system name pointers in the sfile
  959.      * structure, allocating space as necessary.
  960.      */
  961.         if (fnm == NULL || fnm == path)
  962.             sfp->name = fnm;
  963.         else {
  964.             if ((sfp->name = (char *)malloc((MALLOC_S)(strlen(fnm)+1)))
  965.             == NULL) {
  966.             (void) fprintf(stderr,
  967.                 "%s: no space for file name %s\n", Pn, fnm);
  968.             exit(1);
  969.             }
  970.             (void) strcpy(sfp->name, fnm);
  971.         }
  972.         if (fsnm == NULL || fsnm == path)
  973.             sfp->devnm = fsnm;
  974.         else {
  975.             if ((sfp->devnm=(char *)malloc((MALLOC_S)(strlen(fsnm)+1)))
  976.             == NULL) {
  977.             (void) fprintf(stderr,
  978.                 "%s: no space for file system name %s\n", Pn, fsnm);
  979.             exit(1);
  980.             }
  981.             (void) strcpy(sfp->devnm, fsnm);
  982.         }
  983.     /*
  984.      * Save the stat() buffer mode value in the sfile structure.
  985.      * Use st_rdev if the mode value is S_IFBLK or S_IFCHR; otherwise
  986.      * use st_dev.
  987.      */
  988.         sfp->mode = sb.st_mode & S_IFMT;
  989.         if (sfp->mode == S_IFBLK ||  sfp->mode == S_IFCHR)
  990.             sfp->dev = sb.st_rdev;
  991.         else
  992.             sfp->dev = sb.st_dev;
  993.  
  994. #if    defined(_IBMR2)
  995.     /*
  996.      * Save a (possible) AIX multiplexed channel number.
  997.      */
  998.         sfp->ch = getchan(path);
  999. #endif
  1000.  
  1001.     }
  1002. /*
  1003.  * List usage if error or if requested.
  1004.  */
  1005.     if (err || Fhelp) {
  1006.         (void) fprintf(stderr,
  1007.         "%s %s usage: [-d] [-h] [-l] [-n] [-N] [-p l] [-s] [-t]",
  1008.         Pn, Version);
  1009.         (void) fprintf(stderr,
  1010.         " [-u l] [-U] [names]\n");
  1011.         (void) fprintf(stderr,
  1012.         "\t-d     issue /dev subdirectory error messages\n");
  1013.         (void) fprintf(stderr,
  1014.         "\t-h     list help\n");
  1015.         (void) fprintf(stderr,
  1016.         "\t-l     do not convert UID's to login names\n");
  1017.         (void) fprintf(stderr,
  1018.         "\t-n     list Internet network files\n");
  1019.         (void) fprintf(stderr,
  1020.         "\t-N     list NFS files\n");
  1021.         (void) fprintf(stderr,
  1022.         "\t-p l   list files for comma-separated Process ID list l\n");
  1023.         (void) fprintf(stderr,
  1024.          "\t-s     do not display file size\n");
  1025.         (void) fprintf(stderr,
  1026.         "\t-t     terse output -- Process ID numbers and no header\n");
  1027.         (void) fprintf(stderr,
  1028.         "\t-u l   list files for comma-separated user list l ");
  1029.         (void) fprintf(stderr,
  1030.         "(names or UIDs)\n");
  1031.         (void) fprintf(stderr,
  1032.         "\t-U     list Unix domain sockets\n");
  1033.         (void) fprintf(stderr,
  1034.         "\tnames  path names of file systems, mount points, devices");
  1035.         (void) fprintf(stderr,
  1036.         " and\n\t       files to locate\n");
  1037.         if (err)
  1038.         exit(1);
  1039.         exit(0);
  1040.     }
  1041. /*
  1042.  * Open kernel memory accesses.
  1043.  *
  1044.  * Read and build device and mount tables.
  1045.  */
  1046.     if ((Kmem = open("/dev/kmem", O_RDONLY, 0)) < 0) {
  1047.         (void) fprintf(stderr, "%s: can't open /dev/kmem: %s\n",
  1048.             Pn, sys_errlist[errno]);
  1049.         exit(1);
  1050.     }
  1051.  
  1052. #if    defined(HPUX7)
  1053.     if ((Mem = open("/dev/mem", O_RDONLY, 0)) < 0) {
  1054.         (void) fprintf(stderr, "%s: can't open /dev/mem: %s",
  1055.             Pn, sys_errlist[errno]);
  1056.         exit(1);
  1057.     }
  1058. #endif
  1059.  
  1060. #if    defined(DYNIX) || defined(HPUX7)
  1061.     if ((Swap = open(SWAP, O_RDONLY, 0)) < 0) {
  1062.         (void) fprintf(stderr, "%s: /dev/drum: %s\n",
  1063.             Pn, sys_errlist[errno]);
  1064.         exit(1);
  1065.     }
  1066. #endif
  1067.  
  1068. #if    defined(NeXT)
  1069.         if (nlist(VMUNIX, Nl) < 0) {
  1070.                 (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
  1071.                 exit(1);
  1072.         }
  1073.         if (Nl[X_ALLPROC].n_value == 0l) {
  1074.                 (void) fprintf(stderr, "%s: no address for %s\n",
  1075.                         Pn, Nl[X_ALLPROC].n_un.n_name);
  1076.                 exit(1);
  1077.         }
  1078.         if (kread((off_t)Nl[X_ALLPROC].n_value, (char *)&procp, sizeof(procp))){
  1079.                 (void) fprintf(stderr,
  1080.                         "%s: can't read nl[X_ALLPROC].n_un.n_name: %s\n",
  1081.                         Pn, sys_errlist[errno]);
  1082.                 exit(1);
  1083.         }
  1084. #endif
  1085.  
  1086. #if    defined(sun)
  1087.     if ((Kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == 0) {
  1088.         (void) sprintf("%s: kvm_open: %s", Pn, sys_errlist[errno]);
  1089.         exit(1);
  1090.     }
  1091.         if (nlist(N_UNIX, Nl) < 0) {
  1092.                 (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
  1093.                 exit(1);
  1094.     }
  1095.         if (Nl[X_NFS_OPS].n_value == 0l) {
  1096.                 (void) fprintf(stderr, "%s: no address for %s\n",
  1097.                         Pn, Nl[X_NFS_OPS].n_name);
  1098.                 exit(1);
  1099.         }
  1100. #endif
  1101.  
  1102.     (void) readdev();
  1103. /*
  1104.  * Read the processs table.
  1105.  */
  1106.  
  1107. #if    defined(DYNIX) || defined(hpux)
  1108.     if (nlist(N_UNIX, Nl) < 0) {
  1109.                 (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
  1110.                 exit(1);
  1111.     }
  1112.     if (Nl[X_PROC].n_value == NULL
  1113.     ||  kread((off_t)Nl[X_PROC].n_value, (char *)&kp, sizeof(kp))
  1114.     ||  Nl[X_NPROC].n_value == NULL
  1115.     ||  kread((off_t)Nl[X_NPROC].n_value, (char *)&np, sizeof(np))
  1116.     ||  kp == NULL || np == 0) {
  1117.         (void) fprintf(stderr, "%s: can't read proc table info\n",
  1118.             Pn);
  1119.         exit(1);
  1120.     }
  1121. #endif
  1122.  
  1123. #if    defined(HPUX7) && defined(hp9000s300)
  1124.     if ((Usrptmap = (struct pte *)Nl[X_USRPTMAP].n_value) == NULL) {
  1125.         (void) fprintf(stderr, "%s: can't get kernel's Usrptmap\n", Pn);
  1126.         exit(1);
  1127.     }
  1128.     if ((usrpt = (struct pte *)Nl[X_USRPT].n_value) == NULL) {
  1129.         (void) fprintf(stderr, "%s: can't get kernel's usrpt\n", Pn);
  1130.         exit(1);
  1131.     }
  1132. #endif
  1133.  
  1134. #if    defined(HPUX7) && defined(hp9000s800)
  1135.     proc = (struct proc *)kp;
  1136.     if ((ubase = (struct user *)Nl[X_UBASE].n_value) == NULL) {
  1137.         (void) fprintf(stderr, "%s: can't get kernel's ubase\n", Pn);
  1138.         exit(1);
  1139.     }
  1140.     if (Nl[X_NPIDS].n_value == NULL
  1141.     ||  kread((off_t)Nl[X_NPIDS].n_value, (char *)&npids, sizeof(npids))) {
  1142.         (void) fprintf(stderr, "%s: can't get kernel's npids\n", Pn);
  1143.         exit(1);
  1144.     }
  1145. #endif
  1146.  
  1147. #if    defined(_IBMR2)
  1148.     if ((p = (struct procinfo *)malloc((size_t)PROCSIZE)) == NULL) {
  1149.         (void) fprintf(stderr,
  1150.             "%s: can't allocate space for 1 procinfo\n", Pn);
  1151.         exit(1);
  1152.     }
  1153.     np = 0;
  1154.     while (((np = getproc(p, np, PROCSIZE)) == -1) && errno == ENOSPC) {
  1155.         np = p->p_pid + 10;
  1156.         if ((p = (struct procinfo *)realloc((MALLOC_P *)p,
  1157.             (size_t) (np * PROCSIZE))) == NULL) {
  1158.             (void) fprintf(stderr,
  1159.                 "%s: no space for %ld procinfo's\n", Pn, np);
  1160.             exit(1);
  1161.         }
  1162.     }
  1163. #endif
  1164.  
  1165. #if    defined(sun)
  1166.     (void) kvm_setproc(Kd);
  1167. #endif
  1168.  
  1169. /*
  1170.  * Loop through the process table entries.
  1171.  */
  1172.     selflg = (Fnet || Fnfs || Funix || Npid || Nuid || Sfile) ? 0 : 1;
  1173.     selpid = (Fnet || Fnfs || Funix || Nuid || Sfile) ? 0 : 1;
  1174.     seluid = (Fnet || Fnfs || Funix || Sfile) ? 0 : 1;
  1175.  
  1176. #if    defined(DYNIX)
  1177.     for (p = &ps, px = 0, u = &us; px < np; px++)
  1178. #endif
  1179.  
  1180. #if    defined(HPUX7)
  1181.     for (p = &ps, px = 0, u = (struct user *)us; px < np; px++)
  1182. #endif
  1183.  
  1184. #if    defined(HPUX8)
  1185.     for (p = &ps, px = 0, u = &us; px < np; px++)
  1186. #endif
  1187.  
  1188. #if    defined(_IBMR2)
  1189.     for (; np; np--, p++)
  1190. #endif
  1191.  
  1192. #if    defined(NeXT)
  1193.     for (np = procp, p = &ps; np; np = ps.p_nxt)
  1194. #endif
  1195.  
  1196. #if    defined(sun)
  1197.     while ((p = kvm_nextproc(Kd)) != NULL)
  1198. #endif
  1199.  
  1200.     {
  1201.  
  1202. #if    defined(DYNIX)
  1203.         if (kread((off_t)(kp + (long)(px * sizeof(struct proc))),
  1204.             (char *)&ps, sizeof(ps)))
  1205.             continue;
  1206. #endif
  1207.  
  1208. #if    defined(hpux)
  1209.         Procaddr = kp + (long)(px * sizeof(struct proc));
  1210.         if (kread((off_t)Procaddr, (char *)&ps, sizeof(ps)))
  1211.             continue;
  1212. #endif
  1213.  
  1214. #if    defined(NeXT)
  1215.                 if (kread((off_t)np, (char *)&ps, sizeof(ps))) {
  1216.                         (void) fprintf(stderr,
  1217.                                 "%s: can't read proc struct at %#x\n",
  1218.                                 Pn, np);
  1219.                         exit(1);
  1220.                 }
  1221. #endif
  1222.  
  1223.         if (p->p_stat == 0 || p->p_stat == SZOMB)
  1224.             continue;
  1225.         fprint = selflg;
  1226.         for (i = 0; fprint == 0 && i < Npid; i++) {
  1227.             if (Spid[i] == p->p_pid)
  1228.                 fprint = 1;
  1229.         }
  1230.         if ( ! fprint && selpid)
  1231.             continue;
  1232.  
  1233. #if    defined(NeXT)
  1234.         /*
  1235.          * Read the task associated with the process, and the user
  1236.          * area assocated with the task.
  1237.          */
  1238.                 if (kread((off_t) p->task, &t, sizeof(t)))
  1239.                         continue;
  1240.                 if ((struct proc *)t.proc != np)
  1241.                         continue;
  1242.                 if (kread((off_t) t.u_address, &ut, sizeof(ut)))
  1243.                         continue;
  1244.                 if ((struct proc *)ut.uu_procp != np)
  1245.                         continue;
  1246.         u = &ut;
  1247. #endif
  1248.  
  1249. /*
  1250.  * Check for processes owned by specified user(s).
  1251.  */
  1252.         for (i = 0; fprint == 0 && i < Nuid; i++) {
  1253.             if (Suid[i] == p->p_uid)
  1254.                 fprint = 1;
  1255.         }
  1256.         if ( ! fprint && seluid)
  1257.             continue;
  1258.  
  1259. #if    defined(DYNIX) || defined(hpux) || defined(_IBMR2) || defined(sun)
  1260.     /*
  1261.      * Get the user area associated with the process.
  1262.      */
  1263. #endif
  1264.  
  1265. #if    defined(DYNIX)
  1266.         if (getu(p, &us))
  1267.             continue;
  1268. #endif
  1269.  
  1270. #if    defined(hpux)
  1271.         if (getu(p, u))
  1272.             continue;
  1273. #endif
  1274.  
  1275. #if    defined(_IBMR2)
  1276.         u = &us;
  1277.         if (getuser(p, PROCSIZE, u, U_SIZE) != 0)
  1278.             continue;
  1279. #endif
  1280.  
  1281. #if    defined(sun)
  1282.         if ((u = kvm_getu(Kd, p)) == NULL)
  1283.             continue;
  1284. #endif
  1285.  
  1286.     /*
  1287.      * Print information on the current directory.
  1288.      */
  1289.  
  1290. #if    defined(DYNIX) || defined(HPUX7) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  1291.         if (u->u_cdir) {
  1292. #endif
  1293.  
  1294. #if    defined(HPUX8)
  1295.         if (p->p_cdir) {
  1296. #endif
  1297.  
  1298.             Command = u->u_comm;
  1299.             Fdev = 0;
  1300.             Devch[0] = Iproto[0] = Type[0] = '\0';
  1301.         /*
  1302.          * The following line should be:
  1303.          *
  1304.          *    (void) strcpy(Fd, " cwd");
  1305.          *
  1306.          * However, the 3.1.3 xlc compiler produces incorrect code
  1307.          * for it when optimizing (-O).  The 3.1.5 xlc compiles the
  1308.          * strcpy() correctly.
  1309.          */
  1310.             (void) sprintf(Fd, "%4s", "cwd");
  1311.             Fprint = fprint;
  1312.             Inode = -1l;
  1313.             Lock = ' ';
  1314.             Namech[0] = '\0';
  1315.             Pid = p->p_pid;
  1316.             Size_def = 0;
  1317.             Vtype = V_REG;
  1318.             (void) printuid(p->p_uid);
  1319.  
  1320. #if    defined(DYNIX) || defined(HPUX7) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  1321.             printvnode((caddr_t)u->u_cdir);
  1322. #endif
  1323.  
  1324. #if    defined(HPUX8)
  1325.             printvnode((caddr_t)p->p_cdir);
  1326. #endif
  1327.         }
  1328.     /*
  1329.      * Loop through user's files.
  1330.      */
  1331.  
  1332. #if    defined(DYNIX)
  1333.  
  1334. #if    !defined(DYNIX31)
  1335.     /*
  1336.      * Under DYNIX, the file pointers may be located in the user
  1337.      * structure or in an extension to it.  Determine which is the
  1338.      * case and read the pointers.
  1339.      */
  1340.  
  1341.     if (u->u_ofile_ext) {
  1342.         if (kread((off_t)u->u_ofile_ext, (char *)&ofx, sizeof(ofx)))
  1343.             nf = 0;
  1344.         else {
  1345.             nf = ofx.oe_nofile;
  1346.             ui = (unsigned)(ofx.oe_nofile * sizeof(struct ofile));
  1347.             if (ofp == NULL) {
  1348.                 xnf = nf;
  1349.                 if ((ofp = (struct ofile *)malloc(ui))
  1350.                 == NULL) {
  1351.                     (void) fprintf(stderr,
  1352.                         "%s: no malloc ofile space\n",
  1353.                         Pn);
  1354.                     exit(1);
  1355.                 }
  1356.             } else if (nf > xnf) {
  1357.                 xnf = nf;
  1358.                 if ((ofp = (struct ofile *)realloc(
  1359.                        (MALLOC_P *)ofp, ui))
  1360.                 == NULL) {
  1361.                     (void) fprintf(stderr,
  1362.                         "%s: no realloc ofile space\n",
  1363.                         Pn);
  1364.                     exit(1);
  1365.                 }
  1366.             }
  1367.             if (kread((off_t)ofx.oe_ofile, (char *)ofp, (int)ui))
  1368.                 nf = 0;
  1369.             else {
  1370.                 nf = ofx.oe_nofile;
  1371.                 uf = ofp;
  1372.             }
  1373.         }
  1374.     } else {
  1375.         nf = NOFILE;
  1376.         uf = u->u_lofile;
  1377.     }
  1378. #endif
  1379.  
  1380. #if    defined(DYNIX31)
  1381.     /*
  1382.      * Under DYNIX 3.1, the file pointers should be located in an extension
  1383.      * to the user structure.  Determine if is the case and read the
  1384.      * pointers.
  1385.      */
  1386.  
  1387.     if (u->u_ofile_tab) {
  1388.         if (kread((off_t)u->u_ofile_tab, (char *)&oft, sizeof(oft)))
  1389.             nf = 0;
  1390.         else {
  1391.             nf = oft.oft_nofile;
  1392.             ui = (unsigned)(oft.oft_nofile * sizeof(struct ofile));
  1393.             if (ofp == NULL) {
  1394.                 xnf = nf;
  1395.                 if ((ofp = (struct ofile *)malloc(ui))
  1396.                 == NULL) {
  1397.                     (void) fprintf(stderr,
  1398.                         "%s: no malloc ofile space\n",
  1399.                         Pn);
  1400.                     exit(1);
  1401.                 }
  1402.             } else if (nf > xnf) {
  1403.                 xnf = nf;
  1404.                 if ((ofp = (struct ofile *)realloc(
  1405.                        (MALLOC_P *)ofp, ui))
  1406.                 == NULL) {
  1407.                     (void) fprintf(stderr,
  1408.                         "%s: no realloc ofile space\n",
  1409.                         Pn);
  1410.                     exit(1);
  1411.                 }
  1412.             }
  1413.             if (kread((off_t)oft.oft_ofile, (char *)ofp, (int)ui))
  1414.                 nf = 0;
  1415.             else {
  1416.                 nf = oft.oft_nofile;
  1417.                 uf = ofp;
  1418.             }
  1419.         }
  1420.     } else {
  1421.         nf = NOFILE;
  1422.         uf = u->u_lofileXXX;
  1423.     }
  1424. #endif
  1425.  
  1426. #endif
  1427.  
  1428. #if    defined(NeXT)
  1429.     /*
  1430.      * NeXTStep 2.0 and 2.1 file pointers come from a structure whose
  1431.      * pointer is in the user area.
  1432.      */
  1433.         nf = ut.uu_ofile_cnt;
  1434.                 nb = (MALLOC_S) (sizeof(struct file) * nf);
  1435.         if (uf == NULL) {
  1436.             if ((uf = (struct file **)malloc(nb)) == NULL) {
  1437.                 (void) fprintf(stderr,
  1438.                     "%s: no file table space, process %d\n",
  1439.                     Pn, p->p_pid);
  1440.                 exit(1);
  1441.             }
  1442.             pnb = nb;
  1443.         } else if (nb > pnb) {
  1444.             if ((uf = (struct file **)realloc((MALLOC_P *)uf, nb))
  1445.             == NULL) {
  1446.                 (void) fprintf(stderr,
  1447.                     "%s: realloc file[]\n", Pn);
  1448.                 exit(1);
  1449.             }
  1450.             pnb = nb;
  1451.         }
  1452.                 if (kread((off_t)ut.uu_ofile, (char *)uf, nb))
  1453.                         continue;
  1454. #endif
  1455.     
  1456. #if    defined(sun)
  1457.     /*
  1458.      * Under SunOS 4.1.1, the file pointers may be located in the
  1459.      * user structure or in a separately allocated area.  Determine
  1460.      * which is the case and read the pointers.
  1461.      */
  1462.         if ((caddr_t)u->u_ofile
  1463.         == ((caddr_t)&u->u_ofile_arr[0] - (caddr_t)&u
  1464.         + (caddr_t)p->p_uarea)) {
  1465.             nf = NOFILE_IN_U;
  1466.             uf = &u->u_ofile_arr[0];
  1467.         } else {
  1468.             nf = u->u_lastfile + 1;
  1469.             ui = nf * sizeof(struct file);
  1470.             if (xuf == NULL) {
  1471.                 xnf = nf;
  1472.                 if ((xuf = (struct file **)malloc(ui))
  1473.                 == NULL) {
  1474.                     (void) fprintf(stderr,
  1475.                         "%s: malloc file[]\n", Pn);
  1476.                     exit(1);
  1477.                 }
  1478.             } else if (nf > xnf) {
  1479.                 xnf = nf;
  1480.                 if ((xuf = (struct file **)realloc(
  1481.                        (MALLOC_P *)xuf, ui))
  1482.                 == NULL) {
  1483.                     (void) fprintf(stderr,
  1484.                         "%s: realloc file[]\n", Pn);
  1485.                     exit(1);
  1486.                 }
  1487.             }
  1488.             if (kread((off_t)u->u_ofile, (char *)xuf, (int)ui))
  1489.                 nf = 0;
  1490.             uf = xuf;
  1491.         }
  1492. #endif
  1493.  
  1494. #if    defined(DYNIX)
  1495.         for (i = 0; i < nf; i++) {
  1496.             if (uf[i].of_file)
  1497. #endif
  1498.  
  1499. #if    defined(HPUX7)
  1500.         for (i = j = k = 0;; i++) {
  1501.             if (j >= SFDCHUNK) {
  1502.  
  1503.             /*
  1504.              * Get next HP-UX file pointer "chunk".
  1505.              */
  1506.                 while (++k < NFDCHUNKS && u->u_ofilep[k] == NULL)
  1507.                 ;
  1508.                 if (k >= NFDCHUNKS)
  1509.                 break;
  1510.                 if (kread((off_t)u->u_ofilep[k],
  1511.                       (char *)&u->u_ofile,
  1512.                       sizeof(struct ofile_t)))
  1513.                 break;
  1514.                 j = 0;
  1515.             }
  1516.             j++;
  1517.             if (u->u_ofile.ofile[j - 1])
  1518. #endif
  1519.  
  1520. #if    defined(HPUX8)
  1521.         for (i = 0, j = SFDCHUNK;; i++) {
  1522.             if (j >= SFDCHUNK) {
  1523.                 if (kread((off_t)p->p_ofilep, (char *)&ofp,
  1524.                        sizeof(ofp)))
  1525.                 {
  1526.                 (void) fprintf(stderr,
  1527.                     "%s: can't read ofilep from %#x\n",
  1528.                     Pn, ofp);
  1529.                 exit(1);
  1530.                 }
  1531.                 if (ofp == NULL)
  1532.                 break;
  1533.                 if (kread((off_t)ofp, (char *)&oft, sizeof(oft))) {
  1534.                 (void) fprintf(stderr,
  1535.                     "%s: can't read ofile_t from %#x\n",
  1536.                     Pn, ofp);
  1537.                 exit(1);
  1538.                 }
  1539.                 j = 0;
  1540.                 p->p_ofilep++;
  1541.             }
  1542.             j++;
  1543.             if (oft.ofile[j - 1])
  1544. #endif
  1545.  
  1546. #if    defined(_IBMR2)
  1547.         for (i = 0; i < u->u_maxofile; i++) {
  1548.             if (u->u_ufd[i].fp)
  1549. #endif
  1550.  
  1551. #if    defined(NeXT) || defined(sun)
  1552.         for (i = 0; i < nf; i++) {
  1553.             if (uf[i])
  1554. #endif
  1555.             {
  1556.  
  1557.                                 Command = u->u_comm;
  1558.                                 Fdev = 0;
  1559.                 Fprint = fprint;
  1560.                                 Devch[0] = Iproto[0] = Type[0] = '\0';
  1561.                                 (void) sprintf(Fd, "%4d", i);
  1562.                                 Inode = -1l;
  1563.                                 Lock = ' ';
  1564.                                 Namech[0] = '\0';
  1565.                                 Pid = p->p_pid;
  1566.                 Size_def = 0;
  1567.                 Vtype = V_REG;
  1568.                 (void) printuid(p->p_uid);
  1569.  
  1570. #if    defined(DYNIX)
  1571.                 printfile(uf[i].of_file);
  1572. #endif
  1573.  
  1574. #if    defined(HPUX7)
  1575.                 printfile(u->u_ofile.ofile[j - 1]);
  1576. #endif
  1577.  
  1578. #if    defined(HPUX8)
  1579.                 printfile(oft.ofile[j - 1]);
  1580. #endif
  1581.  
  1582. #if    defined(_IBMR2)
  1583.                                 printfile(u->u_ufd[i].fp);
  1584. #endif
  1585.  
  1586. #if    defined(NeXT)
  1587.                 printfile(uf[i]);
  1588. #endif
  1589.  
  1590. #if    defined(sun)
  1591.                                 printfile(uf[i]);
  1592. #endif
  1593.             }
  1594.         }
  1595.     }
  1596.     for (sfp = Sfile; sfp; sfp = sfp->next) {
  1597.         if (sfp->f == 0)
  1598.             exit(1);
  1599.     }
  1600.  
  1601. #if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT)
  1602.     exit(0);
  1603. #endif
  1604.  
  1605. #if    defined(hpux) || defined(sun)
  1606.     return(0);
  1607. #endif
  1608.  
  1609. }
  1610.  
  1611.  
  1612. /*
  1613.  * compdev() - compare device numbers
  1614.  */
  1615.  
  1616. compdev(p1, p2)
  1617.     struct dev **p1;
  1618.     struct dev **p2;
  1619. {
  1620.     if ((long)((*p1)->rdev) < (long)((*p2)->rdev))
  1621.         return(-1);
  1622.     if ((long)((*p1)->rdev) > (long)((*p2)->rdev))
  1623.         return(1);
  1624.     return(0);
  1625. }
  1626.  
  1627.  
  1628. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  1629. /*
  1630.  * completevfs() - complete local vfs structure
  1631.  */
  1632.  
  1633. void
  1634. completevfs(vfs, dev)
  1635.     struct l_vfs *vfs;        /* local vfs structure pointer */
  1636.     dev_t dev;            /* inode/rnode device */
  1637. {
  1638.     struct mounts *mp;
  1639.  
  1640.     for (mp = Mtab; mp; mp = mp->next) {
  1641.         if (mp->dev == dev) {
  1642.  
  1643. #if    defined(DYNIX) || defined(hpux)
  1644.             vfs->dev = mp->dev;
  1645. #endif
  1646.  
  1647.             vfs->dir = mp->dir;
  1648.             vfs->fsname = mp->fsname;
  1649.             return;
  1650.         }
  1651.     }
  1652. }
  1653. #endif
  1654.  
  1655.  
  1656. /*
  1657.  * endnm() - locate end of Namech
  1658.  */
  1659.  
  1660. char *
  1661. endnm()
  1662. {
  1663.     char *s;
  1664.  
  1665.     for (s = Namech; *s; s++)
  1666.         ;
  1667.     return(s);
  1668. }
  1669.  
  1670.  
  1671. /*
  1672.  * entpid() - enter Process IDentifier for searching
  1673.  */
  1674.  
  1675. entpid(p)
  1676.     char *p;            /* PID string pointer */
  1677. {
  1678.     int i, pid;
  1679.     char *s;
  1680.  
  1681.     for (s = p; *s;) {
  1682.     /*
  1683.      * Assemble Process IDentifier.
  1684.      */
  1685.         for (pid = 0; *s && *s != ','; *s++) {
  1686.             if ( ! isascii(*s) || ! isdigit(*s)) {
  1687.                 (void) fprintf(stderr,
  1688.                     "%s: illegal PID specification: %s\n",
  1689.                     Pn, p);
  1690.                 return(1);
  1691.             }
  1692.             pid = (pid * 10) + *s - '0';
  1693.         }
  1694.         if (*s)
  1695.             s++;
  1696.     /*
  1697.      * Avoid entering duplicates.
  1698.      */
  1699.         for (i = 0; i < Npid; i++) {
  1700.             if (pid == Spid[i])
  1701.                 break;
  1702.         }
  1703.         if (i < Npid)
  1704.             continue;
  1705.     /*
  1706.      * Allocate PID table space.
  1707.      */
  1708.         if (Npid >= Mxpid) {
  1709.             Mxpid += PIDINCR;
  1710.             if (Spid == NULL)
  1711.                 Spid = (int *)malloc((MALLOC_S)
  1712.                     (sizeof(int *) * Mxpid));
  1713.             else
  1714.                 Spid = (int *)realloc((MALLOC_P *)Spid,
  1715.                     (MALLOC_S)(sizeof(int *) * Mxpid));
  1716.             if (Spid == NULL) {
  1717.                 (void) fprintf(stderr, "%s: no space for PIDs",
  1718.                     Pn);
  1719.                 exit(1);
  1720.             }
  1721.         }
  1722.         Spid[Npid++] = pid;
  1723.     }
  1724.     return(0);
  1725. }
  1726.  
  1727.  
  1728. /*
  1729.  * entuid() - enter User Identifier for searching
  1730.  */
  1731.  
  1732. entuid(u)
  1733.     char *u;            /* User IDentifier string pointer */
  1734. {
  1735.     int err, i, n;
  1736.     struct passwd *pw;
  1737.     char *s;
  1738.     char uid[LOGINML];
  1739.  
  1740.     for (err = 0, s = u; *s;) {
  1741.     /*
  1742.      * Assemble next User IDentifier.
  1743.      */
  1744.         for (i = n = 0; *s && *s != ','; i++, s++) {
  1745.             if (i >= LOGINML-1) {
  1746.                 (void) fprintf(stderr,
  1747.                     "%s: illegal UID in %s\n", Pn, u);
  1748.                 return(1);
  1749.             }
  1750.             uid[i] = *s;
  1751.             if (n < 0)
  1752.                 continue;
  1753.             if (isascii(*s) && isdigit(*s))
  1754.                 n = (n * 10) + *s - '0';
  1755.             else
  1756.                 n = -1;
  1757.         }
  1758.         if (*s)
  1759.             s++;
  1760.         if (n < 0) {
  1761.                uid[i] = '\0';
  1762.                if ((pw = getpwnam(uid)) == NULL) {
  1763.                 (void) fprintf(stderr,
  1764.                     "%s: can't get UID for %s\n",
  1765.                     Pn, uid);
  1766.                 err++;
  1767.                 continue;
  1768.             } else
  1769.                 n = pw->pw_uid;
  1770.         }
  1771.     /*
  1772.      * Avoid entering duplicates.
  1773.      */
  1774.         for (i = 0; i < Nuid; i++) {
  1775.             if (n == Suid[i])
  1776.                 break;
  1777.         }
  1778.         if (i < Nuid)
  1779.             continue;
  1780.     /*
  1781.      * Allocate space for User IDentifier.
  1782.      */
  1783.         if (Nuid >= Mxuid) {
  1784.             Mxuid += UIDINCR;
  1785.             if (Suid == NULL)
  1786.                 Suid = (int *)malloc((MALLOC_S)
  1787.                     (sizeof(int *) * Mxuid));
  1788.             else
  1789.                 Suid = (int *)realloc((MALLOC_P *)Suid,
  1790.                     (MALLOC_S)(sizeof(int *) * Mxuid));
  1791.             if (Suid == NULL) {
  1792.                 (void) fprintf(stderr, "%s: no space for UIDs",
  1793.                     Pn);
  1794.                 exit(1);
  1795.             }
  1796.         }
  1797.         Suid[Nuid++] = n;
  1798.     }
  1799.     return(err);
  1800. }
  1801.  
  1802.  
  1803. #if    defined(_IBMR2)
  1804. /*
  1805.  * getchan() - get channel from file path name
  1806.  */
  1807.  
  1808. int
  1809. getchan(p)
  1810.     char *p;            /* file path name */
  1811. {
  1812.     int ch;
  1813.     char *s;
  1814.  
  1815.     if ((s = strrchr(p, '/')) == NULL) 
  1816.         return(-1);
  1817.     if (*(++s) == '\0')
  1818.         return(-1);
  1819.     for (ch = 0; *s; s++) {
  1820.         if ( ! isascii(*s) || ! isdigit(*s))
  1821.             return(-1);
  1822.         ch = (ch * 10) + *s - '0';
  1823.     }
  1824.     return(ch);
  1825. }
  1826. #endif
  1827.  
  1828.  
  1829. #if    defined(DYNIX)
  1830. /*
  1831.  * getu() - get DYNIX user area
  1832.  */
  1833.  
  1834. getu(p, u)
  1835.     struct proc *p;            /* process area pointer */
  1836.     struct user *u;            /* user area destination */
  1837. {
  1838.     off_t sp;
  1839.  
  1840.     if ((p->p_flag & SLOAD) == 0) {
  1841.         sp = (off_t) dtob(p->p_swaddr);
  1842.         if (lseek(Swap, sp, L_SET) != sp
  1843.         ||  read(Swap, (char*)u, U_SIZE) != U_SIZE)
  1844.             return(1);
  1845.     } else {
  1846.         if (kread((off_t)p->p_uarea, (char *)u, U_SIZE))
  1847.             return(1);
  1848.     }
  1849.     return(0);
  1850. }
  1851. #endif
  1852.  
  1853.  
  1854. #if    defined(hpux)
  1855. /*
  1856.  * getu() - get HP-UX user area
  1857.  */
  1858.  
  1859. getu(p, u)
  1860.     struct proc *p;            /* process area pointer */
  1861.  
  1862. #if    defined(HPUX7)
  1863.     char *u;            /* user area destination */
  1864. #endif
  1865.  
  1866. #if    defined(HPUX8)
  1867.     struct user *u;            /* user area destination */
  1868. #endif
  1869.  
  1870. {
  1871.  
  1872. #if    defined(HPUX7)
  1873.     long sw;
  1874.  
  1875. #if    defined(hp9000s300)
  1876.     struct pte pte1, pte2;
  1877.     off_t pte_off, pte_addr;
  1878. #endif
  1879. #endif
  1880.  
  1881. #if    defined(HPUX8)
  1882.     char *c, *s;
  1883.     int i;
  1884.     struct pst_status ps;
  1885. #endif
  1886.  
  1887. #if    defined(HPUX7)
  1888. /*
  1889.  * Read the HP-UX 7.x user area from the swap file or memory.
  1890.  */
  1891.     if ((p->p_flag & SLOAD) == 0) {
  1892.  
  1893.     /*
  1894.      * If the process is not loaded, read the user area from the swap file.
  1895.      */
  1896.         sw = (long)p->p_swaddr;
  1897.  
  1898. #if    defined(hp9000s800)
  1899.         sw += (long)ctod(btoc(STACKSIZE * NBPG));
  1900. #endif
  1901.  
  1902.         if (lseek(Swap, (off_t)dtob(sw), L_SET) == (off_t)-1
  1903.         ||  read(Swap, u, U_SIZE) != U_SIZE)
  1904.             return(1);
  1905.         return(0);
  1906.     }
  1907.  
  1908. /*
  1909.  * Read the HP-UX 7.x user area via the page table.
  1910.  */
  1911.  
  1912. #if    defined(hp9000s300)
  1913.     pte_off = (off_t) &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1];
  1914.     if (kread(pte_off, (char *)&pte1, sizeof(pte1)))
  1915.         return(1);
  1916.     pte_addr = (off_t) (ctob(pte1.pg_pfnum + 1)
  1917.          - ((UPAGES + FLOAT) * sizeof(pte2)));
  1918.     if (lseek(Mem, pte_addr, L_SET) == (off_t)-1
  1919.     ||  read(Mem, (char *)&pte2, sizeof(pte2)) != sizeof(pte2))
  1920.         return(1);
  1921.     if (lseek(Mem, (off_t)ctob(pte2.pg_pfnum), L_SET) == (off_t)-1
  1922.     ||  read(Mem, u, sizeof(struct user)) != sizeof(struct user))
  1923.         return(1);
  1924. #endif
  1925.  
  1926. #if    defined(hp9000s800)
  1927.     if (kread((off_t)uvadd((struct proc *)Procaddr),u,sizeof(struct user)))
  1928.         return(1);
  1929. #endif
  1930. #endif    /* HPUX7 */
  1931.  
  1932. #if    defined(HPUX8)
  1933. /*
  1934.  * Use the undocumented HP-UX 8.x pstat() syscall to read process status.
  1935.  *
  1936.  * (HP won't release pstat(2) documentation to customers who have paid for
  1937.  * the inclusion of the syscall in HP-UX.  You figure that one out.)
  1938.  */
  1939.     (void) bzero(u, U_SIZE);
  1940.     if (pstat(PSTAT_PROC, &ps, sizeof(ps), 0, p->p_pid) != 1) {
  1941.         (void) fprintf(stderr, "%s: can't pstat process %d: %s\n",
  1942.             Pn, p->p_pid, sys_errlist[errno]);
  1943.         return(1);
  1944.     }
  1945. /*
  1946.  * Scan the pst_cmd command buffer and skip to the last component of the
  1947.  * first path name.  Also skip any leading `-', signifying a login shell.
  1948.  * Copy the result to u_comm[].
  1949.  */
  1950.     c = ps.pst_cmd;
  1951.     ps.pst_cmd[PST_CLEN - 1] = '\0';    /* paranoia */
  1952.     if (*c == '/') {
  1953.         for (s = c; *s && *s != ' '; s++) {
  1954.             if (*s == '/')
  1955.                 c = s + 1;
  1956.         }
  1957.     }
  1958.     if (*c == '-')
  1959.         c++;
  1960.     for (i = 0; i < MAXCOMLEN; i++) {
  1961.         if (*c == '\0' || *c == ' ' || *c == '/')
  1962.             break;
  1963.         u->u_comm[i] = *c++;
  1964.     }
  1965.     u->u_comm[i] = '\0';
  1966. /*
  1967.  * Copy other process status values to the user area, as required.
  1968.  */
  1969. #endif    /* HPUX8 */
  1970.  
  1971.     return(0);
  1972. }
  1973. #endif
  1974.  
  1975.  
  1976. /*
  1977.  * isfile() - is file selected for printing
  1978.  */
  1979.  
  1980. isfile(d, ty, ch, i)
  1981.     dev_t d;            /* device */
  1982.     enum vtype ty;            /* vnode type */
  1983.  
  1984. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun) 
  1985.     int ch;                /* dummy */
  1986. #endif
  1987.  
  1988. #if    defined(_IBMR2)
  1989.     chan_t ch;            /* gnode channel */
  1990. #endif
  1991.  
  1992.     long i;                 /* inode */
  1993.  
  1994. /* ARGSUSED */
  1995.  
  1996. {
  1997.     int f;
  1998.     struct sfile *s;
  1999.  
  2000.     for (f = 0, s = Sfile; s; s = s->next) {
  2001.  
  2002. #if    defined(_IBMR2)
  2003.     /*
  2004.      * Check for a regular AIX multiplexed file.  Match the channel if
  2005.      * it was supplied.
  2006.      */
  2007.         if (s->type && s->mode == S_IFCHR && d == s->dev
  2008.         && ty == VMPC) {
  2009.             if (s->ch < 0 || (s->ch >= 0 && ch == s->ch)) {
  2010.                 f = 1;
  2011.                 break;
  2012.             }
  2013.         }
  2014. #endif
  2015.  
  2016. #if    defined(sun)
  2017.     /*
  2018.      * Check for a Sun clone file.
  2019.      */
  2020.         if (Vtype == V_STREAM && major(s->dev) == CLONEMAJ
  2021.         && major(d) == minor(s->dev)) {
  2022.             f = 1;
  2023.             break;
  2024.         }
  2025. #endif
  2026.  
  2027.     /*
  2028.      * Check for a regular file or directory -- the device and
  2029.      * inode numbers must match.
  2030.      */
  2031.         if (s->type) {
  2032.             if (d == s->dev && (ino_t)i == s->i) {
  2033.                 f = 1;
  2034.                 break;
  2035.             }
  2036.             continue;
  2037.         }
  2038.     /*
  2039.      * Check for a file system match.
  2040.      * Try to avoid matching VCHR files to non-character devices.
  2041.      */
  2042.         if (d == s->dev) {
  2043.             if ( ! (ty == VCHR && s->mode != S_IFCHR)) {
  2044.                 f = 1;
  2045.                 break;
  2046.             }
  2047.         }
  2048.     }
  2049. /*
  2050.  * Convert the name if a match occurred.
  2051.  */
  2052.     if (f) {
  2053.         (void) strcpy(Namech, s->name);
  2054.  
  2055. #if    defined(_IBMR2)
  2056.         if (ty == VMPC && s->ch < 0)
  2057.             (void) sprintf(endnm(), "/%d", ch);
  2058. #endif
  2059.  
  2060.         if (s->devnm)
  2061.             (void) sprintf(endnm(), " (%s)", s->devnm);
  2062.         s->f = 1;
  2063.         return(1);
  2064.     }
  2065.     return(0);
  2066. }
  2067.  
  2068.  
  2069. #if    defined(_IBMR2)
  2070. /*
  2071.  * isglocked() - is a gnode locked
  2072.  */
  2073.  
  2074. char
  2075. isglocked(ga)
  2076.     struct gnode *ga;        /* local gnode address */
  2077. {
  2078.  
  2079.     struct filock f;
  2080.     off_t l;
  2081.  
  2082.     if (ga->gn_filocks == NULL)
  2083.         return(' ');
  2084.     if (kread((off_t)ga->gn_filocks, &f, sizeof(f)))
  2085.         return(' ');
  2086.     if (f.set.l_whence == 0 && f.set.l_start == 0 && f.set.l_len == MAXEND)
  2087.         l = 1;
  2088.     else
  2089.         l = 0;
  2090.     switch (f.set.l_type & (F_RDLCK | F_WRLCK)) {
  2091.  
  2092.     case F_RDLCK:
  2093.         return((l) ? 'R' : 'r');
  2094.     case F_WRLCK:
  2095.         return((l) ? 'W' : 'w');
  2096.     case (F_RDLCK + F_WRLCK):
  2097.         return('*');
  2098.     }
  2099.     return(' ');
  2100. }
  2101. #endif
  2102.  
  2103.  
  2104. /*
  2105.  * kread() - read from kernel memory
  2106.  */
  2107.  
  2108. int
  2109. kread(addr, buf, len)
  2110.     off_t addr;            /* kernel memory address */
  2111.     char *buf;            /* buffer to receive data */
  2112.     int len;            /* length to read */
  2113. {
  2114.     int br;
  2115.  
  2116. #if    defined(DYNIX) || defined(_IBMR2) || defined(hpux) || defined(NeXT)
  2117.     if (lseek(Kmem, addr, L_SET) == (off_t)-1)
  2118.         return(-1);
  2119.     br = read(Kmem, buf, len);
  2120. #endif
  2121.  
  2122. #if    defined(sun)
  2123.     br = kvm_read(Kd, (u_long)addr, buf, len);
  2124. #endif
  2125.  
  2126.     return((br == len) ? 0 : 1);
  2127. }
  2128.  
  2129.  
  2130. /*
  2131.  * printchdevname() - print character device name
  2132.  */
  2133.  
  2134. void
  2135. printchdevname(rdev, chan)
  2136.     dev_t rdev;            /* device */
  2137.  
  2138. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  2139.     int chan;            /* dummy */
  2140. #endif
  2141.  
  2142. #if    defined(_IBMR2)
  2143.     chan_t chan;            /* channel */
  2144. #endif
  2145.  
  2146. /* ARGSUSED */
  2147.  
  2148. {
  2149.  
  2150. #if    defined(sun)
  2151.     struct clone *c;
  2152. #endif
  2153.  
  2154.     int low, hi, mid;
  2155.     struct dev *dp;
  2156.  
  2157.  
  2158. #if    defined(sun)
  2159. /*
  2160.  * If this is a SunOS stream vnode, search for the clone parent.
  2161.  */
  2162.     if (Vtype == V_STREAM && Clone) {
  2163.         for (c = Clone; c; c = c->next) {
  2164.             dp = c->dp;
  2165.             if (major(rdev) == minor(dp->rdev))
  2166.                 goto found_device;
  2167.         }
  2168.     }
  2169. #endif
  2170.  
  2171.     low = mid = 0;
  2172.     hi = Ndev - 1;
  2173.         while (low <= hi) {
  2174.                 mid = (low + hi) / 2;
  2175.         dp = Sdev[mid];
  2176.         if ((long)rdev < (long)dp->rdev)
  2177.             hi = mid - 1;
  2178.         else if ((long)rdev > (long)dp->rdev)
  2179.                         low = mid + 1;
  2180.                 else {
  2181.  
  2182. #if    defined(sun)
  2183.  
  2184. found_device:
  2185.  
  2186. #endif
  2187.  
  2188. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  2189.             (void) strcpy(Namech, dp->name);
  2190. #endif
  2191.  
  2192. #if    defined(_IBMR2)
  2193.             if (chan < 0)
  2194.                 (void) strcpy(Namech, dp->name);
  2195.             else
  2196.                 (void) sprintf(Namech, "%s/%d", dp->name,
  2197.                     chan);
  2198. #endif
  2199.  
  2200.             return;
  2201.         }
  2202.         }
  2203.     (void) strcpy(Namech, "name unknown");
  2204. }
  2205.  
  2206.  
  2207. #if    defined(DTYPE_GNODE)
  2208. /*
  2209.  * printdevice() - print device file
  2210.  */
  2211.  
  2212. printdevice(va)
  2213.     caddr_t va;            /* vnode's kernel address */
  2214. {
  2215.     struct vnode v;
  2216.  
  2217.     if (readvnode(va, &v)) {
  2218.                 printline();
  2219.                 return;
  2220.         }
  2221.     (void) strcpy(Type, "dev");
  2222.     printline();
  2223. }
  2224. #endif
  2225.  
  2226.  
  2227. /*
  2228.  * printfile() - print file information
  2229.  */
  2230.  
  2231. void
  2232. printfile(fp)
  2233.     struct file *fp;        /* kernel file table address */
  2234. {
  2235.     struct file f;
  2236.  
  2237.     if (kread((off_t) fp, (char *) &f, sizeof(f))) {
  2238.         (void) sprintf(Namech, "can't read file struct from %#x", fp);
  2239.     } else {
  2240.         if (f.f_count) {
  2241.             switch (f.f_type) {
  2242.  
  2243.             case DTYPE_VNODE:
  2244.                 printvnode(f.f_data);
  2245.                 break;
  2246.  
  2247.             case DTYPE_SOCKET:
  2248.                 printsocket((caddr_t)f.f_data);
  2249.                 break;
  2250.  
  2251. #if    defined(DTYPE_GNODE)
  2252.             case DTYPE_GNODE:
  2253.                 printdevice(f.f_data);
  2254.                 break;
  2255. #endif
  2256.  
  2257.             default:
  2258.                 (void) sprintf(Namech,
  2259.                     "unknown file struct type %#x at %#x\n",
  2260.                     f.f_type, fp);
  2261.                 printline();
  2262.             }
  2263.             return;
  2264.         }
  2265.     }
  2266.     return;
  2267. }
  2268.  
  2269.  
  2270. /*
  2271.  * printinaddr() - print Internet address
  2272.  */
  2273.  
  2274. void
  2275. printinaddr(ia, p)
  2276.     struct in_addr *ia;        /* Internet address */
  2277.     u_short p;            /* port */
  2278. {
  2279.     unsigned char *u;
  2280.  
  2281.     if (ia->s_addr == INADDR_ANY) {
  2282.         (void) sprintf(endnm(), "*:%d", p);
  2283.         return;
  2284.     }
  2285.     u = (unsigned char *) ia;
  2286.     (void) sprintf(endnm(), "%u.%u.%u.%u:%u", u[0], u[1], u[2], u[3], p);
  2287. }
  2288.  
  2289.  
  2290. /*
  2291.  * printiproto() - print Internet protocol name
  2292.  */
  2293.  
  2294. void
  2295. printiproto(p)
  2296.     int p;                /* protocol number */
  2297. {
  2298.     int i;
  2299.     static int m = -1;
  2300.     char *s;
  2301.  
  2302.     switch(p) {
  2303.  
  2304. #if    defined(IPPROTO_TCP)
  2305.     case IPPROTO_TCP:
  2306.         s = "TCP";
  2307.         break;
  2308. #endif
  2309.  
  2310. #if    defined(IPPROTO_UDP)
  2311.     case IPPROTO_UDP:
  2312.         s = "UDP";
  2313.         break;
  2314. #endif
  2315.  
  2316. #if    defined(IPPROTO_IP)
  2317.     case IPPROTO_IP:
  2318.         s = "IP";
  2319.         break;
  2320. #endif
  2321.  
  2322. #if    defined(IPPROTO_ICMP)
  2323.     case IPPROTO_ICMP:
  2324.         s = "ICMP";
  2325.         break;
  2326. #endif
  2327.  
  2328. #if    defined(IPPROTO_IGMP)
  2329.     case IPPROTO_IGMP:
  2330.         s = "IGMP";
  2331.         break;
  2332. #endif
  2333.  
  2334. #if    defined(IPPROTO_GGP)
  2335.     case IPPROTO_GGP:
  2336.         s = "GGP";
  2337.         break;
  2338. #endif
  2339.  
  2340. #if    defined(IPPROTO_EGP)
  2341.     case IPPROTO_EGP:
  2342.         s = "EGP";
  2343.         break;
  2344. #endif
  2345.  
  2346. #if    defined(IPPROTO_PUP)
  2347.     case IPPROTO_PUP:
  2348.         s = "PUP";
  2349.         break;
  2350. #endif
  2351.  
  2352. #if    defined(IPPROTO_IDP)
  2353.     case IPPROTO_IDP:
  2354.         s = "IDP";
  2355.         break;
  2356. #endif
  2357.  
  2358. #if    defined(IPPROTO_ND)
  2359.     case IPPROTO_ND:
  2360.         s = "ND";
  2361.         break;
  2362. #endif
  2363.  
  2364. #if    defined(IPPROTO_RAW)
  2365.     case IPPROTO_RAW:
  2366.         s = "RAW";
  2367.         break;
  2368. #endif
  2369.  
  2370. #if    defined(IPPROTO_HELLO)
  2371.     case IPPROTO_HELLO:
  2372.         s = "HELLO";
  2373.         break;
  2374. #endif
  2375.  
  2376. #if    defined(IPPROTO_PXP)
  2377.     case IPPROTO_PXP:
  2378.         s = "PXP";
  2379.         break;
  2380. #endif
  2381.  
  2382. #if    defined(IPPROTO_RAWIP)
  2383.     case IPPROTO_RAWIP:
  2384.         s = "RAWIP";
  2385.         break;
  2386. #endif
  2387.  
  2388. #if    defined(IPPROTO_RAWIF)
  2389.     case IPPROTO_RAWIF:
  2390.         s = "RAWIF";
  2391.         break;
  2392. #endif
  2393.  
  2394.     default:
  2395.         s = NULL;
  2396.     }
  2397.     if (s)
  2398.         (void) sprintf(Iproto, "%*.*s", IPROTOL, IPROTOL, s);
  2399.     else {    
  2400.         if (m < 0) {
  2401.             for (i = 0, m = 1; i < IPROTOL-1; i++)
  2402.                 m *= 10;
  2403.         }
  2404.         (void) sprintf(Iproto, "%d?", p % m);
  2405.     }
  2406. }
  2407.  
  2408.  
  2409. /*
  2410.  * printline() - print output line
  2411.  */
  2412.  
  2413. void
  2414. printline()
  2415. {
  2416.     if (Fprint == 0)
  2417.         return;
  2418.     if (Fterse) {
  2419.         (void) printf("%d\n", Pid);
  2420.         return;
  2421.     }
  2422.     if (Hdr == 0) {
  2423.  
  2424. #if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2425.         (void) printf("COMMAND     PID     USER   FD  TYPE     DEVICE");
  2426. #endif
  2427.  
  2428. #if    defined(hpux)
  2429.         (void) printf("COMMAND     PID     USER   FD  TYPE       DEVICE");
  2430. #endif
  2431.  
  2432.         if (Fsize)
  2433.         (void) printf("     SIZE");
  2434.         (void)printf("   INODE/NAME\n");
  2435.     }
  2436.     Hdr++;
  2437.     (void) printf("%-9.9s%6d %8s %4s%c %4.4s ",
  2438.             Command ? Command : "",
  2439.             Pid,
  2440.             User,
  2441.             Fd,
  2442.             Lock,
  2443.             Type
  2444.     );
  2445.     if (Fdev)
  2446.  
  2447. #if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2448.         (void) printf(" %4d,%4d ", major(Dev), minor(Dev));
  2449. #endif
  2450.  
  2451. #if    defined(hpux)
  2452.         (void) printf("%3d,0x%06x ", major(Dev), minor(Dev));
  2453. #endif
  2454.  
  2455.     else {
  2456.         if (Devch[0])
  2457.  
  2458. #if    defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2459.             (void) printf("%s ", Devch);
  2460.         else
  2461.             (void) printf("           ");
  2462. #endif
  2463.  
  2464. #if    defined(hpux)
  2465.             (void) printf("  %s ", Devch);
  2466.         else
  2467.             (void) printf("             ");
  2468. #endif
  2469.  
  2470.     }
  2471.     if (Fsize) {
  2472.         if (Size_def)
  2473.             (void) printf("%8d ", Size);
  2474.         else
  2475.             (void) printf("         ");
  2476.     }
  2477.     if (Inode >= 0)
  2478.         (void) printf("%7ld ", Inode);
  2479.     else if (Inode == -2l) {
  2480.         if (Iproto[0] == '\0')
  2481.             (void) printf("%7s ", "");
  2482.         else
  2483.             (void) printf("%7.7s ", Iproto);
  2484.     }
  2485.     (void) printf("%s\n", Namech);
  2486. }
  2487.  
  2488.  
  2489. /*
  2490.  * printsocket() - print socket
  2491.  */
  2492.  
  2493. void
  2494. printsocket(sa)
  2495.     caddr_t sa;            /* socket address in kernel */
  2496. {
  2497.     int fam;
  2498.  
  2499. #if    defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2500.     struct domain d;
  2501. #endif
  2502.  
  2503. #if    defined(_IBMR2)
  2504.     struct gnode g;
  2505.     struct inode i;
  2506.     int is = 0;
  2507.     struct vnode v;
  2508. #endif
  2509.  
  2510.     struct inpcb inp;
  2511.     struct mbuf mb;
  2512.     struct protosw p;
  2513.     struct socket s;
  2514.     struct sockaddr_un *ua;
  2515.     struct unpcb uc, unp;
  2516.  
  2517.         (void) strcpy(Type, "sock");
  2518.     Inode = -2l;
  2519.     if (sa == NULL) {
  2520.         (void) sprintf(Namech, "no socket address");
  2521.         printline();
  2522.         return;
  2523.     }
  2524.         if (kread((off_t) sa, (char *) &s, sizeof(s))) {
  2525.                 (void) sprintf(Namech, "can't read socket struct from %#x",
  2526.             sa);
  2527.                 printline();
  2528.                 return;
  2529.         }
  2530.         if (s.so_proto == NULL
  2531.     ||  kread((off_t) s.so_proto, (char *) &p, sizeof(p))) {
  2532.                 (void) strcpy(Namech, "no protocol switch");
  2533.                 printline();
  2534.                 return;
  2535.         }
  2536.  
  2537. #if    defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2538.         if (kread((off_t) p.pr_domain, (char *) &d, sizeof(d))) {
  2539.                 (void) sprintf(Namech, "can't read domain struct from %#x",
  2540.                         p.pr_domain);
  2541.                 printline();
  2542.                 return;
  2543.         }
  2544. #endif
  2545.  
  2546. /*
  2547.  * Process socket by the associated domain family.
  2548.  */
  2549.  
  2550. #if    defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2551.     switch ((fam = d.dom_family))
  2552. #endif
  2553.  
  2554. #if    defined(HPUX7)
  2555.     switch ((fam = p.pr_family))
  2556. #endif
  2557.  
  2558.     {
  2559.     case AF_INET:
  2560.         if (Fnet)
  2561.             Fprint = 1;
  2562.         (void) strcpy(Type, "inet");
  2563.     /*
  2564.      * Read Internet protocol control block.
  2565.      */
  2566.         if (s.so_pcb == NULL
  2567.         || kread((off_t) s.so_pcb, (char *) &inp, sizeof(inp)))
  2568.             return;
  2569.         if ((struct socket *)sa != inp.inp_socket)
  2570.             return;
  2571.         printiproto(p.pr_protocol);
  2572.         (void) sprintf(Devch, "0x%08x",
  2573.                   (inp.inp_ppcb == NULL) ? s.so_pcb
  2574.                              : inp.inp_ppcb);
  2575.  
  2576. #if    defined(DYNIX)
  2577.         printinaddr(&inp.inp_laddr, ntohs(inp.inp_lport));
  2578. #endif
  2579.  
  2580. #if    defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2581.         printinaddr(&inp.inp_laddr, inp.inp_lport);
  2582. #endif
  2583.  
  2584.         if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport != 0) {
  2585.             (void) strcat(endnm(), "->");
  2586.  
  2587. #if    defined(DYNIX)
  2588.         printinaddr(&inp.inp_faddr, ntohs(inp.inp_fport));
  2589. #endif
  2590.  
  2591. #if    defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  2592.             printinaddr(&inp.inp_faddr, inp.inp_fport);
  2593. #endif
  2594.  
  2595.         }
  2596.         break;
  2597.  
  2598.     case AF_UNIX:
  2599.         if (Funix)
  2600.             Fprint = 1;
  2601.         (void) strcpy(Type, "unix");
  2602.     /*
  2603.      * Read Unix protocol control block and the Unix address structure.
  2604.      */
  2605.  
  2606.         (void) sprintf(Devch, "0x%08x", sa);
  2607.         if (kread((off_t) s.so_pcb, (char *) &unp, sizeof(unp))) {
  2608.             (void) sprintf(Namech, "can't read unpcb at %#x",
  2609.                 s.so_pcb);
  2610.             break;
  2611.         }
  2612.         if ((struct socket *)sa != unp.unp_socket) {
  2613.             (void) sprintf(Namech, "unp_socket (%#x) mismatch",
  2614.                 unp.unp_socket);
  2615.             break;
  2616.         }
  2617.         if (unp.unp_addr) {
  2618.             if (kread((off_t) unp.unp_addr, (char *) &mb, sizeof(mb))) {
  2619.             (void) sprintf(Namech,
  2620.                 "can't read unp_addr at %#x",
  2621.                 unp.unp_addr);
  2622.             break;
  2623.             }
  2624.             ua = (struct sockaddr_un *)(((char *)&mb) + mb.m_off);
  2625.         } else {
  2626.             ua = (struct sockaddr_un *)&mb;
  2627.             (void) bzero((char *)ua, sizeof(struct sockaddr_un));
  2628.             ua->sun_family = AF_UNSPEC;
  2629.         }
  2630.     /*
  2631.      * Print information on Unix socket that has no address bound
  2632.      * to it, although it may be connected to another Unix domain
  2633.      * socket as a pipe.
  2634.      */
  2635.         if (ua->sun_family != AF_UNIX) {
  2636.             if (ua->sun_family == AF_UNSPEC) {
  2637.                 if (unp.unp_conn) {
  2638.                     if (kread((off_t) unp.unp_conn,
  2639.                         (char *) &uc, sizeof(uc))) {
  2640.                         (void) sprintf(Namech,
  2641.                         "can't read unp_conn at %#x",
  2642.                         unp.unp_conn);
  2643.                     } else {
  2644.                         (void) sprintf(Namech,
  2645.                         "->0x%08x", uc.unp_socket);
  2646.                     }
  2647.                 } else
  2648.                     (void) strcpy(Namech, "->(none)");
  2649.             } else
  2650.                 (void) sprintf(Namech,
  2651.                     "unknown sun_family (%d)",
  2652.                     ua->sun_family);
  2653.             break;
  2654.         }
  2655.  
  2656. #if    defined(_IBMR2)
  2657.     /*
  2658.      * Read any associated vnode and then read its gnode and inode.
  2659.      */
  2660.         g.gn_type = VSOCK;
  2661.         if (unp.unp_vnode && readvnode(unp.unp_vnode, &v) == 0) {
  2662.             if (v.v_gnode && readgnode(v.v_gnode, &g) == 0) {
  2663.                 Lock = isglocked(&g);
  2664.                 if (g.gn_type == VSOCK && g.gn_data
  2665.                 && readinode(g.gn_data, &i) == 0)
  2666.                     is = 1;
  2667.             }
  2668.         }
  2669.     /*
  2670.      * Print Unix socket information.
  2671.      */
  2672.         if (is) {
  2673.             Dev = i.i_dev;
  2674.             Fdev = 1;
  2675.             Devch[0] = '\0';
  2676.             Inode = (long)i.i_number;
  2677.         }
  2678. #endif
  2679.  
  2680.         (void) sprintf(Namech, "%.*s",
  2681.             mb.m_len - sizeof(ua->sun_family),
  2682.             ua->sun_path[0] ? ua->sun_path : "no address");
  2683.         break;
  2684.  
  2685.     default:
  2686.         (void) sprintf(Namech, "unknown family %#x", fam);
  2687.     }
  2688.     printline();
  2689. }
  2690.  
  2691.  
  2692. /*
  2693.  * printuid() - print User ID or login name
  2694.  */
  2695.  
  2696. void
  2697. printuid(u)
  2698.     uid_t u;            /* User ID number */
  2699. {
  2700.     static int p = 0;
  2701.     static uid_t pu;
  2702.     struct passwd *pw;
  2703.  
  2704.     if (p && u == pu)
  2705.         return;
  2706.     p = 1;
  2707.     pu = u;
  2708.     if (Futol && (pw = getpwuid(u)) != NULL)
  2709.         (void) sprintf(User, "%*.*s", USERPRTL, USERPRTL, pw->pw_name);
  2710.     else
  2711.         (void) sprintf(User, "%*d", USERPRTL, u);
  2712. }
  2713.  
  2714.  
  2715. /*
  2716.  * printvnode() - print vnode
  2717.  */
  2718.  
  2719. void
  2720. printvnode(va)
  2721.     caddr_t va;            /* vnode kernel space address */
  2722. {
  2723.  
  2724.     dev_t dev;
  2725.     struct inode i;
  2726.     int prdev;
  2727.     struct rnode r;
  2728.     char *ty;
  2729.     enum vtype type;
  2730.     struct vnode v;
  2731.     struct l_vfs *vfs;
  2732.  
  2733. #if    defined(NeXT)
  2734.     struct vnode rv;
  2735.     struct snode s;
  2736. #endif
  2737.  
  2738. #if    defined(_IBMR2)
  2739.     struct cdrnode c;
  2740.     struct gnode g;
  2741. #endif
  2742.  
  2743. #if    defined(sun)
  2744.     struct fifonode f;
  2745.     struct vnode rv;
  2746.     struct snode s;
  2747.     struct tmpnode t;
  2748. #endif
  2749.  
  2750. /*
  2751.  * Read the vnode.
  2752.  */
  2753.     if (readvnode((caddr_t)va, &v)) {
  2754.                 printline();
  2755.                 return;
  2756.         }
  2757.  
  2758.  
  2759. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  2760. /*
  2761.  * Determine the DYNIX, HP-UX, NeXT and SunOS vnode type.
  2762.  */
  2763.     if ((unsigned long)v.v_op == Nl[X_NFS_OPS].n_value)
  2764.         Vtype = V_NFS;
  2765.  
  2766. #if    defined(sun)
  2767.     else if ((unsigned long)v.v_op == Nl[X_TMP_OPS].n_value)
  2768.         Vtype = V_TMP;
  2769. #endif
  2770.  
  2771.     else if (v.v_type == VFIFO)
  2772.         Vtype = V_FIFO;
  2773.  
  2774. #if    defined(sun)
  2775.     else if (v.v_type == VCHR && !v.v_vfsp && v.v_stream)
  2776.         Vtype = V_STREAM;
  2777. #endif
  2778.  
  2779. /*
  2780.  * Determine the DYNIX, HP-UX, NeXT or SunOS lock type.
  2781.  */
  2782.     if (v.v_shlockc || v.v_exlockc) {
  2783.         if (v.v_shlockc && v.v_exlockc)
  2784.             Lock = '*';
  2785.         else if (v.v_shlockc)
  2786.             Lock = 'R';
  2787.         else
  2788.             Lock = 'W';
  2789.     }
  2790. #endif
  2791.  
  2792. /*
  2793.  * Read the virtual file system structure.
  2794.  */
  2795.     if ((vfs = readvfs(v.v_vfsp)) == NULL) {
  2796.                 (void) sprintf(Namech, "can't read vfs for %#x at %#x", v,
  2797.             v.v_vfsp);
  2798.                 printline();
  2799.         return;
  2800.     }
  2801.  
  2802. #if    defined(_IBMR2)
  2803. /*
  2804.  * Determine the AIX vnode type.
  2805.  */
  2806.     if (vfs->vmt_flags & MNT_REMOTE)
  2807.         Vtype = V_NFS;
  2808. /*
  2809.  * Read the AIX gnode and the associated inode or rnode.
  2810.  */
  2811.  
  2812.     if (v.v_gnode) {
  2813.         if (readgnode(v.v_gnode, &g)) {
  2814.             printline();
  2815.             return;
  2816.         }
  2817.     } else {
  2818.         (void) sprintf(Namech, "vnode at %#x has no gnode\n", va);
  2819.         printline();
  2820.         return;
  2821.     }
  2822.     Lock = isglocked(&g);
  2823.     if (Vtype == V_NFS) {
  2824.         if (g.gn_data == NULL || readrnode(g.gn_data, &r)) {
  2825.             (void) sprintf(Namech,
  2826.                 "remote gnode at %#x has no rnode", v.v_gnode);
  2827.             printline();
  2828.             return;
  2829.         }
  2830.     } else {
  2831.         if (vfs->vmt_gfstype == MNT_CDROM) {
  2832.             if (g.gn_data == NULL || readcdrnode(g.gn_data, &c)) {
  2833.                 (void) sprintf(Namech,
  2834.                     "gnode at %#x has no cdrnode",
  2835.                     v.v_gnode);
  2836.                 printline();
  2837.                 return;
  2838.             }
  2839.             i.i_number = c.cn_inumber;
  2840.             i.i_size = (off_t)c.cn_size;
  2841.         } else if (g.gn_data == NULL || readinode(g.gn_data, &i)) {
  2842.             (void) sprintf(Namech, "gnode at %#x has no inode",
  2843.                 v.v_gnode);
  2844.             printline();
  2845.             return;
  2846.         }
  2847.     }
  2848. #endif
  2849.  
  2850. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  2851. /*
  2852.  * Read the DYNIX, HP-UX, NeXT or SunOS fifonode, inode, rnode, snode or
  2853.  * tmpnode.
  2854.  */
  2855.     switch (Vtype) {
  2856.     case V_NFS:
  2857.         if (!v.v_data || readrnode((caddr_t)v.v_data, &r)) {
  2858.             (void) sprintf(Namech,
  2859.                 "vnode at %#x: can't read rnode (%#x)",
  2860.                 va, v.v_data);
  2861.             printline();
  2862.             return;
  2863.         }
  2864.         break;
  2865.  
  2866. #if    defined(sun)
  2867.     case V_FIFO:
  2868.  
  2869.     /*
  2870.      * A Sun FIFO's vnode is linked to a fifonode.  The s_realvp
  2871.      * pointer of the snode contained in the fifonode points to
  2872.      * a vnode that points to the inode.  (Whew!)
  2873.      */
  2874.         if (!v.v_data || readfifonode(v.v_data, &f)) {
  2875.             (void) sprintf(Namech,
  2876.                 "vnode at %#x: can't read fifonode (%#x)",
  2877.                 va, v.v_data);
  2878.             printline();
  2879.             return;
  2880.         }
  2881.         if (f.fn_snode.s_realvp) {
  2882.             if (readvnode((caddr_t)f.fn_snode.s_realvp, &rv)) {
  2883.                 (void) sprintf(Namech,
  2884.                 "fifonode at %#x: can't read real vnode (%#x)",
  2885.                 v.v_data, f.fn_snode.s_realvp);
  2886.                 printline();
  2887.                 return;
  2888.             }
  2889.             if (!rv.v_data || readinode(rv.v_data, &i)) {
  2890.                 (void) sprintf(Namech,
  2891.                     "fifonode at %#x: can't read inode (%#x)",
  2892.                     v.v_data, rv.v_data);
  2893.                 printline();
  2894.                 return;
  2895.             }
  2896.         } else {
  2897.             printline();
  2898.             return;
  2899.         }
  2900.         break;
  2901.     case V_STREAM:
  2902.         if (!v.v_data || readsnode((caddr_t)v.v_data, &s)) {
  2903.             (void) sprintf(Namech,
  2904.                 "vnode at %#x: can't read snode (%#x)",
  2905.                 va, v.v_data);
  2906.             printline();
  2907.             return;
  2908.         }
  2909.         break;
  2910.     case V_TMP:
  2911.         if (!v.v_data || readtnode((caddr_t)v.v_data, &t)) {
  2912.             (void) sprintf(Namech,
  2913.                 "vnode at %#x: can't read tnode (%#x)",
  2914.                 va, v.v_data);
  2915.             printline();
  2916.             return;
  2917.         }
  2918.         break;
  2919. #endif
  2920.  
  2921.     case V_REG:
  2922.     default:
  2923.  
  2924. #if    defined(NeXT) || defined(sun)
  2925.     /*
  2926.      * NeXT and Sun VCHR vnodes point to an snode.  The snode's s_realvp
  2927.      * usually points to a real vnode, which points to an inode.
  2928.      */
  2929.         if (v.v_type == VCHR) {
  2930.             if (!v.v_data || readsnode(v.v_data, &s)) {
  2931.                 (void) sprintf(Namech,
  2932.                     "vnode at %#x: can't read snode(%#x)",
  2933.                     va, v.v_data);
  2934.                 printline();
  2935.                 return;
  2936.             }
  2937.             if (s.s_realvp) {
  2938.                 if (readvnode((caddr_t)s.s_realvp, &rv)) {
  2939.                 (void) sprintf(Namech,
  2940.                     "snode at %#x: can't read real vnode (%#x)",
  2941.                     v.v_data, s.s_realvp);
  2942.                 printline();
  2943.                 return;
  2944.                 }
  2945.                 if (!rv.v_data || readinode(rv.v_data, &i)) {
  2946.                 (void) sprintf(Namech,
  2947.                     "snode at %#x: can't read inode (%#x)",
  2948.                     v.v_data, rv.v_data);
  2949.                 printline();
  2950.                 return;
  2951.                 }
  2952.             } else
  2953.                 (void) bzero((char *)&i, sizeof(i));
  2954.             break;
  2955.         }
  2956. #endif
  2957.  
  2958.         if (!v.v_data || readinode(v.v_data, &i)) {
  2959.             (void) sprintf(Namech,
  2960.                 "vnode at %#x: can't read inode (%#x)",
  2961.                 va, v.v_data);
  2962.             printline();
  2963.             return;
  2964.         }
  2965.     }
  2966. #endif
  2967.  
  2968. /*
  2969.  * Get device and type for printing.
  2970.  */
  2971.  
  2972. #if    defined(DYNIX)
  2973.     switch(Vtype) {
  2974.     case V_NFS:
  2975.  
  2976.     /*
  2977.      * Neither the rnode nor the vnode under DYNIX 3.0.12 contains the
  2978.      * correct device number, so it's reclaimed (if possible) from the
  2979.      * local, virtual file system table entry (put there by completevfs()
  2980.      * from information placed in Mtab by readmnt()).
  2981.      */
  2982.         dev = vfs->dev;
  2983.         break;
  2984.     default:
  2985.         dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  2986.     }
  2987.     type = v.v_type;
  2988.     if (vfs->dir == NULL)
  2989.         (void) completevfs(vfs, dev);
  2990. #endif
  2991.  
  2992. #if    defined(hpux)
  2993.     if (Vtype == V_NFS)
  2994.         dev = vfs->dev;
  2995.     else
  2996.         dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  2997.     type = v.v_type;
  2998. #endif
  2999.  
  3000. #if    defined(_IBMR2)
  3001.     if (Vtype == V_NFS)
  3002.         dev = vfs->dev;
  3003.     else
  3004.         dev = g.gn_rdev;
  3005.     type = g.gn_type;
  3006. #endif
  3007.  
  3008. #if    defined(NeXT)
  3009.     switch (Vtype) {
  3010.     case V_NFS:
  3011.         dev = r.r_attr.va_fsid;
  3012.         if (dev & 0x8000)
  3013.             dev |= 0xff00;
  3014.         break;
  3015.     case V_REG:
  3016.         dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  3017.     }
  3018.     type = v.v_type;
  3019.     if (vfs->dir == NULL)
  3020.         (void) completevfs(vfs, dev);
  3021. #endif
  3022.  
  3023. #if    defined(sun)
  3024.     switch (Vtype) {
  3025.     case V_NFS:
  3026.         dev = r.r_attr.va_fsid;
  3027.         break;
  3028.     case V_STREAM:
  3029.         dev = s.s_dev;
  3030.         break;
  3031.     case V_TMP:
  3032.         dev = t.tn_attr.va_fsid;
  3033.         break;
  3034.     default:
  3035.         dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
  3036.     }
  3037.     type = v.v_type;
  3038.     if (vfs->dir == NULL)
  3039.         (void) completevfs(vfs, dev);
  3040. #endif
  3041.  
  3042. /*
  3043.  * Obtain the inode number.
  3044.  */
  3045.  
  3046. #if    defined(DYNIX)
  3047.     switch (Vtype) {
  3048.     case V_NFS:
  3049.         Inode = (long)r.r_nfsattr.na_nodeid;
  3050.         break;
  3051.     case V_FIFO:
  3052.     case V_REG:
  3053.         Inode = (long)i.i_number;
  3054.     }
  3055. #endif
  3056.  
  3057. #if    defined(hpux)
  3058.     switch (Vtype) {
  3059.     case V_NFS:
  3060.         Inode = (long)r.r_nfsattr.na_nodeid;
  3061.         break;
  3062.     case V_FIFO:
  3063.     case V_REG:
  3064.         Inode = (long)i.i_number;
  3065.     }
  3066. #endif
  3067.  
  3068. #if    defined(_IBMR2)
  3069.     Inode = (long)(Vtype == V_NFS) ? r.r_attr.va_serialno : i.i_number;
  3070. #endif
  3071.  
  3072. #if    defined(NeXT)
  3073.     switch(Vtype) {
  3074.     case V_NFS:
  3075.         Inode = (long)r.r_attr.va_nodeid;
  3076.         break;
  3077.     case V_REG:
  3078.         Inode = (long)i.i_number;
  3079.     }
  3080. #endif
  3081.  
  3082. #if    defined(sun)
  3083.     switch (Vtype) {
  3084.     case V_NFS:
  3085.         Inode = (long)r.r_attr.va_nodeid;
  3086.         break;
  3087.     case V_FIFO:
  3088.     case V_REG:
  3089.         Inode = (long)i.i_number;
  3090.         break;
  3091.     case V_TMP:
  3092.         Inode = (long)t.tn_attr.va_nodeid;
  3093.         break;
  3094.     case V_STREAM:
  3095.         Inode = -2l;
  3096.     }
  3097. #endif
  3098.  
  3099. /*
  3100.  * Obtain the file size.
  3101.  */
  3102.     switch (Vtype) {
  3103.     case V_NFS:
  3104.  
  3105. #if    defined(DYNIX) || defined(hpux)
  3106.         Size = r.r_nfsattr.na_size;
  3107. #endif
  3108.  
  3109. #if    defined(_IBMR2) || defined(NeXT) || defined(sun)
  3110.         Size = r.r_attr.va_size;
  3111. #endif
  3112.  
  3113.         Size_def = 1;
  3114.         break;
  3115.     case V_REG:
  3116.         Size = i.i_size;
  3117.         Size_def = 1;
  3118.     }
  3119.  
  3120. /*
  3121.  * Format the name characters.
  3122.  */
  3123.     if (Vtype == V_NFS && Fnfs)
  3124.         Fprint = 1;
  3125.     (void) sprintf(Namech, "%s (%s)",
  3126.         (vfs->dir) ? vfs->dir : "",
  3127.         (vfs->fsname) ? vfs->fsname : "");
  3128. /*
  3129.  * Test for specified file.
  3130.  */
  3131.     prdev = 1;
  3132.     if (Sfile && Fprint == 0) {
  3133.  
  3134. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
  3135.         Fprint = isfile(dev, type, 0, Inode);
  3136. #endif
  3137.  
  3138. #if    defined(_IBMR2)
  3139.         Fprint = isfile(dev, type, g.gn_chan, Inode);
  3140. #endif
  3141.  
  3142.         if (Fprint == 0)
  3143.             return;
  3144.         prdev = 0;
  3145.     }
  3146. /*
  3147.  * Format the vnode type, and possibly the device name.
  3148.  */
  3149.     switch (type) {
  3150.  
  3151.     case VNON:
  3152.         ty ="VNON";
  3153.         break;
  3154.     case VREG:
  3155.     case VDIR:
  3156.         ty = (type == VREG) ? "VREG" : "VDIR";
  3157.         Fdev = 1;
  3158.         Dev = dev;
  3159.         break;
  3160.     case VBLK:
  3161.         ty = "VBLK";
  3162.         break;
  3163.     case VCHR:
  3164.         Dev = dev;
  3165.         Fdev = 1;
  3166.         if (prdev)
  3167.             (void) printchdevname(Dev, -1);
  3168.         ty = "VCHR";
  3169.         break;
  3170.     case VLNK:
  3171.         ty = "VLNK";
  3172.         break;
  3173.     case VSOCK:
  3174.         ty = "SOCK";
  3175.         break;
  3176.     case VBAD:
  3177.         ty = "VBAD";
  3178.         break;
  3179.     case VFIFO:
  3180.         Dev = dev;
  3181.         Fdev = 1;
  3182.         ty = "FIFO";
  3183.         break;
  3184.  
  3185. #if    defined(_IBMR2)
  3186.     case VMPC:
  3187.         Dev = g.gn_rdev;
  3188.         Fdev = 1;
  3189.         Inode = -2l;
  3190.         if (prdev)
  3191.             (void) printchdevname(g.gn_rdev, g.gn_chan);
  3192.         ty = "VMPC";
  3193.         break;
  3194. #endif
  3195.  
  3196.     default:
  3197.         (void) sprintf(Type, "%4d", type);
  3198.         (void) strcpy(Namech, "unknown type");
  3199.         ty = NULL;
  3200.     }
  3201.     if (ty)
  3202.         (void) strcpy(Type, ty);
  3203. /*
  3204.  * Print the line (at last) if printing has been selected.
  3205.  */
  3206.     printline();
  3207. }
  3208.  
  3209.  
  3210. #if    defined(_IBMR2)
  3211. /*
  3212.  * readcdrnode() - read CD-ROM node
  3213.  */
  3214.  
  3215. int
  3216. readcdrnode(ca, c)
  3217.     caddr_t ca;            /* cdrnode kernel address */
  3218.     struct cdrnode *c;        /* cdrnode buffer */
  3219. {
  3220.     if (kread((off_t)ca, (char *)c, sizeof(struct cdrnode))) {
  3221.         (void) sprintf(Namech, "can't read cdrnode at %#x", ca);
  3222.         return(1);
  3223.     }
  3224.     return(0);
  3225. }
  3226. #endif
  3227.  
  3228.  
  3229. /*
  3230.  * readdev() - read names, modes and device types of everything in /dev
  3231.  */
  3232.  
  3233. void
  3234. readdev()
  3235. {
  3236.  
  3237.     DIR *dfp;
  3238.     int dn = 0;
  3239.     char **dstk = NULL;
  3240.     int dx = 0;
  3241.     int err = 0;
  3242.     int i = 0;
  3243.     MALLOC_S nl;
  3244.     char path[MAXNAMLEN+1];
  3245.     int pl;
  3246.     struct stat sb;
  3247.  
  3248. #if    defined(DYNIX) || defined(NeXT)
  3249.     struct direct *dp;
  3250. #endif
  3251.  
  3252. #if    defined(hpux) || defined(_IBMR2) || defined(sun)
  3253.     struct dirent *dp;
  3254. #endif
  3255.  
  3256. #if    defined(sun)
  3257.     struct clone *c;
  3258. #endif
  3259.  
  3260.     (void) stkdir(&dstk, &dn, &dx, "/dev");
  3261. /*
  3262.  * Unstack the next /dev or /dev/<subdirectory> directory.
  3263.  */
  3264.     while (--dx >= 0) {
  3265.         (void) strcpy(path, dstk[dx]);
  3266.         if ((dfp = opendir(path)) == NULL) {
  3267.             if (Fdevmsg)
  3268.                 (void) fprintf(stderr, "%s: can't open %s\n",
  3269.                     Pn, path);
  3270.             continue;
  3271.         }
  3272.         (void) strcat(path, "/");
  3273.         pl = strlen(path);
  3274.         (void) free((FREE_P *)dstk[dx]);
  3275.         dstk[dx] = NULL;
  3276.     /*
  3277.      * Scan the directory.
  3278.      */
  3279.         for (dp = readdir(dfp); dp; dp = readdir(dfp)) {
  3280.             if (dp->d_ino == 0 || dp->d_name[0] == '.')
  3281.                 continue;
  3282.         /*
  3283.          * Form the full path name and get its status.
  3284.          */
  3285.             if ((nl = pl + dp->d_namlen) >= sizeof(path)) {
  3286.                 (void) fprintf(stderr,
  3287.                     "%s: /dev entry name too long: %s\n",
  3288.                     Pn, dp->d_name);
  3289.                 exit(1);
  3290.             }
  3291.             (void) strncpy(&path[pl], dp->d_name,
  3292.                       (STRNCPY_L)dp->d_namlen);
  3293.             path[nl++] = '\0';
  3294.             if (lstat(path, &sb) != 0) {
  3295.                 (void) fprintf(stderr,
  3296.                     "%s: can't lstat %s: %s\n",
  3297.                     Pn, path, sys_errlist[errno]);
  3298.                 err++;
  3299.                 continue;
  3300.             }
  3301.         /*
  3302.          * If it's a subdirectory, stack its name for later
  3303.          * processing.
  3304.          */
  3305.             if ((sb.st_mode & S_IFMT) == S_IFDIR) {
  3306.                 (void) stkdir(&dstk, &dn, &dx, path);
  3307.                 continue;
  3308.             }
  3309.         /*
  3310.          * Skip all but character devices.
  3311.          */
  3312.             if ((sb.st_mode & S_IFMT) != S_IFCHR)
  3313.                 continue;
  3314.         /*
  3315.          * Make room for another Devtp[] entry.
  3316.          */
  3317.             if (i >= Ndev) {
  3318.                 Ndev += DEVINCR;
  3319.                 if (Devtp == NULL)
  3320.                     Devtp = (struct dev *)malloc(
  3321.                     (MALLOC_S)(sizeof(struct dev) * Ndev));
  3322.                 else
  3323.                     Devtp = (struct dev *)realloc(
  3324.                     (MALLOC_P *)Devtp,
  3325.                     (MALLOC_S)(sizeof(struct dev)*Ndev));
  3326.                 if (Devtp == NULL) {
  3327.                     (void) fprintf(stderr,
  3328.                         "%s: no space for devices\n",
  3329.                         Pn);
  3330.                     exit(1);
  3331.                 }
  3332.             }
  3333.         /*
  3334.          * Store the name and device number in the Devtp[] entry.
  3335.          */
  3336.             Devtp[i].rdev = sb.st_rdev;
  3337.             if ((Devtp[i].name = (char *)malloc(nl)) == NULL) {
  3338.                 (void) fprintf(stderr,
  3339.                     "%s: no space for /dev/%s\n",
  3340.                     Pn, dp->d_name);
  3341.                 exit(1);
  3342.             }
  3343.             (void) strcpy(Devtp[i].name, path);
  3344.  
  3345. #if    defined(sun)
  3346.         /*
  3347.          * Save the locations of the SunOS clone devices.
  3348.          */
  3349.             if (major(Devtp[i].rdev) == CLONEMAJ) {
  3350.                 if ((c =
  3351.                    (struct clone *)malloc(sizeof(struct clone)))
  3352.                 == NULL) {
  3353.                     (void) fprintf(stderr,
  3354.                         "%s: no space for clone\n", Pn);
  3355.                     exit(1);
  3356.                 }
  3357.                 c->dp = &Devtp[i];
  3358.                 c->next = Clone;
  3359.                 Clone = c;
  3360.             }
  3361. #endif
  3362.  
  3363.             i++;
  3364.         }
  3365.         (void) closedir(dfp);
  3366.     }
  3367. /*
  3368.  * Free any directory stack space.
  3369.  */
  3370.     if (dstk != NULL)
  3371.         (void) free((FREE_P *)dstk);
  3372. /*
  3373.  * Reduce the Devtp[] table to its minimum size.
  3374.  */
  3375.     if (Ndev > i) {
  3376.         Ndev = i;
  3377.         Devtp = (struct dev *)realloc((MALLOC_P *)Devtp,
  3378.               (MALLOC_S)(sizeof(struct dev) * Ndev));
  3379.     }
  3380.     if (err)
  3381.         exit(1);
  3382. /*
  3383.  * Allocate sorting pointers and sort them by Devtp[] device number.
  3384.  */
  3385.     if ((Sdev = (struct dev **)malloc((MALLOC_S)(sizeof(struct dev *)
  3386.         * Ndev)))
  3387.     == NULL) {
  3388.         (void) fprintf(stderr, "%s: no space for device pointers\n",
  3389.             Pn);
  3390.         exit(1);
  3391.     }
  3392.     for (i = 0; i < Ndev; i++) {
  3393.         Sdev[i] = &Devtp[i];
  3394.     }
  3395.     (void) qsort((QSORT_P *)Sdev,(size_t)Ndev,(size_t)sizeof(struct dev *),
  3396.         compdev);
  3397. }
  3398.  
  3399.  
  3400. #if    defined(sun)
  3401. /*
  3402.  * readfifonode() - read fifonode
  3403.  */
  3404.  
  3405. int
  3406. readfifonode(fa, f)
  3407.     caddr_t fa;            /* fifonode kernel address */
  3408.     struct fifonode *f;        /* fifonode buffer */
  3409. {
  3410.     if (kread((off_t)fa, (char *)f, sizeof(struct fifonode))) {
  3411.         (void) sprintf(Namech, "can't read fifonode at %#x", fa);
  3412.         return(1);
  3413.     }
  3414.     return(0);
  3415. }
  3416. #endif
  3417.  
  3418.  
  3419. #if    defined(_IBMR2)
  3420. /*
  3421.  * readgnode() - read gnode
  3422.  */
  3423.  
  3424. int
  3425. readgnode(ga, g)
  3426.     caddr_t ga;            /* gnode kernel address */
  3427.     struct gnode *g;        /* gnode buffer */
  3428. {
  3429.     if (kread((off_t)ga, g, sizeof(struct gnode))) {
  3430.         (void) sprintf(Namech, "can't read gnode at %#x", ga);
  3431.         return(1);
  3432.     }
  3433.     return(0);
  3434. }
  3435. #endif
  3436.  
  3437.  
  3438. /*
  3439.  * readinode() - read inode
  3440.  */
  3441.  
  3442. int
  3443. readinode(ia, i)
  3444.     caddr_t ia;            /* inode kernel address */
  3445.     struct inode *i;        /* inode buffer */
  3446. {
  3447.     if (kread((off_t)ia, (char *)i, sizeof(struct inode))) {
  3448.         (void) sprintf(Namech, "can't read inode at %#x", ia);
  3449.         return(1);
  3450.     }
  3451.     return(0);
  3452. }
  3453.  
  3454.  
  3455. #if    defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun) 
  3456. /*
  3457.  * readmnt() - read mount table
  3458.  */
  3459.  
  3460. void
  3461. readmnt()
  3462. {
  3463.     int err = 0;
  3464.     FILE *mfp;
  3465.     struct mntent *mp;
  3466.     struct mounts *mtp;
  3467.     struct stat sb;
  3468.  
  3469.         if ((mfp = setmntent(MOUNTED, "r")) == NULL) {
  3470.                 (void) fprintf(stderr, "%s: can't access %s\n", Pn, MOUNTED);
  3471.                 exit(1);
  3472.         }
  3473.         while ((mp = getmntent(mfp)) != NULL) {
  3474.                 if (statsafely(mp->mnt_dir, &sb, STATTMO))
  3475.                         continue;
  3476.         if ((mtp = (struct mounts *)malloc(sizeof(struct mounts)))
  3477.         == NULL) {
  3478.             err = 1;
  3479.             break;
  3480.         }
  3481.         if ((mtp->dir = (char *)malloc(
  3482.                 (MALLOC_S)(strlen(mp->mnt_dir)+1)))
  3483.         == NULL) {
  3484.             err = 1;
  3485.             break;
  3486.         }
  3487.         (void) strcpy(mtp->dir, mp->mnt_dir);
  3488.         if ((mtp->fsname = (char *)malloc(
  3489.                    (MALLOC_S)(strlen(mp->mnt_fsname)+1)))
  3490.         == NULL) {
  3491.             err = 1;
  3492.             break;
  3493.         }
  3494.         (void) strcpy(mtp->fsname, mp->mnt_fsname);
  3495.         mtp->next = Mtab;
  3496.         mtp->dev = sb.st_dev;
  3497.         mtp->inode = sb.st_ino;
  3498.         mtp->mode = sb.st_mode;
  3499.         mtp->rdev = sb.st_rdev;
  3500.         Mtab = mtp;
  3501.         }
  3502.         (void) endmntent(mfp);
  3503.     if (err) {
  3504.         (void) fprintf(stderr, "%s: no space for mount at %s (%s)\n",
  3505.             Pn, mp->mnt_fsname, mp->mnt_dir);
  3506.         exit(1);
  3507.     }
  3508. }
  3509. #endif
  3510.  
  3511.  
  3512. #if    defined(_IBMR2)
  3513. /*
  3514.  * readmnt() - read mount table
  3515.  */
  3516.  
  3517. void
  3518. readmnt()
  3519. {
  3520.     int err = 0;
  3521.     char *dir, *fs, *h;
  3522.     int fsl;
  3523.     struct mounts *mtp;
  3524.     int nm;
  3525.     struct stat sb;
  3526.     unsigned sz;
  3527.     struct vmount *v, *vt;
  3528.  
  3529. /*
  3530.  * Read the table of vmount structures.
  3531.  */
  3532.     for (sz = sizeof(struct vmount);;) {
  3533.         if ((vt = (struct vmount *)malloc(sz)) == NULL) {
  3534.             (void) fprintf(stderr,
  3535.                 "%s: no space for vmount table\n", Pn);
  3536.             exit(1);
  3537.         }
  3538.         nm = mntctl(MCTL_QUERY, sz, vt);
  3539.         if (nm > 0) {
  3540.             if (vt->vmt_revision != VMT_REVISION) {
  3541.                 (void) fprintf(stderr,
  3542.                     "%s: stale file system, rev %d != %d\n",
  3543.                     Pn, vt->vmt_revision, VMT_REVISION);
  3544.                 exit(1);
  3545.             }
  3546.             break;
  3547.         }
  3548.         if (nm == 0) {
  3549.             sz = (unsigned)vt->vmt_revision;
  3550.             (void) free((FREE_P *)vt);
  3551.         } else {
  3552.             (void) fprintf(stderr, "%s: mntctl error: %s\n",
  3553.                 Pn, sys_errlist[errno]);
  3554.             exit(1);
  3555.         }
  3556.     }
  3557. /*
  3558.  * Scan the vmount structures and build Mtab.
  3559.  */
  3560.     for (v = vt; nm--; v = (struct vmount *)((char *)v + v->vmt_length)) {
  3561.         dir = (char *)vmt2dataptr(v, VMT_STUB);
  3562.         fs = (char *)vmt2dataptr(v, VMT_OBJECT);
  3563.         h = (char *)vmt2dataptr(v, VMT_HOST);
  3564.         fsl = strlen(fs);
  3565.         if (v->vmt_flags & MNT_REMOTE)
  3566.             fsl += strlen(h) + 1;
  3567.                 if (statsafely(dir, &sb, STATTMO))
  3568.                         continue;
  3569.         if ((mtp = (struct mounts *)malloc(sizeof(struct mounts)))
  3570.         == NULL) {
  3571.             err = 1;
  3572.             break;
  3573.         }
  3574.         if ((mtp->dir = (char *)malloc(strlen(dir) + 1)) == NULL) {
  3575.             err = 1;
  3576.             break;
  3577.         }
  3578.         (void) strcpy(mtp->dir, dir);
  3579.         if ((mtp->fsname = (char *)malloc(fsl + 1)) == NULL) {
  3580.             err = 1;
  3581.             break;
  3582.         }
  3583.         if (v->vmt_flags & MNT_REMOTE)
  3584.             (void) sprintf(mtp->fsname, "%s:%s", h, fs);
  3585.         else
  3586.             (void) strcpy(mtp->fsname, fs);
  3587.         mtp->dev = sb.st_dev;
  3588.         mtp->inode = sb.st_ino;
  3589.         mtp->mode = sb.st_mode;
  3590.         mtp->rdev = sb.st_rdev;
  3591.         mtp->next = Mtab;
  3592.         Mtab = mtp;
  3593.         }
  3594.     if (err) {
  3595.         (void) fprintf(stderr, "%s: no space for mount at %s (%s)\n",
  3596.             Pn, fs, dir);
  3597.         exit(1);
  3598.     }
  3599.     (void) free((FREE_P *)vt);
  3600. }
  3601. #endif
  3602.  
  3603.  
  3604. /*
  3605.  * readrnode() - read rnode
  3606.  */
  3607.  
  3608. int
  3609. readrnode(ra, r)
  3610.     caddr_t ra;            /* rnode kernel space address */
  3611.     struct rnode *r;        /* rnode buffer pointer */
  3612. {
  3613.     if (kread((off_t)ra, (char *)r, sizeof(struct rnode))) {
  3614.         (void) sprintf(Namech, "can't read rnode at %#x", ra);
  3615.         return(1);
  3616.     }
  3617.     return(0);
  3618. }
  3619.  
  3620.  
  3621. #if    defined(NeXT) || defined(sun)
  3622. /*
  3623.  * readsnode() - read snode
  3624.  */
  3625.  
  3626. int
  3627. readsnode(sa, s)
  3628.     caddr_t sa;            /* snode kernel space address */
  3629.     struct snode *s;        /* snode buffer pointer */
  3630. {
  3631.     if (kread((off_t)sa, (char *)s, sizeof(struct snode))) {
  3632.         (void) sprintf(Namech, "can't read snode at %#x", sa);
  3633.         return(1);
  3634.     }
  3635.     return(0);
  3636. }
  3637. #endif
  3638.  
  3639.  
  3640. #if    defined(sun)
  3641. /*
  3642.  * readtnode() - read tmpnode
  3643.  */
  3644.  
  3645. int
  3646. readtnode(ta, t)
  3647.     caddr_t ta;            /* tmpnode kernel space address */
  3648.     struct tmpnode *t;        /* tmpnode buffer pointer */
  3649. {
  3650.     if (kread((off_t)ta, (char *)t, sizeof(struct tmpnode))) {
  3651.         (void) sprintf(Namech, "can't read tmpnode at %#x", ta);
  3652.         return(1);
  3653.     }
  3654.     return(0);
  3655. }
  3656. #endif
  3657.  
  3658.  
  3659. /*
  3660.  * readvfs() - read vfs structure
  3661.  */
  3662.  
  3663. struct l_vfs *
  3664. readvfs(va)
  3665.     struct vfs *va;            /* vfs structure kernel address
  3666.                      * - e. g., v.v_vfsp */
  3667. {
  3668.     struct vfs v;
  3669.     struct l_vfs *vp;
  3670.  
  3671. #if    defined(DYNIX) ||defined(hpux) || defined(sun)
  3672.     struct mount m;
  3673. #endif
  3674.  
  3675. #if    defined(DYNIX) || defined(hpux)
  3676.     struct mntinfo mi;
  3677. #endif
  3678.  
  3679. #if    defined(_IBMR2)
  3680.     struct gfs g;
  3681.     void *mp;
  3682.     char *s1, *s2;
  3683.     unsigned slen;
  3684.     u_long ul;
  3685.     struct vmount *vm;
  3686. #endif
  3687.  
  3688.     for (vp = Lvfs; vp; vp = vp->next) {
  3689.         if (va == vp->addr)
  3690.             return(vp);
  3691.     }
  3692.     if ((vp = (struct l_vfs *)malloc(sizeof(struct l_vfs))) == NULL) {
  3693.         (void) fprintf(stderr, "%s: no space for vfs\n", Pn);
  3694.         exit(1);
  3695.     }
  3696.  
  3697. #if    defined(DYNIX) || defined(hpux)
  3698.     vp->dev = 0;
  3699. #endif
  3700.  
  3701.     vp->dir = NULL;
  3702.     vp->fsname = NULL;
  3703.  
  3704. #if    defined(sun)
  3705. /*
  3706.  * SunOS vnodes of type VCHR that have a non-null v_stream pointer
  3707.  * represent streams and have no virtual file system pointer.
  3708.  */
  3709.  
  3710. #endif
  3711.  
  3712. #if    defined(DYNIX) ||defined(hpux) || defined(_IBMR2) || defined(NeXT)
  3713.     if (!va)
  3714.         goto vfs_exit;
  3715. #endif
  3716.  
  3717.     if (va && kread((off_t)va, (char *)&v, sizeof(v))) {
  3718.  
  3719. #if    defined(DYNIX) || defined(hpux) || defined(_IBMR2) || defined(NeXT)
  3720.  
  3721. vfs_exit:
  3722.  
  3723. #endif
  3724.  
  3725.         (void) free((FREE_P *)vp);
  3726.         return(NULL);
  3727.     }
  3728.  
  3729. #if    defined(_IBMR2)
  3730. /*
  3731.  * Locate AIX mount information.
  3732.  */
  3733.     if (kread((off_t) v.vfs_gfs, &g, sizeof(g)))
  3734.         goto vfs_exit;
  3735.     if (kread((off_t) v.vfs_mdata + sizeof(u_long), &ul, sizeof(ul)))
  3736.         goto vfs_exit;
  3737.     if ((mp = malloc((size_t) ul)) == NULL) {
  3738.         (void) fprintf(stderr, "%s: no space for mount data\n", Pn);
  3739.         exit(1);
  3740.     }
  3741.     if (kread((off_t) v.vfs_mdata, mp, (int) ul)) {
  3742.         (void) free((FREE_P *)mp);
  3743.         goto vfs_exit;
  3744.     }
  3745.     vm = (struct vmount *)mp;
  3746.     vp->vmt_flags = vm->vmt_flags;
  3747.     vp->vmt_gfstype = vm->vmt_gfstype;
  3748.     vp->dev = (dev_t)vm->vmt_fsid.fsid_dev;
  3749.     if ((s1 = vmt2dataptr(vm, VMT_STUB)) != NULL) {
  3750.         if ((vp->dir = (char *)malloc(strlen(s1) + 1)) == NULL) {
  3751.  
  3752. readvfs_aix1:
  3753.             (void) fprintf(stderr, "%s: readvfs, no space\n", Pn);
  3754.             exit(1);
  3755.         }
  3756.         (void) strcpy(vp->dir, s1);
  3757.     } else
  3758.         vp->dir = NULL;
  3759.     s1 = vmt2dataptr(vm, VMT_HOST);
  3760.     if ((s2 = vmt2dataptr(vm, VMT_OBJECT)) == NULL || *s1 == '\0')
  3761.         s2 = g.gfs_name;
  3762.     if (s1 == NULL && s2 == NULL)
  3763.         vp->fsname = NULL;
  3764.     else {
  3765.         slen = s2 ? strlen(s2) : 0;
  3766.         if (vm->vmt_flags & MNT_REMOTE)
  3767.             slen += (s1 ? strlen(s1) : 0) + 1;
  3768.         if ((vp->fsname = (char *)malloc(slen + 1)) == NULL)
  3769.             goto readvfs_aix1;
  3770.         if (vm->vmt_flags & MNT_REMOTE)
  3771.             (void) sprintf(vp->fsname, "%s:%s",
  3772.                 s1 ? s1 : "", s2 ? s2 : "");
  3773.         else
  3774.             (void) strcpy(vp->fsname, s2 ? s2 : "");
  3775.     }
  3776.     (void) free((FREE_P *)mp);
  3777. #endif
  3778.  
  3779. /*
  3780.  * Complete DYNIX, HP-UX and SunOS mount information.
  3781.  */
  3782.  
  3783. #if    defined(DYNIX) || defined(hpux)
  3784.     if (Vtype == V_NFS) {
  3785.  
  3786.     /*
  3787.      * DYNIX and HP-UX NFS vnode device values have a major number of 255.
  3788.      * The minor number is a serial number found in the mntinfo
  3789.      * structure to which the virtual file system's vfs_data points.
  3790.      */ 
  3791.         if (v.vfs_data
  3792.         &&  kread((off_t)v.vfs_data, (char *)&mi, sizeof(mi)) == 0)
  3793.             (void) completevfs(vp, makedev(255, mi.mi_mntno));
  3794.     } else {
  3795.         if (kread((off_t)v.vfs_data, (char *)&m, sizeof(m)) == 0)
  3796.             (void) completevfs(vp, m.m_dev);
  3797.     }
  3798. #endif
  3799.  
  3800. #if    defined(sun)
  3801.     if (va && v.vfs_data && kread((off_t)v.vfs_data, (char *)&m, sizeof(m))
  3802.     == 0)
  3803.         (void) completevfs(vp, m.m_dev);
  3804. #endif
  3805.  
  3806.     vp->next = Lvfs;
  3807.     vp->addr = va;
  3808.     Lvfs = vp;
  3809.     return(vp);
  3810. }
  3811.  
  3812.  
  3813. /*
  3814.  * readvnode() - read vnode
  3815.  */
  3816.  
  3817. int
  3818. readvnode(va, v)
  3819.     caddr_t va;            /* vnode kernel space address */
  3820.     struct vnode *v;        /* vnode buffer pointer */
  3821. {
  3822.     if (kread((off_t)va, (char *)v, sizeof(struct vnode))) {
  3823.         (void) sprintf(Namech, "can't read vnode at %#x", va);
  3824.         return(1);
  3825.     }
  3826.     return(0);
  3827. }
  3828.  
  3829.  
  3830. /*
  3831.  * statsafely() - stat path safely (i. e., with timeout)
  3832.  */
  3833.  
  3834. statsafely(path, buf, tm)
  3835.         char *path;
  3836.         struct stat *buf;
  3837.         int tm;
  3838. {
  3839.         int err;
  3840.         static int sverr;
  3841.  
  3842.         if (tm == 0)
  3843.                 return(stat(path, buf));
  3844.         sverr = errno;
  3845.         if (setjmp(Tmo_jbuf)) {
  3846.                 (void) alarm(0);
  3847.                 (void) signal(SIGALRM, SIG_IGN);
  3848.                 errno = ETIMEDOUT;
  3849.                 return(-1);
  3850.         }
  3851.         (void) signal(SIGALRM, stattimeout);
  3852.         (void) alarm((unsigned)tm);
  3853.         err = stat(path, buf);
  3854.         if (err != 0)
  3855.                 sverr = errno;
  3856.         (void) alarm(0);
  3857.         (void) signal(SIGALRM, SIG_IGN);
  3858.         errno = sverr;
  3859.         return(err);
  3860. }
  3861.  
  3862.  
  3863. /*
  3864.  * stattimeout() - time out a stat() call
  3865.  */
  3866.  
  3867. #if    defined(DYNIX)
  3868. int
  3869. #endif
  3870.  
  3871. #if    defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
  3872. void
  3873. #endif
  3874.  
  3875. stattimeout()
  3876. {
  3877.         (void) alarm(0);
  3878.         (void) signal(SIGALRM, SIG_IGN);
  3879.         longjmp(Tmo_jbuf, 1);
  3880. }
  3881.  
  3882.  
  3883. /*
  3884.  * stkdir() - stack directory name
  3885.  */
  3886.  
  3887. void
  3888. stkdir(d, n, x, p)
  3889.     char ***d;        /* array of directory pointers */
  3890.     int *n;            /* number of pointers */
  3891.     int *x;            /* current index */
  3892.     char *p;        /* directory path */
  3893. {
  3894.     if (*d == NULL) {
  3895.  
  3896.     /*
  3897.      * Allocate first entry.
  3898.      */
  3899.         if ((*d = (char **)malloc(sizeof(char *))) == NULL) {
  3900.  
  3901. stkdir_nospace:
  3902.  
  3903.             (void) fprintf(stderr,
  3904.                 "%s: no space for directory stack at %s\n",
  3905.                 Pn, p);
  3906.             exit(1);
  3907.         }
  3908.         *n = 1;
  3909.         *x = 0;
  3910.     } else if (*x >= *n) {
  3911.  
  3912.     /*
  3913.      * Allocate additional space as required.
  3914.      */
  3915.         *n += 1;
  3916.         if ((*d = (char **)realloc((MALLOC_P *)*d,
  3917.                   (MALLOC_S)(*n * sizeof(char *))))
  3918.         == NULL)
  3919.             goto stkdir_nospace;
  3920.     }
  3921. /*
  3922.  * Allocate space for the name, copy it there and put its pointer on the stack.
  3923.  */
  3924.     if (((*d)[*x] = (char *)malloc((MALLOC_S)(strlen(p) + 1))) == NULL) {
  3925.         (void) fprintf(stderr, "%s: no space for %s\n", Pn, p);
  3926.         exit(1);
  3927.     }
  3928.     (void) strcpy((*d)[*x], p);
  3929.     *x += 1;
  3930. }
  3931.