use setpassent, not _pw_stayopen
[unix-history] / usr / src / usr.bin / lastcomm / lastcomm.c
index 48b0e5f..53ac675 100644 (file)
@@ -1,6 +1,29 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)lastcomm.c  4.8 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)lastcomm.c 5.7 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * last command
 
 /*
  * last command
@@ -8,13 +31,11 @@ static char *sccsid = "@(#)lastcomm.c        4.8 (Berkeley) %G%";
 #include <sys/param.h>
 #include <sys/acct.h>
 #include <sys/file.h>
 #include <sys/param.h>
 #include <sys/acct.h>
 #include <sys/file.h>
-
-#include <stdio.h>
-#include <pwd.h>
 #include <sys/stat.h>
 #include <utmp.h>
 #include <struct.h>
 #include <ctype.h>
 #include <sys/stat.h>
 #include <utmp.h>
 #include <struct.h>
 #include <ctype.h>
+#include <stdio.h>
 
 struct acct buf[DEV_BSIZE / sizeof (struct acct)];
 
 
 struct acct buf[DEV_BSIZE / sizeof (struct acct)];
 
@@ -24,21 +45,41 @@ char        *getname();
 char   *getdev();
 
 main(argc, argv)
 char   *getdev();
 
 main(argc, argv)
+       int argc;
        char *argv[];
 {
        char *argv[];
 {
-       register int bn, cc;
+       extern int optind;
+       extern char *optarg;
        register struct acct *acp;
        register struct acct *acp;
-       int fd;
+       register int bn, cc;
        struct stat sb;
        struct stat sb;
+       int ch, fd;
+       char *acctfile, *strcpy(), *ctime();
+       long lseek();
 
 
-       fd = open("/usr/adm/acct", O_RDONLY);
+       acctfile = NULL;
+       while ((ch = getopt(argc, argv, "f:")) != EOF)
+               switch((char)ch) {
+               case 'f':
+                       acctfile = optarg;
+                       break;
+               case '?':
+               default:
+                       fputs("lastcomm [ -f file ]\n", stderr);
+                       exit(1);
+               }
+       argv += optind;
+       if (!acctfile)
+               acctfile = "/usr/adm/acct";
+       fd = open(acctfile, O_RDONLY);
        if (fd < 0) {
        if (fd < 0) {
-               perror("/usr/adm/acct");
+               perror(acctfile);
                exit(1);
        }
                exit(1);
        }
-       fstat(fd, &sb);
-       for (bn = btodb(sb.st_size) - 1; bn >= 0; bn--) {
-               lseek(fd, bn * DEV_BSIZE, L_SET);
+       (void)fstat(fd, &sb);
+       setpassent(1);
+       for (bn = btodb(sb.st_size); bn >= 0; bn--) {
+               (void)lseek(fd, (off_t)dbtob(bn), L_SET);
                cc = read(fd, buf, DEV_BSIZE);
                if (cc < 0) {
                        perror("read");
                cc = read(fd, buf, DEV_BSIZE);
                if (cc < 0) {
                        perror("read");
@@ -47,24 +88,26 @@ main(argc, argv)
                acp = buf + (cc / sizeof (buf[0])) - 1;
                for (; acp >= buf; acp--) {
                        register char *cp;
                acp = buf + (cc / sizeof (buf[0])) - 1;
                for (; acp >= buf; acp--) {
                        register char *cp;
-                       time_t x =
-                           expand(acp->ac_utime) + expand(acp->ac_stime);
+                       time_t x;
 
 
-                       acp->ac_comm[10] = '\0';
-                       if (*acp->ac_comm == '\0')
-                               strcpy(acp->ac_comm, "?");
-                       for (cp = acp->ac_comm; *cp; cp++)
-                               if (iscntrl(*cp))
+                       if (acp->ac_comm[0] == '\0')
+                               (void)strcpy(acp->ac_comm, "?");
+                       for (cp = &acp->ac_comm[0];
+                            cp < &acp->ac_comm[fldsiz(acct, ac_comm)] && *cp;
+                            cp++)
+                               if (!isascii(*cp) || iscntrl(*cp))
                                        *cp = '?';
                                        *cp = '?';
-                       if (!ok(argc, argv, acp) && argc != 1)
+                       if (*argv && !ok(argv, acp))
                                continue;
                                continue;
-                       printf("%-*s %s %-*s %-*s %4d sec%s %.16s\n",
-                               fldsiz(acct, ac_comm), acp->ac_comm,
-                               flagbits(acp->ac_flag),
-                               fldsiz(utmp, ut_name), getname(acp->ac_uid),
+                       x = expand(acp->ac_utime) + expand(acp->ac_stime);
+                       printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
+                               fldsiz(acct, ac_comm),
+                               fldsiz(acct, ac_comm),
+                               acp->ac_comm, flagbits(acp->ac_flag),
+                               fldsiz(utmp, ut_name),
+                               (cp = getname(acp->ac_uid)) ? cp : "",
                                fldsiz(utmp, ut_line), getdev(acp->ac_tty),
                                fldsiz(utmp, ut_line), getdev(acp->ac_tty),
-                               x, x > 1 || x == 0 ? "s" : " ",
-                               ctime(&acp->ac_btime));
+                               x / (double)AHZ, ctime(&acp->ac_btime));
                }
        }
 }
                }
        }
 }
@@ -88,91 +131,64 @@ char *
 flagbits(f)
        register int f;
 {
 flagbits(f)
        register int f;
 {
-       register int i = 0;
        static char flags[20];
        static char flags[20];
+       char *p, *strcpy();
 
 
-#define BIT(flag, ch)  flags[i++] = (f & flag) ? ch : ' '
+#define        BIT(flag, ch)   if (f & flag) *p++ = ch;
+       p = strcpy(flags, "-    ");
        BIT(ASU, 'S');
        BIT(AFORK, 'F');
        BIT(ACOMPAT, 'C');
        BIT(ACORE, 'D');
        BIT(AXSIG, 'X');
        BIT(ASU, 'S');
        BIT(AFORK, 'F');
        BIT(ACOMPAT, 'C');
        BIT(ACORE, 'D');
        BIT(AXSIG, 'X');
-       flags[i] = '\0';
        return (flags);
 }
 
        return (flags);
 }
 
-ok(argc, argv, acp)
-       register int argc;
+ok(argv, acp)
        register char *argv[];
        register struct acct *acp;
 {
        register char *argv[];
        register struct acct *acp;
 {
-       register int j;
+       register char *cp;
 
 
-       for (j = 1; j < argc; j++)
-               if (strcmp(getname(acp->ac_uid), argv[j]) &&
-                   strcmp(getdev(acp->ac_tty), argv[j]) &&
-                   strcmp(acp->ac_comm, argv[j]))
-                       break;
-       return (j == argc);
+       do {
+               if ((cp = getname(acp->ac_uid)) && !strcmp(cp, *argv) ||
+                   (cp = getdev(acp->ac_tty)) && !strcmp(cp, *argv) ||
+                   !strncmp(acp->ac_comm, *argv, fldsiz(acct, ac_comm)))
+                       return(1);
+       } while (*++argv);
+       return(0);
 }
 
 /* should be done with nameserver or database */
 
 }
 
 /* should be done with nameserver or database */
 
-struct utmp utmp;
+#include <pwd.h>
 
 
-#define NUID   2048
+struct utmp utmp;
 #define        NMAX    (sizeof (utmp.ut_name))
 #define        NMAX    (sizeof (utmp.ut_name))
+#define SCPYN(a, b)    strncpy(a, b, NMAX)
 
 
-char   names[NUID][NMAX+1];
-char   outrangename[NMAX+1];
-int    outrangeuid = -1;
+#define NCACHE 64              /* power of 2 */
+#define CAMASK NCACHE - 1
 
 char *
 getname(uid)
 
 char *
 getname(uid)
+       uid_t uid;
 {
 {
+       static struct ncache {
+               uid_t   uid;
+               char    name[NMAX+1];
+       } c_uid[NCACHE];
        register struct passwd *pw;
        register struct passwd *pw;
-       static init;
-       struct passwd *getpwent();
+       register struct ncache *cp;
 
 
-       if (uid >= 0 && uid < NUID && names[uid][0])
-               return (&names[uid][0]);
-       if (uid >= 0 && uid == outrangeuid)
-               return (outrangename);
-       if (init == 2) {
-               if (uid < NUID)
-                       return (0);
-               setpwent();
-               while (pw = getpwent()) {
-                       if (pw->pw_uid != uid)
-                               continue;
-                       outrangeuid = pw->pw_uid;
-                       strncpy(outrangename, pw->pw_name, NMAX);
-                       endpwent();
-                       return (outrangename);
-               }
-               endpwent();
-               return (0);
-       }
-       if (init == 0)
-               setpwent(), init = 1;
-       while (pw = getpwent()) {
-               if (pw->pw_uid < 0 || pw->pw_uid >= NUID) {
-                       if (pw->pw_uid == uid) {
-                               outrangeuid = pw->pw_uid;
-                               strncpy(outrangename, pw->pw_name, NMAX);
-                               return (outrangename);
-                       }
-                       continue;
-               }
-               if (names[pw->pw_uid][0])
-                       continue;
-               strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
-               if (pw->pw_uid == uid)
-                       return (&names[uid][0]);
-       }
-       init = 2;
-       endpwent();
-       return (0);
+       cp = c_uid + (uid & CAMASK);
+       if (cp->uid == uid && *cp->name)
+               return(cp->name);
+       if (!(pw = getpwuid(uid)))
+               return((char *)0);
+       cp->uid = uid;
+       SCPYN(cp->name, pw->pw_name);
+       return(cp->name);
 }
 
 #include <sys/dir.h>
 }
 
 #include <sys/dir.h>
@@ -195,14 +211,16 @@ setupdevs()
        register struct devhash * hashtab;
        register ndevs = NDEVS;
        struct direct * dp;
        register struct devhash * hashtab;
        register ndevs = NDEVS;
        struct direct * dp;
+       char *malloc();
 
 
-       if ((fd = opendir("/dev")) == NULL) {
-               perror("/dev");
-               return;
-       }
+       /*NOSTRICT*/
        hashtab = (struct devhash *)malloc(NDEVS * sizeof(struct devhash));
        if (hashtab == (struct devhash *)0) {
        hashtab = (struct devhash *)malloc(NDEVS * sizeof(struct devhash));
        if (hashtab == (struct devhash *)0) {
-               fprintf(stderr, "No mem for dev table\n");
+               fputs("No mem for dev table\n", stderr);
+               return;
+       }
+       if ((fd = opendir("/dev")) == NULL) {
+               perror("/dev");
                return;
        }
        while (dp = readdir(fd)) {
                return;
        }
        while (dp = readdir(fd)) {
@@ -230,7 +248,8 @@ getdev(dev)
        char name[fldsiz(devhash, dev_name) + 6];
        static dev_t lastdev = (dev_t) -1;
        static char *lastname;
        char name[fldsiz(devhash, dev_name) + 6];
        static dev_t lastdev = (dev_t) -1;
        static char *lastname;
-       int init = 0;
+       static int init = 0;
+       char *strcpy(), *strcat();
 
        if (dev == NODEV)
                return ("__");
 
        if (dev == NODEV)
                return ("__");