BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.bin / w / w.c
index 045f509..501938a 100644 (file)
@@ -1,18 +1,44 @@
 /*-
 /*-
- * Copyright (c) 1980, 1991 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1980, 1991, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #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, 1994\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[] = "@(#)w.c        5.37 (Berkeley) %G%";
+static char sccsid[] = "@(#)w.c        8.6 (Berkeley) 6/30/94";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -31,6 +57,7 @@ static char sccsid[] = "@(#)w.c       5.37 (Berkeley) %G%";
 #include <sys/socket.h>
 #include <sys/tty.h>
 
 #include <sys/socket.h>
 #include <sys/tty.h>
 
+#include <machine/cpu.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
@@ -48,23 +75,23 @@ static char sccsid[] = "@(#)w.c     5.37 (Berkeley) %G%";
 #include <tzfile.h>
 #include <unistd.h>
 #include <utmp.h>
 #include <tzfile.h>
 #include <unistd.h>
 #include <utmp.h>
+#include <vis.h>
 
 #include "extern.h"
 
 
 #include "extern.h"
 
-struct timeval boottime;
-struct utmp utmp;
-struct winsize ws;
-kvm_t *kd;
-time_t now;                    /* the current time of day */
-time_t uptime;                 /* time of last reboot & elapsed time since */
-int ttywidth;                  /* width of tty */
-int argwidth;                  /* width of tty */
-int header = 1;                        /* true if -h flag: don't print heading */
-int nflag;                     /* true if -n flag: don't convert addrs */
-int sortidle;                  /* sort bu idle time */
-char *sel_user;                        /* login of particular user selected */
-char *program;
-char domain[MAXHOSTNAMELEN];
+struct timeval boottime;
+struct utmp    utmp;
+struct winsize ws;
+kvm_t         *kd;
+time_t         now;            /* the current time of day */
+time_t         uptime;         /* time of last reboot & elapsed time since */
+int            ttywidth;       /* width of tty */
+int            argwidth;       /* width of tty */
+int            header = 1;     /* true if -h flag: don't print heading */
+int            nflag;          /* true if -n flag: don't convert addrs */
+int            sortidle;       /* sort bu idle time */
+char          *sel_user;       /* login of particular user selected */
+char           domain[MAXHOSTNAMELEN];
 
 /*
  * One of these per active utmp entry.
 
 /*
  * One of these per active utmp entry.
@@ -78,42 +105,32 @@ struct     entry {
        char    *args;          /* arg list of interesting process */
 } *ep, *ehead = NULL, **nextp = &ehead;
 
        char    *args;          /* arg list of interesting process */
 } *ep, *ehead = NULL, **nextp = &ehead;
 
-struct nlist nl[] = {
-       { "_boottime" },
-#define X_BOOTTIME     0
-#if defined(hp300) || defined(i386)
-       { "_cn_tty" },
-#define X_CNTTY                1
-#endif
-       { "" },
-};
-
-static void     pr_header __P((kvm_t *, time_t *, int));
+static void     pr_header __P((time_t *, int));
 static struct stat
                *ttystat __P((char *));
 static void     usage __P((int));
 
 static struct stat
                *ttystat __P((char *));
 static void     usage __P((int));
 
-char *fmt_argv __P((char **, char *, int));
+char *fmt_argv __P((char **, char *, int));    /* ../../bin/ps/fmt.c */
 
 int
 main(argc, argv)
        int argc;
        char **argv;
 {
 
 int
 main(argc, argv)
        int argc;
        char **argv;
 {
-       extern char *optarg;
-       extern int optind;
+       extern char *__progname;
        struct kinfo_proc *kp;
        struct hostent *hp;
        struct stat *stp;
        FILE *ut;
        u_long l;
        struct kinfo_proc *kp;
        struct hostent *hp;
        struct stat *stp;
        FILE *ut;
        u_long l;
+       size_t arglen;
        int ch, i, nentries, nusers, wcmd;
        int ch, i, nentries, nusers, wcmd;
-       char *memf, *nlistf, *p, *x;
+       char *memf, *nlistf, *p, *vis_args, *x;
        char buf[MAXHOSTNAMELEN], errbuf[256];
 
        /* Are we w(1) or uptime(1)? */
        char buf[MAXHOSTNAMELEN], errbuf[256];
 
        /* Are we w(1) or uptime(1)? */
-       program = argv[0];
-       if ((p = rindex(program, '/')) || *(p = program) == '-')
+       p = __progname;
+       if (*p == '-')
                p++;
        if (*p == 'u') {
                wcmd = 0;
                p++;
        if (*p == 'u') {
                wcmd = 0;
@@ -133,6 +150,7 @@ main(argc, argv)
                        sortidle = 1;
                        break;
                case 'M':
                        sortidle = 1;
                        break;
                case 'M':
+                       header = 0;
                        memf = optarg;
                        break;
                case 'N':
                        memf = optarg;
                        break;
                case 'N':
@@ -152,9 +170,7 @@ main(argc, argv)
        argv += optind;
 
        if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
        argv += optind;
 
        if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
-               err(1, "%s", errbuf);
-       if (header && kvm_nlist(kd, nl) != 0)
-               err(1, "can't read namelist");
+               errx(1, "%s", errbuf);
 
        (void)time(&now);
        if ((ut = fopen(_PATH_UTMP, "r")) == NULL)
 
        (void)time(&now);
        if ((ut = fopen(_PATH_UTMP, "r")) == NULL)
@@ -174,30 +190,23 @@ main(argc, argv)
                        err(1, NULL);
                *nextp = ep;
                nextp = &(ep->next);
                        err(1, NULL);
                *nextp = ep;
                nextp = &(ep->next);
-               bcopy(&utmp, &(ep->utmp), sizeof (struct utmp));
-               stp = ttystat(ep->utmp.ut_line);
+               memmove(&(ep->utmp), &utmp, sizeof(struct utmp));
+               if (!(stp = ttystat(ep->utmp.ut_line)))
+                       continue;
                ep->tdev = stp->st_rdev;
                ep->tdev = stp->st_rdev;
-#if defined(hp300) || defined(i386)
+#ifdef CPU_CONSDEV
                /*
                /*
-                * XXX
                 * If this is the console device, attempt to ascertain
                 * the true console device dev_t.
                 */
                if (ep->tdev == 0) {
                 * If this is the console device, attempt to ascertain
                 * the true console device dev_t.
                 */
                if (ep->tdev == 0) {
-                       static dev_t cn_dev;
+                       int mib[2];
+                       size_t size;
 
 
-                       if (nl[X_CNTTY].n_value) {
-                               struct tty cn_tty, *cn_ttyp;
-                               
-                               if (kvm_read(kd, (u_long)nl[X_CNTTY].n_value,
-                                   (char *)&cn_ttyp, sizeof(cn_ttyp)) > 0) {
-                                       (void)kvm_read(kd, (u_long)cn_ttyp,
-                                           (char *)&cn_tty, sizeof (cn_tty));
-                                       cn_dev = cn_tty.t_dev;
-                               }
-                               nl[X_CNTTY].n_value = 0;
-                       }
-                       ep->tdev = cn_dev;
+                       mib[0] = CTL_MACHDEP;
+                       mib[1] = CPU_CONSDEV;
+                       size = sizeof(dev_t);
+                       (void) sysctl(mib, 2, &ep->tdev, &size, NULL, 0);
                }
 #endif
                if ((ep->idle = now - stp->st_atime) < 0)
                }
 #endif
                if ((ep->idle = now - stp->st_atime) < 0)
@@ -206,7 +215,7 @@ main(argc, argv)
        (void)fclose(ut);
 
        if (header || wcmd == 0) {
        (void)fclose(ut);
 
        if (header || wcmd == 0) {
-               pr_header(kd, &now, nusers);
+               pr_header(&now, nusers);
                if (wcmd == 0)
                        exit (0);
        }
                if (wcmd == 0)
                        exit (0);
        }
@@ -218,8 +227,8 @@ main(argc, argv)
        if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == NULL)
                err(1, "%s", kvm_geterr(kd));
        for (i = 0; i < nentries; i++, kp++) {
        if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == NULL)
                err(1, "%s", kvm_geterr(kd));
        for (i = 0; i < nentries; i++, kp++) {
-               register struct proc *p = &kp->kp_proc;
-               register struct eproc *e;
+               struct proc *p = &kp->kp_proc;
+               struct eproc *e;
 
                if (p->p_stat == SIDL || p->p_stat == SZOMB)
                        continue;
 
                if (p->p_stat == SIDL || p->p_stat == SZOMB)
                        continue;
@@ -273,16 +282,18 @@ main(argc, argv)
                        
        if (!nflag)
                if (gethostname(domain, sizeof(domain) - 1) < 0 ||
                        
        if (!nflag)
                if (gethostname(domain, sizeof(domain) - 1) < 0 ||
-                   (p = index(domain, '.')) == 0)
+                   (p = strchr(domain, '.')) == 0)
                        domain[0] = '\0';
                else {
                        domain[sizeof(domain) - 1] = '\0';
                        domain[0] = '\0';
                else {
                        domain[sizeof(domain) - 1] = '\0';
-                       bcopy(p, domain, strlen(p) + 1);
+                       memmove(domain, p, strlen(p) + 1);
                }
 
                }
 
+       if ((vis_args = malloc(argwidth * 4 + 1)) == NULL)
+               err(1, NULL);
        for (ep = ehead; ep != NULL; ep = ep->next) {
                p = *ep->utmp.ut_host ? ep->utmp.ut_host : "-";
        for (ep = ehead; ep != NULL; ep = ep->next) {
                p = *ep->utmp.ut_host ? ep->utmp.ut_host : "-";
-               if (x = index(p, ':'))
+               if ((x = strchr(p, ':')) != NULL)
                        *x++ = '\0';
                if (!nflag && isdigit(*p) &&
                    (long)(l = inet_addr(p)) != -1 &&
                        *x++ = '\0';
                if (!nflag && isdigit(*p) &&
                    (long)(l = inet_addr(p)) != -1 &&
@@ -291,13 +302,14 @@ main(argc, argv)
                                p = hp->h_name;
                                p += strlen(hp->h_name);
                                p -= strlen(domain);
                                p = hp->h_name;
                                p += strlen(hp->h_name);
                                p -= strlen(domain);
-                               if (p > hp->h_name && !strcmp(p, domain))
+                               if (p > hp->h_name && strcmp(p, domain) == 0)
                                        *p = '\0';
                        }
                        p = hp->h_name;
                }
                if (x) {
                                        *p = '\0';
                        }
                        p = hp->h_name;
                }
                if (x) {
-                       (void)snprintf(buf, sizeof(buf), "%s:%s", p, x);
+                       (void)snprintf(buf, sizeof(buf), "%s:%.*s", p,
+                               ep->utmp.ut_host + UT_HOSTSIZE - x, x);
                        p = buf;
                }
                (void)printf("%-*.*s %-2.2s %-*.*s ",
                        p = buf;
                }
                (void)printf("%-*.*s %-2.2s %-*.*s ",
@@ -307,60 +319,68 @@ main(argc, argv)
                    UT_HOSTSIZE, UT_HOSTSIZE, *p ? p : "-");
                pr_attime(&ep->utmp.ut_time, &now);
                pr_idle(ep->idle);
                    UT_HOSTSIZE, UT_HOSTSIZE, *p ? p : "-");
                pr_attime(&ep->utmp.ut_time, &now);
                pr_idle(ep->idle);
+               if (ep->args != NULL) {
+                       arglen = strlen(ep->args);
+                       strvisx(vis_args, ep->args,
+                           arglen > argwidth ? argwidth : arglen,
+                           VIS_TAB | VIS_NL | VIS_NOSLASH);
+               }
                (void)printf("%.*s\n", argwidth, ep->args);
        }
        exit(0);
 }
 
 static void
                (void)printf("%.*s\n", argwidth, ep->args);
        }
        exit(0);
 }
 
 static void
-pr_header(kd, nowp, nusers)
-       kvm_t *kd;
+pr_header(nowp, nusers)
        time_t *nowp;
        int nusers;
 {
        double avenrun[3];
        time_t uptime;
        int days, hrs, i, mins;
        time_t *nowp;
        int nusers;
 {
        double avenrun[3];
        time_t uptime;
        int days, hrs, i, mins;
-       char buf[256], fmt[10];
+       int mib[2];
+       size_t size;
+       char buf[256];
 
        /*
         * Print time of day.
         *
 
        /*
         * Print time of day.
         *
-        * Note, SCCS forces the string manipulation below, as it
-        * replaces w.c with file information.
+        * SCCS forces the string manipulation below, as it replaces
+        * %, M, and % in a character string with the file name.
         */
         */
-       (void)strcpy(fmt, "%l:%%%p");
-       fmt[4] = 'M';
-       (void)strftime(buf, sizeof(buf), fmt, localtime(nowp));
+       (void)strftime(buf, sizeof(buf),
+           __CONCAT("%l:%","M%p"), localtime(nowp));
        (void)printf("%s ", buf);
 
        /*
         * Print how long system has been up.
        (void)printf("%s ", buf);
 
        /*
         * Print how long system has been up.
-        * (Found by looking for "boottime" in kernel)
+        * (Found by looking getting "boottime" from the kernel)
         */
         */
-       if ((kvm_read(kd, (u_long)nl[X_BOOTTIME].n_value,
-           &boottime, sizeof(boottime))) != sizeof(boottime))
-               err(1, "can't read kernel bootime variable");
-
-       uptime = now - boottime.tv_sec;
-       uptime += 30;
-       days = uptime / SECSPERDAY;
-       uptime %= SECSPERDAY;
-       hrs = uptime / SECSPERHOUR;
-       uptime %= SECSPERHOUR;
-       mins = uptime / SECSPERMIN;
-       (void)printf(" up");
-       if (days > 0)
-               (void)printf(" %d day%s,", days, days > 1 ? "s" : "");
-       if (hrs > 0 && mins > 0)
-               (void)printf(" %2d:%02d,", hrs, mins);
-       else {
-               if (hrs > 0)
-                       (void)printf(" %d hr%s,",
-                           hrs, hrs > 1 ? "s" : "");
-               if (mins > 0)
-                       (void)printf(" %d min%s,",
-                           mins, mins > 1 ? "s" : "");
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_BOOTTIME;
+       size = sizeof(boottime);
+       if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
+           boottime.tv_sec != 0) {
+               uptime = now - boottime.tv_sec;
+               uptime += 30;
+               days = uptime / SECSPERDAY;
+               uptime %= SECSPERDAY;
+               hrs = uptime / SECSPERHOUR;
+               uptime %= SECSPERHOUR;
+               mins = uptime / SECSPERMIN;
+               (void)printf(" up");
+               if (days > 0)
+                       (void)printf(" %d day%s,", days, days > 1 ? "s" : "");
+               if (hrs > 0 && mins > 0)
+                       (void)printf(" %2d:%02d,", hrs, mins);
+               else {
+                       if (hrs > 0)
+                               (void)printf(" %d hr%s,",
+                                   hrs, hrs > 1 ? "s" : "");
+                       if (mins > 0)
+                               (void)printf(" %d min%s,",
+                                   mins, mins > 1 ? "s" : "");
+               }
        }
 
        /* Print number of users logged in to system */
        }
 
        /* Print number of users logged in to system */
@@ -369,8 +389,7 @@ pr_header(kd, nowp, nusers)
        /*
         * Print 1, 5, and 15 minute load averages.
         */
        /*
         * Print 1, 5, and 15 minute load averages.
         */
-       if (kvm_getloadavg(kd,
-           avenrun, sizeof(avenrun) / sizeof(avenrun[0])) == -1)
+       if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) == -1)
                (void)printf(", no load average information available\n");
        else {
                (void)printf(", load averages:");
                (void)printf(", no load average information available\n");
        else {
                (void)printf(", load averages:");
@@ -392,7 +411,7 @@ ttystat(line)
 
        (void)snprintf(ttybuf, sizeof(ttybuf), "%s/%s", _PATH_DEV, line);
        if (stat(ttybuf, &sb))
 
        (void)snprintf(ttybuf, sizeof(ttybuf), "%s/%s", _PATH_DEV, line);
        if (stat(ttybuf, &sb))
-               err(1, "%s", ttybuf);
+               return (NULL);
        return (&sb);
 }
 
        return (&sb);
 }