4.4BSD snapshot (revision 8.1)
[unix-history] / usr / src / usr.sbin / pstat / pstat.c
index 87b4229..4b1d78f 100644 (file)
@@ -1,23 +1,21 @@
 /*-
 /*-
- * Copyright (c) 1980, 1991 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1980, 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.proprietary.c%
+ * %sccs.include.redist.c%
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1980, 1991 The Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1980, 1991, 1993\n\
      The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)pstat.c    5.39 (Berkeley) %G%";
+static char sccsid[] = "@(#)pstat.c    8.1 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
-#include <sys/user.h>
-#include <sys/proc.h>
 #include <sys/time.h>
 #include <sys/vnode.h>
 #include <sys/map.h>
 #include <sys/time.h>
 #include <sys/vnode.h>
 #include <sys/map.h>
@@ -31,83 +29,51 @@ static char sccsid[] = "@(#)pstat.c 5.39 (Berkeley) %G%";
 #undef NFS
 #include <sys/stat.h>
 #include <nfs/nfsnode.h>
 #undef NFS
 #include <sys/stat.h>
 #include <nfs/nfsnode.h>
-/* #include <nfs/nfsv2.h> */
-/* #include <nfs/nfs.h> */
 #include <sys/ioctl.h>
 #include <sys/tty.h>
 #include <sys/conf.h>
 
 #include <sys/sysctl.h>
 
 #include <sys/ioctl.h>
 #include <sys/tty.h>
 #include <sys/conf.h>
 
 #include <sys/sysctl.h>
 
-#include <nlist.h>
+#include <err.h>
 #include <kvm.h>
 #include <kvm.h>
-#include <stdio.h>
 #include <limits.h>
 #include <limits.h>
-#include "pathnames.h"
-
-#define mask(x)                (x&0377)
-#define        clear(x)        ((int)x &~ KERNBASE)
+#include <nlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 
-char   *nlistf = NULL;
-char   *memf   = NULL;
+#include "pathnames.h"
 
 struct nlist nl[] = {
 
 struct nlist nl[] = {
-#define        SWAPMAP 0
-       { "_swapmap" },
-#define        SNSWAPMAP 1
-       { "_nswapmap" },
-#define        SDMMIN  2
-       { "_dmmin" },
-#define        SDMMAX  3
-       { "_dmmax" },
-#define        SNSWDEV 4
-       { "_nswdev" },
-#define        SSWDEVT 5
-       { "_swdevt" },
-#define NLMANDATORY SSWDEVT    /* names up to here are mandatory */
+#define VM_SWAPMAP     0
+       { "_swapmap" }, /* list of free swap areas */
+#define VM_NSWAPMAP    1
+       { "_nswapmap" },/* size of the swap map */
+#define VM_SWDEVT      2
+       { "_swdevt" },  /* list of swap devices and sizes */
+#define VM_NSWAP       3
+       { "_nswap" },   /* size of largest swap device */
+#define VM_NSWDEV      4
+       { "_nswdev" },  /* number of swap devices */
+#define VM_DMMAX       5
+       { "_dmmax" },   /* maximum size of a swap block */
+#define V_NUMV         6
+       { "_numvnodes" },
+#define V_ROOTFS       7
+       { "_rootfs" },
+#define        FNL_NFILE       8
+       {"_nfiles"},
+#define FNL_MAXFILE    9
+       {"_maxfiles"},
+#define NLMANDATORY FNL_MAXFILE        /* names up to here are mandatory */
 #define        SCONS   NLMANDATORY + 1
        { "_cons" },
 #define        SPTY    NLMANDATORY + 2
        { "_pt_tty" },
 #define        SNPTY   NLMANDATORY + 3
        { "_npty" },
 #define        SCONS   NLMANDATORY + 1
        { "_cons" },
 #define        SPTY    NLMANDATORY + 2
        { "_pt_tty" },
 #define        SNPTY   NLMANDATORY + 3
        { "_npty" },
-#ifdef vax
-#define        SDZ     (SNPTY+1)
-       { "_dz_tty" },
-#define        SNDZ    (SNPTY+2)
-       { "_dz_cnt" },
-#define        SDMF    (SNPTY+3)
-       { "_dmf_tty" },
-#define        SNDMF   (SNPTY+4)
-       { "_ndmf" },
-#define        SDH     (SNPTY+5)
-       { "_dh11" },
-#define        SNDH    (SNPTY+6)
-       { "_ndh11" },
-#define        SDHU    (SNPTY+7)
-       { "_dhu_tty" },
-#define        SNDHU   (SNPTY+8)
-       { "_ndhu" },
-#define        SDMZ    (SNPTY+9)
-       { "_dmz_tty" },
-#define        SNDMZ   (SNPTY+10)
-       { "_ndmz" },
-#define        SQD     (SNPTY+11)
-       { "_qd_tty" },
-#define        SNQD    (SNPTY+12)
-       { "_nNQD" },
-#endif
-
-#ifdef tahoe
-#define        SVX     (SNPTY+1)
-       { "_vx_tty" },
-#define        SNVX    (SNPTY+2)
-       { "_nvx" },
-#define SMP    (SNPTY+3)
-       { "_mp_tty" },
-#define SNMP   (SNPTY+4)
-       { "_nmp" },
-#endif
 
 #ifdef hp300
 #define        SDCA    (SNPTY+1)
 
 #ifdef hp300
 #define        SDCA    (SNPTY+1)
@@ -127,139 +93,135 @@ struct nlist nl[] = {
 #define        SNITE   (SNPTY+8)
        { "_nite" },
 #endif
 #define        SNITE   (SNPTY+8)
        { "_nite" },
 #endif
+
+#ifdef mips
+#define SDC    (SNPTY+1)
+       { "_dc_tty" },
+#define SNDC   (SNPTY+2)
+       { "_dc_cnt" },
+#endif
+
        { "" }
 };
 
        { "" }
 };
 
-int    vnof;
-int    txtf;
-int    prcf;
-int    ttyf;
-int    usrf;
-int    upid;
-int    filf;
-int    swpf;
-int    totflg;
-char   partab[1];
-struct cdevsw  cdevsw[1];
-struct bdevsw  bdevsw[1];
-int    allflg;
-int    nflg;
-u_long getword();
-off_t  mkphys();
+int    usenumflag;
+int    totalflag;
+char   *nlistf = NULL;
+char   *memf   = NULL;
 kvm_t  *kd;
 
 kvm_t  *kd;
 
-#define V(x)   (u_long)(x)
+#define        SVAR(var) __STRING(var) /* to force expansion */
+#define        KGET(idx, var)                                                  \
+       KGET1(idx, &var, sizeof(var), SVAR(var))
+#define        KGET1(idx, p, s, msg)                                           \
+       KGET2(nl[idx].n_value, p, s, msg)
+#define        KGET2(addr, p, s, msg)                                          \
+       if (kvm_read(kd, (u_long)(addr), p, s) != s)                    \
+               warnx("cannot read %s: %s", msg, kvm_geterr(kd))
+#define        KGETRET(addr, p, s, msg)                                        \
+       if (kvm_read(kd, (u_long)(addr), p, s) != s) {                  \
+               warnx("cannot read %s: %s", msg, kvm_geterr(kd));       \
+               return (0);                                             \
+       }
 
 
+void   filemode __P((void));
+int    getfiles __P((char **, int *));
+struct mount *
+       getmnt __P((struct mount *));
+struct e_vnode *
+       kinfo_vnodes __P((int *));
+struct e_vnode *
+       loadvnodes __P((int *));
+void   mount_print __P((struct mount *));
+void   nfs_header __P((void));
+int    nfs_print __P((struct vnode *));
+void   swapmode __P((void));
+void   ttymode __P((void));
+void   ttyprt __P((struct tty *, int));
+void   ttytype __P((struct tty *, char *, int, int));
+void   ufs_header __P((void));
+int    ufs_print __P((struct vnode *));
+void   usage __P((void));
+void   vnode_header __P((void));
+void   vnode_print __P((struct vnode *, struct vnode *));
+void   vnodemode __P((void));
+
+int
 main(argc, argv)
        int argc;
        char *argv[];
 {
        extern char *optarg;
        extern int optind;
 main(argc, argv)
        int argc;
        char *argv[];
 {
        extern char *optarg;
        extern int optind;
-       int ch, ret;
+       int ch, i, quit, ret;
+       int fileflag, swapflag, ttyflag, vnodeflag;
        char buf[_POSIX2_LINE_MAX];
 
        char buf[_POSIX2_LINE_MAX];
 
-       while ((ch = getopt(argc, argv, "TafvikptU:sxnu")) != EOF)
+       fileflag = swapflag = ttyflag = vnodeflag = 0;
+       while ((ch = getopt(argc, argv, "TM:N:finstv")) != EOF)
                switch (ch) {
                switch (ch) {
-               case 'T':
-                       totflg++;
-                       break;
-               case 'a':
-                       allflg++;
-                       /*FALLTHROUGH*/
-               case 'p':
-                       prcf++;
-                       break;
                case 'f':
                case 'f':
-                       filf++;
+                       fileflag = 1;
                        break;
                        break;
-               case 'v':
-               case 'i':
-                       vnof++;
+               case 'M':
+                       memf = optarg;
                        break;
                        break;
-               case 't':
-                       ttyf++;
+               case 'N':
+                       nlistf = optarg;
                        break;
                        break;
-               case 'U':
-                       usrf++;
-                       sscanf(optarg, "%d", &upid);
+               case 'n':
+                       usenumflag = 1;
                        break;
                case 's':
                        break;
                case 's':
-                       swpf++;
+                       swapflag = 1;
                        break;
                        break;
-               case 'x':
-                       txtf++;
+               case 'T':
+                       totalflag = 1;
                        break;
                        break;
-               case 'n':
-                       nflg++;
+               case 't':
+                       ttyflag = 1;
+                       break;
+               case 'v':
+               case 'i':               /* Backward compatibility. */
+                       vnodeflag = 1;
                        break;
                        break;
-               case 'u':
-                       fprintf(stderr, "pstat: use [ -U pid ] for -u\n");
-                       exit(1);
-               case '?':
                default:
                        usage();
                }
        argc -= optind;
        argv += optind;
 
                default:
                        usage();
                }
        argc -= optind;
        argv += optind;
 
-       if (argc > 1)
-               memf = argv[1];
-       if (argc > 0)
-               nlistf = argv[0];
-
        /*
         * Discard setgid privileges if not the running kernel so that bad
         * guys can't print interesting stuff from kernel memory.
         */
        if (nlistf != NULL || memf != NULL)
        /*
         * Discard setgid privileges if not the running kernel so that bad
         * guys can't print interesting stuff from kernel memory.
         */
        if (nlistf != NULL || memf != NULL)
-               setgid(getgid());
+               (void)setgid(getgid());
 
 
-       if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == 0) {
-               error("kvm_openfiles: %s", buf);
-               exit(1);
-       }
+       if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == 0)
+               errx(1, "kvm_openfiles: %s", buf);
        if ((ret = kvm_nlist(kd, nl)) != 0) {
        if ((ret = kvm_nlist(kd, nl)) != 0) {
-               int i, quit = 0;
-
-               if (ret == -1) {
-                       error("kvm_nlist: %s", kvm_geterr(kd));
-                       exit(1);
-               }
-               for (i = 0; i <= NLMANDATORY; i++) {
+               if (ret == -1)
+                       errx(1, "kvm_nlist: %s", kvm_geterr(kd));
+               for (i = quit = 0; i <= NLMANDATORY; i++)
                        if (!nl[i].n_value) {
                                quit = 1;
                        if (!nl[i].n_value) {
                                quit = 1;
-                               error("undefined symbol: %s\n",
-                                       nl[i].n_name);
+                               warnx("undefined symbol: %s\n", nl[i].n_name);
                        }
                        }
-               }
                if (quit)
                        exit(1);
        }
                if (quit)
                        exit(1);
        }
-       if (!(filf | totflg | vnof | prcf | txtf | ttyf | usrf | swpf))
+       if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag))
                usage();
                usage();
-       if (filf||totflg)
-               dofile();
-       if (vnof||totflg)
-               dovnode();
-       if (prcf||totflg)
-               doproc();
-       if (txtf||totflg)
-               dotext();
-       if (ttyf)
-               dotty();
-       if (usrf)
-               dousr();
-       if (swpf||totflg)
-               doswap();
-}
-
-usage()
-{
-
-       fprintf(stderr,
-           "usage: pstat -[Tafiptsx] [-U [pid]] [system] [core]\n");
-       exit(1);
+       if (fileflag || totalflag)
+               filemode();
+       if (vnodeflag || totalflag)
+               vnodemode();
+       if (ttyflag)
+               ttymode();
+       if (swapflag || totalflag)
+               swapmode();
+       exit (0);
 }
 
 struct e_vnode {
 }
 
 struct e_vnode {
@@ -267,25 +229,25 @@ struct e_vnode {
        struct vnode vnode;
 };
 
        struct vnode vnode;
 };
 
-dovnode()
+void
+vnodemode()
 {
        register struct e_vnode *e_vnodebase, *endvnode, *evp;
        register struct vnode *vp;
 {
        register struct e_vnode *e_vnodebase, *endvnode, *evp;
        register struct vnode *vp;
-       register struct mount *maddr = NULL, *mp;
+       register struct mount *maddr, *mp;
        int numvnodes;
        int numvnodes;
-       struct e_vnode *loadvnodes();
-       struct mount *getmnt();
 
        e_vnodebase = loadvnodes(&numvnodes);
 
        e_vnodebase = loadvnodes(&numvnodes);
-       if (totflg) {
-               printf("%7d vnodes\n", numvnodes);
+       if (totalflag) {
+               (void)printf("%7d vnodes\n", numvnodes);
                return;
        }
        endvnode = e_vnodebase + numvnodes;
                return;
        }
        endvnode = e_vnodebase + numvnodes;
-       printf("%d active vnodes\n", numvnodes);
+       (void)printf("%d active vnodes\n", numvnodes);
 
 
 #define ST     mp->mnt_stat
 
 
 #define ST     mp->mnt_stat
+       maddr = NULL;
        for (evp = e_vnodebase; evp < endvnode; evp++) {
                vp = &evp->vnode;
                if (vp->v_mount != maddr) {
        for (evp = e_vnodebase; evp < endvnode; evp++) {
                vp = &evp->vnode;
                if (vp->v_mount != maddr) {
@@ -310,7 +272,7 @@ dovnode()
                        default:
                                break;
                        }
                        default:
                                break;
                        }
-                       printf("\n");
+                       (void)printf("\n");
                }
                vnode_print(evp->avnode, vp);
                switch(ST.f_type) {
                }
                vnode_print(evp->avnode, vp);
                switch(ST.f_type) {
@@ -326,23 +288,25 @@ dovnode()
                default:
                        break;
                }
                default:
                        break;
                }
-               printf("\n");
+               (void)printf("\n");
        }
        free(e_vnodebase);
 }
 
        }
        free(e_vnodebase);
 }
 
+void
 vnode_header()
 {
 vnode_header()
 {
-       printf("ADDR     TYP VFLAG  USE HOLD");
+       (void)printf("ADDR     TYP VFLAG  USE HOLD");
 }
 
 }
 
+void
 vnode_print(avnode, vp)
        struct vnode *avnode;
        struct vnode *vp;
 {
        char *type, flags[16]; 
        char *fp = flags;
 vnode_print(avnode, vp)
        struct vnode *avnode;
        struct vnode *vp;
 {
        char *type, flags[16]; 
        char *fp = flags;
-       register flag;
+       register int flag;
 
        /*
         * set type
 
        /*
         * set type
@@ -390,33 +354,27 @@ vnode_print(avnode, vp)
        if (flag == 0)
                *fp++ = '-';
        *fp = '\0';
        if (flag == 0)
                *fp++ = '-';
        *fp = '\0';
-       /*
-        * print it
-        */
-       printf("%8x %s %5s %4d %4d",
-               avnode, type, flags, vp->v_usecount, vp->v_holdcnt);
+       (void)printf("%8x %s %5s %4d %4d",
+           avnode, type, flags, vp->v_usecount, vp->v_holdcnt);
 }
 
 }
 
+void
 ufs_header() 
 {
 ufs_header() 
 {
-       printf(" FILEID IFLAG RDEV|SZ");
+       (void)printf(" FILEID IFLAG RDEV|SZ");
 }
 
 }
 
+int
 ufs_print(vp) 
        struct vnode *vp;
 {
 ufs_print(vp) 
        struct vnode *vp;
 {
+       register int flag;
        struct inode inode, *ip = &inode;
        char flagbuf[16], *flags = flagbuf;
        struct inode inode, *ip = &inode;
        char flagbuf[16], *flags = flagbuf;
-       register flag;
        char *name;
        mode_t type;
        char *name;
        mode_t type;
-       extern char *devname();
 
 
-       if (kvm_read(kd, V(VTOI(vp)), &inode, sizeof(struct inode)) != 
-           sizeof(struct inode)) {
-               error("can't read inode for %x", vp);
-               return;
-       }
+       KGETRET(VTOI(vp), &inode, sizeof(struct inode), "vnode's inode");
        flag = ip->i_flag;
        if (flag & ILOCKED)
                *flags++ = 'L';
        flag = ip->i_flag;
        if (flag & ILOCKED)
                *flags++ = 'L';
@@ -442,38 +400,36 @@ ufs_print(vp)
                *flags++ = '-';
        *flags = '\0';
 
                *flags++ = '-';
        *flags = '\0';
 
-       printf(" %6d %5s", ip->i_number, flagbuf);
+       (void)printf(" %6d %5s", ip->i_number, flagbuf);
        type = ip->i_mode & S_IFMT;
        type = ip->i_mode & S_IFMT;
-       if (type == S_IFCHR || type == S_IFBLK)
-               if (nflg || ((name = devname(ip->i_rdev, type)) == NULL))
-                       printf("   %2d,%-2d", 
-                               major(ip->i_rdev), minor(ip->i_rdev));
+       if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
+               if (usenumflag || ((name = devname(ip->i_rdev, type)) == NULL))
+                       (void)printf("   %2d,%-2d", 
+                           major(ip->i_rdev), minor(ip->i_rdev));
                else
                else
-                       printf(" %7s", name);
+                       (void)printf(" %7s", name);
        else
        else
-               printf(" %7qd", ip->i_size);
+               (void)printf(" %7qd", ip->i_size);
+       return (0);
 }
 
 }
 
+void
 nfs_header() 
 {
 nfs_header() 
 {
-       printf(" FILEID NFLAG RDEV|SZ");
+       (void)printf(" FILEID NFLAG RDEV|SZ");
 }
 
 }
 
+int
 nfs_print(vp) 
        struct vnode *vp;
 {
        struct nfsnode nfsnode, *np = &nfsnode;
        char flagbuf[16], *flags = flagbuf;
 nfs_print(vp) 
        struct vnode *vp;
 {
        struct nfsnode nfsnode, *np = &nfsnode;
        char flagbuf[16], *flags = flagbuf;
-       register flag;
+       register int flag;
        char *name;
        mode_t type;
        char *name;
        mode_t type;
-       extern char *devname();
 
 
-       if (kvm_read(kd, V(VTONFS(vp)), &nfsnode, sizeof(struct nfsnode)) != 
-           sizeof(struct nfsnode)) {
-               error("can't read nfsnode for %x", vp);
-               return;
-       }
+       KGETRET(VTONFS(vp), &nfsnode, sizeof(nfsnode), "vnode's nfsnode");
        flag = np->n_flag;
        if (flag & NFLUSHWANT)
                *flags++ = 'W';
        flag = np->n_flag;
        if (flag & NFLUSHWANT)
                *flags++ = 'W';
@@ -494,16 +450,17 @@ nfs_print(vp)
        *flags = '\0';
 
 #define VT     np->n_vattr
        *flags = '\0';
 
 #define VT     np->n_vattr
-       printf(" %6d %5s", VT.va_fileid, flagbuf);
+       (void)printf(" %6d %5s", VT.va_fileid, flagbuf);
        type = VT.va_mode & S_IFMT;
        type = VT.va_mode & S_IFMT;
-       if (type == S_IFCHR || type == S_IFBLK)
-               if (nflg || ((name = devname(VT.va_rdev, type)) == NULL))
-                       printf("   %2d,%-2d", 
-                               major(VT.va_rdev), minor(VT.va_rdev));
+       if (S_ISCHR(VT.va_mode) || S_ISBLK(VT.va_mode))
+               if (usenumflag || ((name = devname(VT.va_rdev, type)) == NULL))
+                       (void)printf("   %2d,%-2d", 
+                           major(VT.va_rdev), minor(VT.va_rdev));
                else
                else
-                       printf(" %7s", name);
+                       (void)printf(" %7s", name);
        else
        else
-               printf(" %7qd", np->n_size);
+               (void)printf(" %7qd", np->n_size);
+       return (0);
 }
        
 /*
 }
        
 /*
@@ -524,29 +481,24 @@ getmnt(maddr)
        for (mt = mhead; mt != NULL; mt = mt->next)
                if (maddr == mt->maddr)
                        return (&mt->mount);
        for (mt = mhead; mt != NULL; mt = mt->next)
                if (maddr == mt->maddr)
                        return (&mt->mount);
-       if ((mt = (struct mtab *)malloc(sizeof (struct mtab))) == NULL) {
-               error("out of memory");
-               exit(1);
-       }
-       if (kvm_read(kd, V(maddr), &mt->mount, sizeof(struct mount)) != 
-           sizeof(struct mount)) {
-               error("can't read mount table at %x", maddr);
-               return (NULL);
-       }
+       if ((mt = malloc(sizeof(struct mtab))) == NULL)
+               err(1, NULL);
+       KGETRET(maddr, &mt->mount, sizeof(struct mount), "mount table");
        mt->maddr = maddr;
        mt->next = mhead;
        mhead = mt;
        return (&mt->mount);
 }
 
        mt->maddr = maddr;
        mt->next = mhead;
        mhead = mt;
        return (&mt->mount);
 }
 
+void
 mount_print(mp)
        struct mount *mp;
 {
 mount_print(mp)
        struct mount *mp;
 {
-       char *type = "unknown";
-       register flags;
+       register int flags;
+       char *type;
 
 #define ST     mp->mnt_stat
 
 #define ST     mp->mnt_stat
-       printf("*** MOUNT ");
+       (void)printf("*** MOUNT ");
        switch (ST.f_type) {
        case MOUNT_NONE:
                type = "none";
        switch (ST.f_type) {
        case MOUNT_NONE:
                type = "none";
@@ -563,94 +515,97 @@ mount_print(mp)
        case MOUNT_PC:
                type = "pc";
                break;
        case MOUNT_PC:
                type = "pc";
                break;
+       default:
+               type = "unknown";
+               break;
        }
        }
-       printf("%s %s on %s", type, ST.f_mntfromname, ST.f_mntonname);
+       (void)printf("%s %s on %s", type, ST.f_mntfromname, ST.f_mntonname);
        if (flags = mp->mnt_flag) {
                char *comma = "(";
 
                putchar(' ');
                /* user visable flags */
                if (flags & MNT_RDONLY) {
        if (flags = mp->mnt_flag) {
                char *comma = "(";
 
                putchar(' ');
                /* user visable flags */
                if (flags & MNT_RDONLY) {
-                       printf("%srdonly", comma);
+                       (void)printf("%srdonly", comma);
                        flags &= ~MNT_RDONLY;
                        comma = ",";
                }
                if (flags & MNT_SYNCHRONOUS) {
                        flags &= ~MNT_RDONLY;
                        comma = ",";
                }
                if (flags & MNT_SYNCHRONOUS) {
-                       printf("%ssynchronous", comma);
+                       (void)printf("%ssynchronous", comma);
                        flags &= ~MNT_SYNCHRONOUS;
                        comma = ",";
                }
                if (flags & MNT_NOEXEC) {
                        flags &= ~MNT_SYNCHRONOUS;
                        comma = ",";
                }
                if (flags & MNT_NOEXEC) {
-                       printf("%snoexec", comma);
+                       (void)printf("%snoexec", comma);
                        flags &= ~MNT_NOEXEC;
                        comma = ",";
                }
                if (flags & MNT_NOSUID) {
                        flags &= ~MNT_NOEXEC;
                        comma = ",";
                }
                if (flags & MNT_NOSUID) {
-                       printf("%snosuid", comma);
+                       (void)printf("%snosuid", comma);
                        flags &= ~MNT_NOSUID;
                        comma = ",";
                }
                if (flags & MNT_NODEV) {
                        flags &= ~MNT_NOSUID;
                        comma = ",";
                }
                if (flags & MNT_NODEV) {
-                       printf("%snodev", comma);
+                       (void)printf("%snodev", comma);
                        flags &= ~MNT_NODEV;
                        comma = ",";
                }
                if (flags & MNT_EXPORTED) {
                        flags &= ~MNT_NODEV;
                        comma = ",";
                }
                if (flags & MNT_EXPORTED) {
-                       printf("%sexport", comma);
+                       (void)printf("%sexport", comma);
                        flags &= ~MNT_EXPORTED;
                        comma = ",";
                }
                if (flags & MNT_EXRDONLY) {
                        flags &= ~MNT_EXPORTED;
                        comma = ",";
                }
                if (flags & MNT_EXRDONLY) {
-                       printf("%sexrdonly", comma);
+                       (void)printf("%sexrdonly", comma);
                        flags &= ~MNT_EXRDONLY;
                        comma = ",";
                }
                if (flags & MNT_LOCAL) {
                        flags &= ~MNT_EXRDONLY;
                        comma = ",";
                }
                if (flags & MNT_LOCAL) {
-                       printf("%slocal", comma);
+                       (void)printf("%slocal", comma);
                        flags &= ~MNT_LOCAL;
                        comma = ",";
                }
                if (flags & MNT_QUOTA) {
                        flags &= ~MNT_LOCAL;
                        comma = ",";
                }
                if (flags & MNT_QUOTA) {
-                       printf("%squota", comma);
+                       (void)printf("%squota", comma);
                        flags &= ~MNT_QUOTA;
                        comma = ",";
                }
                /* filesystem control flags */
                if (flags & MNT_UPDATE) {
                        flags &= ~MNT_QUOTA;
                        comma = ",";
                }
                /* filesystem control flags */
                if (flags & MNT_UPDATE) {
-                       printf("%supdate", comma);
+                       (void)printf("%supdate", comma);
                        flags &= ~MNT_UPDATE;
                        comma = ",";
                }
                if (flags & MNT_MLOCK) {
                        flags &= ~MNT_UPDATE;
                        comma = ",";
                }
                if (flags & MNT_MLOCK) {
-                       printf("%slock", comma);
+                       (void)printf("%slock", comma);
                        flags &= ~MNT_MLOCK;
                        comma = ",";
                }
                if (flags & MNT_MWAIT) {
                        flags &= ~MNT_MLOCK;
                        comma = ",";
                }
                if (flags & MNT_MWAIT) {
-                       printf("%swait", comma);
+                       (void)printf("%swait", comma);
                        flags &= ~MNT_MWAIT;
                        comma = ",";
                }
                if (flags & MNT_MPBUSY) {
                        flags &= ~MNT_MWAIT;
                        comma = ",";
                }
                if (flags & MNT_MPBUSY) {
-                       printf("%sbusy", comma);
+                       (void)printf("%sbusy", comma);
                        flags &= ~MNT_MPBUSY;
                        comma = ",";
                }
                if (flags & MNT_MPWANT) {
                        flags &= ~MNT_MPBUSY;
                        comma = ",";
                }
                if (flags & MNT_MPWANT) {
-                       printf("%swant", comma);
+                       (void)printf("%swant", comma);
                        flags &= ~MNT_MPWANT;
                        comma = ",";
                }
                if (flags & MNT_UNMOUNT) {
                        flags &= ~MNT_MPWANT;
                        comma = ",";
                }
                if (flags & MNT_UNMOUNT) {
-                       printf("%sunmount", comma);
+                       (void)printf("%sunmount", comma);
                        flags &= ~MNT_UNMOUNT;
                        comma = ",";
                }
                if (flags)
                        flags &= ~MNT_UNMOUNT;
                        comma = ",";
                }
                if (flags)
-                       printf("%sunknown_flags:%x", flags);
-               printf(")");
+                       (void)printf("%sunknown_flags:%x", comma, flags);
+               (void)printf(")");
        }
        }
-       printf("\n");
+       (void)printf("\n");
 #undef ST
 }
 
 #undef ST
 }
 
@@ -661,7 +616,6 @@ loadvnodes(avnodes)
        int mib[2];
        size_t copysize;
        struct e_vnode *vnodebase;
        int mib[2];
        size_t copysize;
        struct e_vnode *vnodebase;
-       struct e_vnode *kinfo_vnodes();
 
        if (memf != NULL) {
                /*
 
        if (memf != NULL) {
                /*
@@ -671,23 +625,15 @@ loadvnodes(avnodes)
        }
        mib[0] = CTL_KERN;
        mib[1] = KERN_VNODE;
        }
        mib[0] = CTL_KERN;
        mib[1] = KERN_VNODE;
-       if (sysctl(mib, 2, NULL, &copysize, NULL, 0) == -1) {
-               syserror("can't get estimate from sysctl");
-               exit(1);
-       }
-       if ((vnodebase = (struct e_vnode *)malloc(copysize)) == NULL) {
-               error("out of memory");
-               exit(1);
-       }
-       if (sysctl(mib, 2, vnodebase, &copysize, NULL, 0) == -1) {
-               syserror("can't get vnode list");
-               exit(1);
-       }
-       if (copysize % sizeof (struct e_vnode)) {
-               error("vnode size mismatch");
-               exit(1);
-       }
-       *avnodes = copysize / sizeof (struct e_vnode);
+       if (sysctl(mib, 2, NULL, &copysize, NULL, 0) == -1)
+               err(1, "sysctl: KERN_VNODE");
+       if ((vnodebase = malloc(copysize)) == NULL)
+               err(1, NULL);
+       if (sysctl(mib, 2, vnodebase, &copysize, NULL, 0) == -1)
+               err(1, "sysctl: KERN_VNODE");
+       if (copysize % sizeof(struct e_vnode))
+               errx(1, "vnode size mismatch");
+       *avnodes = copysize / sizeof(struct e_vnode);
 
        return (vnodebase);
 }
 
        return (vnodebase);
 }
@@ -699,48 +645,32 @@ struct e_vnode *
 kinfo_vnodes(avnodes)
        int *avnodes;
 {
 kinfo_vnodes(avnodes)
        int *avnodes;
 {
-       struct nlist vnl[] = {
-#define V_NUMV 0
-               { "_numvnodes" },
-#define V_ROOTFS 1
-               { "_rootfs" },
-               {""}
-       };
        int numvnodes;
        struct mount *rootfs, *mp, mount;
        char *vbuf, *evbuf, *bp;
        struct vnode *vp, vnode;
        int num;
 
        int numvnodes;
        struct mount *rootfs, *mp, mount;
        char *vbuf, *evbuf, *bp;
        struct vnode *vp, vnode;
        int num;
 
-#define VPTRSZ  sizeof (struct vnode *)
-#define VNODESZ sizeof (struct vnode)
-#define NVAL(indx)     vnl[(indx)].n_value
+#define VPTRSZ  sizeof(struct vnode *)
+#define VNODESZ sizeof(struct vnode)
 
 
-       if (kvm_nlist(kd, vnl) != 0) {
-               error("nlist vnl: %s", kvm_geterr(kd));
-               exit(1);
-       }
-       numvnodes = getword(NVAL(V_NUMV));
-       if ((vbuf = (char *)malloc((numvnodes + 20) * (VPTRSZ + VNODESZ))) 
-           == NULL) {
-               error("out of memory");
-               exit(1);
-       }
+       KGET(V_NUMV, numvnodes);
+       if ((vbuf = malloc((numvnodes + 20) * (VPTRSZ + VNODESZ))) == NULL)
+               err(1, NULL);
        bp = vbuf;
        evbuf = vbuf + (numvnodes + 20) * (VPTRSZ + VNODESZ);
        bp = vbuf;
        evbuf = vbuf + (numvnodes + 20) * (VPTRSZ + VNODESZ);
-       mp = rootfs = (struct mount *)getword(NVAL(V_ROOTFS));
+       KGET(V_ROOTFS, rootfs);
+       mp = rootfs;
        do {
        do {
-               kvm_read(kd, V(mp), &mount, sizeof(mount));
+               KGET2(mp, &mount, sizeof(mount), "mount entry");
                for (vp = mount.mnt_mounth; vp; vp = vnode.v_mountf) {
                for (vp = mount.mnt_mounth; vp; vp = vnode.v_mountf) {
-                       kvm_read(kd, V(vp), &vnode, sizeof (vnode));
-                       if ((bp + VPTRSZ + VNODESZ) > evbuf) {
+                       KGET2(vp, &vnode, sizeof(vnode), "vnode");
+                       if ((bp + VPTRSZ + VNODESZ) > evbuf)
                                /* XXX - should realloc */
                                /* XXX - should realloc */
-                               fprintf(stderr, "pstat: ran out of room for vnodes\n");
-                               exit(1);
-                       }
-                       bcopy(&vp, bp, VPTRSZ);
+                               errx(1, "no more room for vnodes");
+                       memmove(bp, &vp, VPTRSZ);
                        bp += VPTRSZ;
                        bp += VPTRSZ;
-                       bcopy(&vnode, bp, VNODESZ);
+                       memmove(bp, &vnode, VNODESZ);
                        bp += VNODESZ;
                        num++;
                }
                        bp += VNODESZ;
                        num++;
                }
@@ -750,128 +680,80 @@ kinfo_vnodes(avnodes)
        return ((struct e_vnode *)vbuf);
 }
        
        return ((struct e_vnode *)vbuf);
 }
        
-       
-u_long
-getword(loc)
-       int loc;
-{
-       u_long word;
-
-       kvm_read(kd, V(loc), &word, sizeof (word));
-       return (word);
-}
-
-putf(v, n)
-{
-       if (v)
-               printf("%c", n);
-       else
-               printf(" ");
-}
-
-dotext()
-{
-
-       printf("no text table in this system\n");
-}
-
-doproc()
-{
-       if (!totflg)
-               printf("pstat: -p no longer supported (use ps)\n");
-}
-
-char mesg[] = "  LINE RAW CAN OUT  HWT LWT     ADDR COL STATE  SESS  PGID DISC\n";
+char hdr[]="  LINE RAW CAN OUT  HWT LWT     ADDR COL STATE  SESS  PGID DISC\n";
 int ttyspace = 128;
 int ttyspace = 128;
-struct tty *tty;
 
 
-dotty()
+void
+ttymode()
 {
 {
+       struct tty *tty;
 
 
-       if ((tty = (struct tty *)malloc(ttyspace * sizeof(*tty))) == 0) {
-               printf("pstat: out of memory\n");
-               return;
-       }
+       if ((tty = malloc(ttyspace * sizeof(*tty))) == NULL)
+               err(1, NULL);
 #ifndef hp300
 #ifndef hp300
-       printf("1 cons\n");
-       kvm_read(kd, V(nl[SCONS].n_value), tty, sizeof(*tty));
-       printf(mesg);
+       (void)printf("1 console\n");
+       KGET(SCONS, *tty);
+       (void)printf(hdr);
        ttyprt(&tty[0], 0);
 #endif
 #ifdef vax
        if (nl[SNQD].n_type != 0) 
        ttyprt(&tty[0], 0);
 #endif
 #ifdef vax
        if (nl[SNQD].n_type != 0) 
-               doqdss();
+               qdss();
        if (nl[SNDZ].n_type != 0)
        if (nl[SNDZ].n_type != 0)
-               dottytype("dz", SDZ, SNDZ);
+               ttytype(tty, "dz", SDZ, SNDZ);
        if (nl[SNDH].n_type != 0)
        if (nl[SNDH].n_type != 0)
-               dottytype("dh", SDH, SNDH);
+               ttytype(tty, "dh", SDH, SNDH);
        if (nl[SNDMF].n_type != 0)
        if (nl[SNDMF].n_type != 0)
-               dottytype("dmf", SDMF, SNDMF);
+               ttytype(tty, "dmf", SDMF, SNDMF);
        if (nl[SNDHU].n_type != 0)
        if (nl[SNDHU].n_type != 0)
-               dottytype("dhu", SDHU, SNDHU);
+               ttytype(tty, "dhu", SDHU, SNDHU);
        if (nl[SNDMZ].n_type != 0)
        if (nl[SNDMZ].n_type != 0)
-               dottytype("dmz", SDMZ, SNDMZ);
+               ttytype(tty, "dmz", SDMZ, SNDMZ);
 #endif
 #ifdef tahoe
        if (nl[SNVX].n_type != 0)
 #endif
 #ifdef tahoe
        if (nl[SNVX].n_type != 0)
-               dottytype("vx", SVX, SNVX);
+               ttytype(tty, "vx", SVX, SNVX);
        if (nl[SNMP].n_type != 0)
        if (nl[SNMP].n_type != 0)
-               dottytype("mp", SMP, SNMP);
+               ttytype(tty, "mp", SMP, SNMP);
 #endif
 #ifdef hp300
        if (nl[SNITE].n_type != 0)
 #endif
 #ifdef hp300
        if (nl[SNITE].n_type != 0)
-               dottytype("ite", SITE, SNITE);
+               ttytype(tty, "ite", SITE, SNITE);
        if (nl[SNDCA].n_type != 0)
        if (nl[SNDCA].n_type != 0)
-               dottytype("dca", SDCA, SNDCA);
+               ttytype(tty, "dca", SDCA, SNDCA);
        if (nl[SNDCM].n_type != 0)
        if (nl[SNDCM].n_type != 0)
-               dottytype("dcm", SDCM, SNDCM);
+               ttytype(tty, "dcm", SDCM, SNDCM);
        if (nl[SNDCL].n_type != 0)
        if (nl[SNDCL].n_type != 0)
-               dottytype("dcl", SDCL, SNDCL);
+               ttytype(tty, "dcl", SDCL, SNDCL);
+#endif
+#ifdef mips
+       if (nl[SNDC].n_type != 0)
+               ttytype(tty, "dc", SDC, SNDC);
 #endif
        if (nl[SNPTY].n_type != 0)
 #endif
        if (nl[SNPTY].n_type != 0)
-               dottytype("pty", SPTY, SNPTY);
+               ttytype(tty, "pty", SPTY, SNPTY);
 }
 
 }
 
-/* 
- * Special case the qdss: there are 4 ttys per qdss,
- * but only the first of each is used as a tty.  
- */
-#ifdef vax
-doqdss()
+void
+ttytype(tty, name, type, number)
+       register struct tty *tty;
+       char *name;
+       int type, number;
 {
 {
-       int nqd;
        register struct tty *tp;
        register struct tty *tp;
-
-       kvm_read(kd, V(nl[SNQD].n_value), &nqd, sizeof(nqd));
-       printf("%d qd\n", nqd);
-       kvm_read(kd, V(nl[SQD].n_value), tty, nqd * sizeof(struct tty) * 4);
-       printf(mesg);
-       for (tp = tty; tp < &tty[nqd * 4]; tp += 4)
-               ttyprt(tp, tp - tty);
-}
-#endif
-
-dottytype(name, type, number)
-char *name;
-{
        int ntty;
        int ntty;
-       register struct tty *tp;
-       extern char *realloc();
 
 
-       if (tty == (struct tty *)0) 
+       if (tty == NULL)
                return;
                return;
-       kvm_read(kd, V(nl[number].n_value), &ntty, sizeof(ntty));
-       printf("%d %s %s\n", ntty, name, (ntty == 1) ? "line" :
-           "lines");
+       KGET(number, ntty);
+       (void)printf("%d %s %s\n", ntty, name, (ntty == 1) ? "line" : "lines");
        if (ntty > ttyspace) {
                ttyspace = ntty;
        if (ntty > ttyspace) {
                ttyspace = ntty;
-               if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) {
-                       printf("pstat: out of memory\n");
-                       return;
-               }
+               if ((tty = realloc(tty, ttyspace * sizeof(*tty))) == 0)
+                       err(1, NULL);
        }
        }
-       kvm_read(kd, V(nl[type].n_value), tty, ntty * sizeof(struct tty));
-       printf(mesg);
+       KGET1(type, tty, ntty * sizeof(struct tty), "tty structs");
+       (void)printf(hdr);
        for (tp = tty; tp < &tty[ntty]; tp++)
                ttyprt(tp, tp - tty);
 }
        for (tp = tty; tp < &tty[ntty]; tp++)
                ttyprt(tp, tp - tty);
 }
@@ -880,43 +762,41 @@ struct {
        int flag;
        char val;
 } ttystates[] = {
        int flag;
        char val;
 } ttystates[] = {
-       TS_WOPEN,       'W',
-       TS_ISOPEN,      'O',
-       TS_CARR_ON,     'C',
-       TS_TIMEOUT,     'T',
-       TS_FLUSH,       'F',
-       TS_BUSY,        'B',
-       TS_ASLEEP,      'A',
-       TS_XCLUDE,      'X',
-       TS_TTSTOP,      'S',
-       TS_TBLOCK,      'K',
-       TS_ASYNC,       'Y',
-       TS_BKSL,        'D',
-       TS_ERASE,       'E',
-       TS_LNCH,        'L',
-       TS_TYPEN,       'P',
-       TS_CNTTB,       'N',
-       0,      0
+       { TS_WOPEN,     'W'},
+       { TS_ISOPEN,    'O'},
+       { TS_CARR_ON,   'C'},
+       { TS_TIMEOUT,   'T'},
+       { TS_FLUSH,     'F'},
+       { TS_BUSY,      'B'},
+       { TS_ASLEEP,    'A'},
+       { TS_XCLUDE,    'X'},
+       { TS_TTSTOP,    'S'},
+       { TS_TBLOCK,    'K'},
+       { TS_ASYNC,     'Y'},
+       { TS_BKSL,      'D'},
+       { TS_ERASE,     'E'},
+       { TS_LNCH,      'L'},
+       { TS_TYPEN,     'P'},
+       { TS_CNTTB,     'N'},
+       { 0,           '\0'},
 };
 
 };
 
-ttyprt(atp, line)
-struct tty *atp;
-{
+void
+ttyprt(tp, line)
        register struct tty *tp;
        register struct tty *tp;
-       char state[20];
-       register i, j;
-       char *name;
-       extern char *devname();
+       int line;
+{
+       register int i, j;
        pid_t pgid;
        pid_t pgid;
+       char *name, state[20];
 
 
-       tp = atp;
-       if (nflg || tp->t_dev == 0 ||
+       if (usenumflag || tp->t_dev == 0 ||
           (name = devname(tp->t_dev, S_IFCHR)) == NULL)
           (name = devname(tp->t_dev, S_IFCHR)) == NULL)
-               printf("%7d ", line); 
+               (void)printf("%7d ", line); 
        else
        else
-               printf("%7s ", name);
-       printf("%2d %3d ", tp->t_rawq.c_cc, tp->t_canq.c_cc);
-       printf("%3d %4d %3d %8x %3d ", tp->t_outq.c_cc, 
+               (void)printf("%7s ", name);
+       (void)printf("%2d %3d ", tp->t_rawq.c_cc, tp->t_canq.c_cc);
+       (void)printf("%3d %4d %3d %8x %3d ", tp->t_outq.c_cc, 
                tp->t_hiwat, tp->t_lowat, tp->t_addr, tp->t_col);
        for (i = j = 0; ttystates[i].flag; i++)
                if (tp->t_state&ttystates[i].flag)
                tp->t_hiwat, tp->t_lowat, tp->t_addr, tp->t_col);
        for (i = j = 0; ttystates[i].flag; i++)
                if (tp->t_state&ttystates[i].flag)
@@ -924,145 +804,113 @@ struct tty *atp;
        if (j == 0)
                state[j++] = '-';
        state[j] = '\0';
        if (j == 0)
                state[j++] = '-';
        state[j] = '\0';
-       printf("%-4s %6x", state, (u_long)tp->t_session & ~KERNBASE);
-       if (tp->t_pgrp == NULL || kvm_read(kd, V(&tp->t_pgrp->pg_id), &pgid, 
-           sizeof (pid_t)) != sizeof (pid_t))
-               pgid = 0;
-       printf("%6d ", pgid);
+       (void)printf("%-4s %6x", state, (u_long)tp->t_session & ~KERNBASE);
+       pgid = 0;
+       if (tp->t_pgrp != NULL)
+               KGET2(&tp->t_pgrp->pg_id, &pgid, sizeof(pid_t), "pgid");
+       (void)printf("%6d ", pgid);
        switch (tp->t_line) {
        switch (tp->t_line) {
-
        case TTYDISC:
        case TTYDISC:
-               printf("term\n");
+               (void)printf("term\n");
                break;
                break;
-
        case TABLDISC:
        case TABLDISC:
-               printf("tab\n");
+               (void)printf("tab\n");
                break;
                break;
-
        case SLIPDISC:
        case SLIPDISC:
-               printf("slip\n");
+               (void)printf("slip\n");
                break;
                break;
-
        default:
        default:
-               printf("%d\n", tp->t_line);
+               (void)printf("%d\n", tp->t_line);
+               break;
        }
 }
 
        }
 }
 
-/*
- * The user structure is going away.  What's left here won't
- * be around for long.
- */
-dousr()
-{
-
-       printf("nothing left in user structure in this system\n");
-}
-
-oatoi(s)
-char *s;
-{
-       register v;
-
-       v = 0;
-       while (*s)
-               v = (v<<3) + *s++ - '0';
-       return(v);
-}
-
-dofile()
+void
+filemode()
 {
        register struct file *fp;
        struct file *addr;
 {
        register struct file *fp;
        struct file *addr;
-       char *buf;
+       char *buf, flagbuf[16], *fbp;
        int len, maxfile, nfile;
        int len, maxfile, nfile;
-       struct nlist fnl[] = {
-#define        FNL_NFILE       0
-               {"_nfiles"},
-#define FNL_MAXFILE    1
-               {"_maxfiles"},
-               {""}
-       };
        static char *dtypes[] = { "???", "inode", "socket" };
 
        static char *dtypes[] = { "???", "inode", "socket" };
 
-       if (kvm_nlist(kd, fnl) != 0) {
-               error("kvm_nlist: no _nfiles or _maxfiles: %s", 
-                       kvm_geterr(kd));
-               return;
-       }
-       kvm_read(kd, V(fnl[FNL_MAXFILE].n_value), &maxfile,
-               sizeof (maxfile));
-       if (totflg) {
-               kvm_read(kd, V(fnl[FNL_NFILE].n_value), &nfile, sizeof (nfile));
-               printf("%3d/%3d files\n", nfile, maxfile);
+       KGET(FNL_MAXFILE, maxfile);
+       if (totalflag) {
+               KGET(FNL_NFILE, nfile);
+               (void)printf("%3d/%3d files\n", nfile, maxfile);
                return;
        }
        if (getfiles(&buf, &len) == -1)
                return;
        /*
                return;
        }
        if (getfiles(&buf, &len) == -1)
                return;
        /*
-        * getfiles returns in malloc'd buf a pointer to the first file
-        * structure, and then an array of file structs (whose
-        * addresses are derivable from the previous entry)
+        * Getfiles returns in malloc'd memory a pointer to the first file
+        * structure, and then an array of file structs (whose addresses are
+        * derivable from the previous entry).
         */
        addr = *((struct file **)buf);
         */
        addr = *((struct file **)buf);
-       fp = (struct file *)(buf + sizeof (struct file *));
-       nfile = (len - sizeof (struct file *)) / sizeof (struct file);
+       fp = (struct file *)(buf + sizeof(struct file *));
+       nfile = (len - sizeof(struct file *)) / sizeof(struct file);
        
        
-       printf("%d/%d open files\n", nfile, maxfile);
-       printf("   LOC   TYPE    FLG     CNT  MSG    DATA    OFFSET\n");
+       (void)printf("%d/%d open files\n", nfile, maxfile);
+       (void)printf("   LOC   TYPE    FLG     CNT  MSG    DATA    OFFSET\n");
        for (; (char *)fp < buf + len; addr = fp->f_filef, fp++) {
                if ((unsigned)fp->f_type > DTYPE_SOCKET)
                        continue;
        for (; (char *)fp < buf + len; addr = fp->f_filef, fp++) {
                if ((unsigned)fp->f_type > DTYPE_SOCKET)
                        continue;
-               printf("%x ", addr);
-               printf("%-8.8s", dtypes[fp->f_type]);
-               putf(fp->f_flag&FREAD, 'R');
-               putf(fp->f_flag&FWRITE, 'W');
-               putf(fp->f_flag&FAPPEND, 'A');
+               (void)printf("%x ", addr);
+               (void)printf("%-8.8s", dtypes[fp->f_type]);
+               fbp = flagbuf;
+               if (fp->f_flag & FREAD)
+                       *fbp++ = 'R';
+               if (fp->f_flag & FWRITE)
+                       *fbp++ = 'W';
+               if (fp->f_flag & FAPPEND)
+                       *fbp++ = 'A';
 #ifdef FSHLOCK /* currently gone */
 #ifdef FSHLOCK /* currently gone */
-               putf(fp->f_flag&FSHLOCK, 'S');
-               putf(fp->f_flag&FEXLOCK, 'X');
-#else
-               putf(0, ' ');
-               putf(0, ' ');
+               if (fp->f_flag & FSHLOCK)
+                       *fbp++ = 'S';
+               if (fp->f_flag & FEXLOCK)
+                       *fbp++ = 'X';
 #endif
 #endif
-               putf(fp->f_flag&FASYNC, 'I');
-               printf("  %3d", fp->f_count);
-               printf("  %3d", fp->f_msgcount);
-               printf("  %8.1x", fp->f_data);
+               if (fp->f_flag & FASYNC)
+                       *fbp++ = 'I';
+               *fbp = '\0';
+               (void)printf("%6s  %3d", flagbuf, fp->f_count);
+               (void)printf("  %3d", fp->f_msgcount);
+               (void)printf("  %8.1x", fp->f_data);
                if (fp->f_offset < 0)
                if (fp->f_offset < 0)
-                       printf("  %x\n", fp->f_offset);
+                       (void)printf("  %qx\n", fp->f_offset);
                else
                else
-                       printf("  %ld\n", fp->f_offset);
+                       (void)printf("  %qd\n", fp->f_offset);
        }
        free(buf);
 }
 
        }
        free(buf);
 }
 
+int
 getfiles(abuf, alen)
        char **abuf;
        int *alen;
 {
 getfiles(abuf, alen)
        char **abuf;
        int *alen;
 {
-       char *buf;
-       int mib[2];
        size_t len;
        size_t len;
+       int mib[2];
+       char *buf;
+
+       /*
+        * XXX
+        * Add emulation of KINFO_FILE here.
+        */
+       if (memf != NULL)
+               errx(1, "files on dead kernel, not implemented\n");
 
 
-       if (memf != NULL) {
-               /*
-                * add emulation of KINFO_FILE here
-                */
-               error("files on dead kernel, not impl\n");
-               exit(1);
-       }
        mib[0] = CTL_KERN;
        mib[1] = KERN_FILE;
        if (sysctl(mib, 2, NULL, &len, NULL, 0) == -1) {
        mib[0] = CTL_KERN;
        mib[1] = KERN_FILE;
        if (sysctl(mib, 2, NULL, &len, NULL, 0) == -1) {
-               syserror("sysctl size estimate");
-               return (-1);
-       }
-       if ((buf = (char *)malloc(len)) == NULL) {
-               error("out of memory");
+               warn("sysctl: KERN_FILE");
                return (-1);
        }
                return (-1);
        }
+       if ((buf = malloc(len)) == NULL)
+               err(1, NULL);
        if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) {
        if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) {
-               syserror("sysctl");
+               warn("sysctl: KERN_FILE");
                return (-1);
        }
        *abuf = buf;
                return (-1);
        }
        *abuf = buf;
@@ -1070,40 +918,126 @@ getfiles(abuf, alen)
        return (0);
 }
 
        return (0);
 }
 
-
-doswap()
+/*
+ * swapmode is based on a program called swapinfo written
+ * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
+ */
+void
+swapmode()
 {
 {
-       printf("swap statistics not yet supported in this system\n");
-}
+       char *header;
+       int hlen, nswap, nswdev, dmmax, nswapmap;
+       int s, e, div, i, avail, nfree, npfree, used;
+       struct swdevt *sw;
+       long blocksize, *perdev;
+       struct map *swapmap, *kswapmap;
+       struct mapent *mp;
+
+       KGET(VM_NSWAP, nswap);
+       KGET(VM_NSWDEV, nswdev);
+       KGET(VM_DMMAX, dmmax);
+       KGET(VM_NSWAPMAP, nswapmap);
+       KGET(VM_SWAPMAP, kswapmap);     /* kernel `swapmap' is a pointer */
+       if ((sw = malloc(nswdev * sizeof(*sw))) == NULL ||
+           (perdev = malloc(nswdev * sizeof(*perdev))) == NULL ||
+           (mp = malloc(nswapmap * sizeof(*mp))) == NULL)
+               err(1, "malloc");
+       KGET1(VM_SWDEVT, sw, nswdev * sizeof(*sw), "swdevt");
+       KGET2((long)kswapmap, mp, nswapmap * sizeof(*mp), "swapmap");
+
+       /* First entry in map is `struct map'; rest are mapent's. */
+       swapmap = (struct map *)mp;
+       if (nswapmap != swapmap->m_limit - (struct mapent *)kswapmap)
+               errx(1, "panic: nswapmap goof");
+
+       /* Count up swap space. */
+       nfree = 0;
+       memset(perdev, 0, nswdev * sizeof(*perdev));
+       for (mp++; mp->m_addr != 0; mp++) {
+               s = mp->m_addr;                 /* start of swap region */
+               e = mp->m_addr + mp->m_size;    /* end of region */
+               nfree += mp->m_size;
 
 
-#include <varargs.h>
+               /*
+                * Swap space is split up among the configured disks.
+                * The first dmmax blocks of swap space some from the
+                * first disk, the next dmmax blocks from the next, 
+                * and so on.  The list of free space joins adjacent
+                * free blocks, ignoring device boundries.  If we want
+                * to keep track of this information per device, we'll
+                * just have to extract it ourselves.
+                */
 
 
-error(va_alist)
-       va_dcl
-{
-       char *fmt;
-       va_list ap;
-       extern errno;
-
-       fprintf(stderr, "pstat: ");
-       va_start(ap);
-       fmt = va_arg(ap, char *);
-       (void) vfprintf(stderr, fmt, ap);
-       va_end(ap);
-       fprintf(stderr, "\n");
+               /* calculate first device on which this falls */
+               i = (s / dmmax) % nswdev;
+               while (s < e) {         /* XXX this is inefficient */
+                       int bound = roundup(s+1, dmmax);
+
+                       if (bound > e)
+                               bound = e;
+                       perdev[i] += bound - s;
+                       if (++i >= nswdev)
+                               i = 0;
+                       s = bound;
+               }
+       }
+
+       header = getbsize(&hlen, &blocksize);
+       if (!totalflag)
+               (void)printf("%-10s %*s %10s %10s %10s\n",
+                   "Device", hlen, header, "Used", "Available", "Capacity");
+       div = blocksize / 512;
+       avail = npfree = 0;
+       for (i = 0; i < nswdev; i++) {
+               int xsize, xfree;
+
+               if (!totalflag)
+                       (void)printf("/dev/%-5s %*d ",
+                           devname(sw[i].sw_dev, S_IFBLK),
+                           hlen, sw[i].sw_nblks / div);
+
+               /*
+                * Don't report statistics for partitions which have not
+                * yet been activated via swapon(8).
+                */
+               if (!sw[i].sw_freed) {
+                       if (totalflag)
+                               continue;
+                       (void)printf(" *** not available for swapping ***\n");
+                       continue;
+               }
+               xsize = sw[i].sw_nblks;
+               xfree = perdev[i];
+               used = xsize - xfree;
+               npfree++;
+               avail += xsize;
+               if (totalflag)
+                       continue;
+               (void)printf("%10d %10d %7.0f%%\n", 
+                   used / div, xfree / div,
+                   (double)used / (double)xsize * 100.0);
+       }
+
+       /* 
+        * If only one partition has been set up via swapon(8), we don't
+        * need to bother with totals.
+        */
+       used = avail - nfree;
+       if (totalflag) {
+               (void)printf("%dM/%dM swap space\n", used / 2048, avail / 2048);
+               return;
+       }
+       if (npfree > 1) {
+               (void)printf("%-10s %*d %10d %10d %7.0f%%\n",
+                   "Total", hlen, avail / div, used / div, nfree / div,
+                   (double)used / (double)avail * 100.0);
+       }
 }
 
 }
 
-syserror(va_alist)
-       va_dcl
+void
+usage()
 {
 {
-       char *fmt;
-       va_list ap;
-       extern errno;
-
-       fprintf(stderr, "pstat: ");
-       va_start(ap);
-       fmt = va_arg(ap, char *);
-       (void) vfprintf(stderr, fmt, ap);
-       va_end(ap);
-       fprintf(stderr, ": %s\n", strerror(errno));
+       (void)fprintf(stderr,
+           "usage: pstat -Tfnstv [system] [-M core] [-N system]\n");
+       exit(1);
 }
 }