BSD 4 release
[unix-history] / usr / src / cmd / last.c
index 3adaeb4..495accc 100644 (file)
-#
+static char *sccsid = "@(#)last.c      4.2 (Berkeley) 10/9/80";
 /*
 /*
- * NAME: last
- *
- * SYNOPSIS: last [list]
- *
- * DESCRIPTION: Displays login history of named users or tty's.
- *             Last with no argument prints history for all users.
- *
- * AUTHOR - Howard P. Katseff
+ * last
  */
  */
+#include <sys/types.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stat.h>
+#include <utmp.h>
 
 
-# include <sys/types.h>
-# include <stdio.h>
-# include <stat.h>
-# include <utmp.h>
+#define NMAX   sizeof(buf[0].ut_name)
+#define LMAX   sizeof(buf[0].ut_line)
+#define        SECDAY  (24*60*60)
 
 
-char   yes =   1,
-       no  =   0,
+#define        lineq(a,b)      (!strncmp(a,b,LMAX))
+#define        nameq(a,b)      (!strncmp(a,b,NMAX))
 
 
-       *wtmp = "/usr/adm/wtmp",
-       b [512],
+#define MAXTTYS 256
 
 
-       Arg       [25] [9],
-       tty_names [48] [9],
+char   **argv;
+int    argc;
 
 
-       *ctime  (),
-       *move   (),
-       *rmchar ();
+struct utmp buf[128];
+char   ttnames[MAXTTYS][LMAX+1];
+long   logouts[MAXTTYS];
 
 
+char   *ctime(), *strspl();
+int    onintr();
 
 
-long   logouts [48],
-       bl,
-       rec,
-       nblock;
-
-struct utmp buf [128]; /* buf takes exactly 5 blocks */
-
-main (argc, argv)
-char **argv;
+main(ac, av)
+       char **av;
 {
 {
-       char    f,
-               narg,
-
-               *bend,
-               *p,
-               *q;
-
-       short   n_byte,
-               n_record;
-
-       long    i,
-               k,
-               ntime,
-               otime,
-
-               intrp ();
-
-       struct  stat sbuf;
+       register int i, k;
+       int bl, wtmp;
+       char *ct;
+       register struct utmp *bp;
+       long otime;
+       struct stat stb;
+       int print;
  
  
-       for (i = 1; i < argc; i++)
-       {
-               if
-               (
-                       length (argv [i]) > 2 /* long tty or user name */
-                       ||
-                       equal (argv [i], "~") /* tilde */
-                       ||
-                       getpwnam (argv [i]) /* user name */
-               )
-               {
-                       move (argv [i], Arg [narg++]);
-               }
-               else /* short tty name */
-               {
-                       move (argv [i], move ("tty", Arg [narg++]));
-               }
+       time(&buf[0].ut_time);
+       ac--, av++;
+       argc = ac;
+       argv = av;
+       for (i = 0; i < argc; i++) {
+               if (strlen(argv[i])>2)
+                       continue;
+               if (!strcmp(argv[i], "~"))
+                       continue;
+               if (getpwnam(argv[i]))
+                       continue;
+               argv[i] = strspl("tty", argv[i]);
        }
        }
-       f = open (wtmp, 0);
-       if (f < 0)
-       {
-               perror (wtmp);
-               fflush (stdout);
-               exit ();
+       wtmp = open("/usr/adm/wtmp", 0);
+       if (wtmp < 0) {
+               perror("/usr/adm/wtmp");
+               exit(1);
        }
        }
-       if (fstat (f, &sbuf) < 0)
-       {
-               perror ("/usr/adm/wtmp");
-               fflush (stdout);
-               exit ();
+       fstat(wtmp, &stb);
+       bl = (stb.st_size + sizeof (buf)-1) / sizeof (buf);
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
+               signal(SIGINT, onintr);
+               signal(SIGQUIT, onintr);
        }
        }
-       nblock = (sbuf.st_size + 2559) / 2560;
-       signal (2, intrp);
-       for (bl = nblock - 1; bl >= 0; bl--)
-       {
-               lseek (f, bl * 2560, 0);
-               n_byte = read (f, buf, 2560);
-               n_record = n_byte / sizeof buf [0];
-               for (rec = n_record - 1; rec >= 0; rec--)
-               {
-                       
-                       if (should_print ())
-                       {
-                               q = ctime (&buf[rec].ut_time);
-                               printf
-                               (
-                                       "%-8.8s  %-8.8s  %10.10s %5.5s ",
-                                       buf[rec].ut_name, buf[rec].ut_line, q, 11+q
-                               );
-                               otime = buf[rec].ut_time;
-                       /*
-                        * look up the logout time for the tty
-                        */
-                               for (i = 0;; i++)
-                               {
-                                       if (!*tty_names [i])
-                                       /* not in the table, therefore add it */
-                                       {
-                                               move
-                                               (
-                                                       buf[rec].ut_line,
-                                                       tty_names [i]
-                                               );
-                                               ntime = 0;
-                                               break;
-                                       }
-                                       if
-                                       (
-                                               equal
-                                               (
-                                                       tty_names [i],
-                                                       buf [rec].ut_line
-                                               )
-                                       )
-                                       {
-                                               ntime = logouts [i];
-                                               break;
-                                       }
-                               }
-                               if (ntime == 0)
-                               {
-                                       printf ("  still logged in\n");
-                               }
-                               else
-                               {
-                                       if (ntime < 0)
-                                       {
-                                               ntime = -ntime;
-                                               printf ("- crash");
-                                       }
-                                       else 
-                                       {
-                                               printf ("- %5.5s", ctime (&ntime) + 11);
-                                       }
-                               /*
-                                * calculate how long logged in
-                                */
-                                       otime = ntime - otime;
-                                       otime += 231220830 + 10800;
-                                       if (otime < 231220830 + 86400 + 10800)
-                                       {
-                                               printf
-                                               (
-                                                       "  (%5.5s)\n",
-                                                       ctime (&otime) + 11
-                                               );
-                                       }
-                                       else
-                                       {
-                                               printf
-                                               (
-                                                       " (%ld+%5.5s)\n",
-                                                       (otime -
-                                                       (231330830-86400-10800))/86400,
-                                                       ctime (&otime) + 11
-                                               );
-                                       }
-                               }
-                               fflush (stdout);
+       for (bl--; bl >= 0; bl--) {
+               lseek(wtmp, bl * sizeof (buf), 0);
+               bp = &buf[read(wtmp, buf, sizeof (buf)) / sizeof(buf[0]) - 1];
+               for ( ; bp >= buf; bp--) {
+                       print = want(bp);
+                       if (print) {
+                               ct = ctime(&bp->ut_time);
+                               printf("%-*.*s  %-*.*s  %10.10s %5.5s ",
+                                   NMAX, NMAX, bp->ut_name,
+                                   LMAX, LMAX, bp->ut_line, ct, 11+ct);
                        }
                        }
-                       if
-                       (
-                               equal (buf[rec].ut_line, "~")
-                               ||
-                               equal (buf[rec].ut_line, "tty~")
-                       )
-                       {
-                               for (i = 0; *tty_names [i]; i++)
-                               {
-                                       logouts [i] = -buf[rec].ut_time;
+                       for (i = 0; i < MAXTTYS; i++) {
+                               if (ttnames[i][0] == 0) {
+                                       strncpy(ttnames[i], bp->ut_line,
+                                           sizeof(bp->ut_line));
+                                       otime = logouts[i];
+                                       logouts[i] = bp->ut_time;
+                                       break;
+                               }
+                               if (lineq(ttnames[i], bp->ut_line)) {
+                                       otime = logouts[i];
+                                       logouts[i] = bp->ut_time;
+                                       break;
                                }
                        }
                                }
                        }
-                       else
-                       {
-                               for (k = 0;; k++)
-                               {
-                                       if (!*tty_names [k])
-                                       {
-                                               move
-                                               (
-                                                       buf[rec].ut_line,
-                                                       tty_names [k]
-                                               );
-                                               logouts [k] = buf[rec].ut_time;
-                                               break;
-                                       }
-                                       if (equal (tty_names [k], buf[rec].ut_line))
-                                       {
-                                               logouts [k] = buf[rec].ut_time;
-                                               break;
-                                       }
+                       if (print) {
+                               if (otime == 0)
+                                       printf("  still logged in\n");
+                               else {
+                                       long delta;
+                                       if (otime < 0) {
+                                               otime = -otime;
+                                               printf("- crash");
+                                       } else
+                                               printf("- %5.5s",
+                                                   ctime(&otime)+11);
+                                       delta = otime - bp->ut_time;
+                                       if (delta < SECDAY)
+                                           printf("  (%5.5s)\n",
+                                               asctime(gmtime(&delta))+11);
+                                       else
+                                           printf(" (%ld+%5.5s)\n",
+                                               delta / SECDAY,
+                                               asctime(gmtime(&delta))+11);
                                }
                                }
+                               fflush(stdout);
                        }
                        }
+                       if (!strcmp(bp->ut_name, "reboot"))
+                               for (i = 0; i < MAXTTYS; i++)
+                                       logouts[i] = -bp->ut_time;
                }
        }
                }
        }
-       q = ctime (&buf [0].ut_time);
-       printf
-       (
-               "\nwtmp begins %10.10s %5.5s \n",
-               q, q + 11
-       );
-}
-
-equal (a, b)
-char *a, *b;
-{
-       char i;
-
-       for (i = 0; i < 8; i++)
-       {
-               if (!*a) return (!*b);
-               if (*a++ != *b++) return (0);
-       }
-       return (1);
+       ct = ctime(&buf[0].ut_time);
+       printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11);
+       exit(0);
 }
 
 }
 
-
-intrp ()
+onintr(signo)
+       int signo;
 {
 {
-       char *q;
-
-       signal (2, 1); /* ignore further interrupts */
-       q = ctime (&buf[rec].ut_time);
-       printf
-       (
-               "\ninterrupted %10.10s %5.5s \n",
-               q, q + 11
-       );
-       exit ();
+       char *ct;
+
+       if (signo == SIGQUIT)
+               signal(SIGQUIT, onintr);
+       ct = ctime(&buf[0].ut_time);
+       printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11);
+       if (signo == SIGINT)
+               exit(1);
 }
 
 }
 
-char *
-rmchar (c, s)
-char c, *s;
+want(bp)
+       struct utmp *bp;
 {
 {
-       for (; *s; s++)
-       {
-               if (*s == c)
-               {
-                       *s = 0;
-                       return (s);
-               }
+       register char **av;
+       register int ac;
+
+       if (bp->ut_line[0] == '~')
+               strcpy(bp->ut_name, "reboot");          /* bandaid */
+       if (bp->ut_name[0] == 0)
+               return (0);
+       if (argc == 0)
+               return (1);
+       av = argv;
+       for (ac = 0; ac < argc; ac++) {
+               if (nameq(*av, bp->ut_name) || lineq(*av, bp->ut_line))
+                       return (1);
+               av++;
        }
        return (0);
 }
 
        }
        return (0);
 }
 
-length (a)
-char *a;
-{
-       char *b;
-
-       for (b = a; *b; b++);
-       return (b - a);
-}
-
 char *
 char *
-move (a, b)
-char *a, *b;
+strspl(left, right)
+       char *left, *right;
 {
 {
-       while (*b++ = *a++);
-       return (b - 1);
-}
-
-should_print ()
-{
-       short i;
+       char *res = (char *)malloc(strlen(left)+strlen(right)+1);
 
 
-       if (buf [rec].ut_name [0] == no) return no; /* a logout entry */
-       if (!**Arg) return yes; /* no arguments? Print all login entries */
-       for (i = 0; i < *Arg [i]; i++)
-       {
-               if 
-               (
-                       equal (Arg [i], buf[rec].ut_name)
-                       ||
-                       equal (Arg [i], buf[rec].ut_line)
-               )
-               return yes;
-       }
-       return no;
+       strcpy(res, left);
+       strcat(res, right);
+       return (res);
 }
 }