home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / upgrade / src / last.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  5KB  |  254 lines

  1. /*
  2.  * NAME: last
  3.  *
  4.  * SYNOPSIS: last [-] [name ...]
  5.  *
  6.  * DESCRIPTION: Displays login history of named users or tty's.
  7.  *             Last with no argument prints history for all users.
  8.  *           Last - displays history for all non-class users.
  9.  *
  10.  * EXTERNAL ROUTINES USED: bread.c blseek.c
  11.  *
  12.  * AUTHOR - Howard P. Katseff
  13.  */
  14.  
  15. struct {char c1, c2, c3, c4;};
  16. struct {long l1;};
  17. int    allflag;
  18. char buf[32];
  19. extern    fout;
  20.  
  21. main(argc, argv)
  22. char **argv; {
  23.     register char tty;
  24.     register char **p;
  25.     register char *q;
  26.     int f, i, count;
  27.     int intrp(), qintrp();
  28.     long lx;
  29.     long otime, ntime;
  30.     long logouts[128];
  31.  
  32.     count = 0;
  33.     fout = dup(1);
  34.     if (allflag = argc==1) argv--;
  35.     f = open("/usr/adm/wtmp", 0);
  36.     if (f < 0) {
  37.         printf("Can't open /usr/adm/wtmp\n");
  38.         exit();
  39.         }
  40. x:      fstat(f, buf);
  41.  
  42.     for (i=0; i<127; i++) logouts[i] = 0;
  43.  
  44.     lx.c2 = 0;
  45.     lx.c1 = buf[9];
  46.     lx.c3 = buf[10] & 0360;
  47.     lx.c4 = buf[11];
  48.  
  49.     blseek(f, lx, 0);
  50.     lx =- 16;
  51.  
  52.     if ((signal(2,1) && 01) == 0) {
  53.         signal(2, &intrp);
  54.         signal(3, &qintrp);
  55.         }
  56.  
  57.     for(;;) {
  58.         if (lx < 16) {
  59.             f = open("/usr/adm/owtmp", 0);
  60.             if (count++ == 0 && f > 0) goto x;
  61.             q = ctime(buf+10);
  62.             printf("\nwtmp begins at  %10.10s  %5.5s \n",
  63.                 q, 11+q);
  64.             flush();
  65.             exit();
  66.             }
  67.  
  68.         if (bread(f, buf+16, -16) < 16) {
  69.             perror("impossible error");
  70.             exit();
  71.             }
  72.  
  73.         for (p = 1+argv; *p != -1; p++) {
  74.             if (equal(*p, buf)) {
  75.                 tty = buf[8];
  76.                 q = ctime(buf+10);
  77.                 if (tty >= ' ') 
  78.                     printf("%8.8s  tty%c  %10.10s  %5.5s ",
  79.                         buf, tty, q, 11+q);
  80.                 else
  81.                     printf("%8.8s  tty^%c %10.10s  %5.5s ",
  82.                         buf, tty+0140, q, 11+q);
  83.                 otime = (buf+10)->l1;
  84.                 ntime = logouts[tty];
  85.                 if (ntime == 0) {
  86.                     printf("  still logged in\n");
  87.                     }
  88.                 else {
  89.                     if (ntime <= 0) {
  90.                         ntime = -ntime;
  91.                         printf("- crash");
  92.                         }
  93.                     else printf("- %5.5s", 11+ctime(&ntime));
  94.                     otime = ntime - otime;
  95.                     otime =+ 231231630;
  96.                     if (otime < 231318030)
  97.                         printf("  (%5.5s)\n", 11+
  98.                         ctime(&otime));
  99.                     else
  100.                         printf(" (%ld+%5.5s)\n",
  101.                         (otime-231231630)/86400,
  102.                         11+ctime(&otime));
  103.                     }
  104.                 flush();
  105.                 break;
  106.                 }
  107.             }
  108.         lx =- 16;
  109.  
  110.         if (buf[0] == '\0') {
  111.             tty = buf[8];
  112.             if (tty == '~')
  113.                 for (i=0; i<127; i++) logouts[i] = -(buf+10)->l1;
  114.             else logouts[tty] = (buf+10)->l1;
  115.             }
  116.         }
  117.     }
  118.  
  119.  
  120. equal(c1, c2)
  121. char *c1, *c2; {
  122.     int i;
  123.  
  124.     if (allflag && (*c2 != '\0' || *(c2+8) >= '|')) return(1);
  125.  
  126.     if (*(c1+1) == '\0') {
  127.         if ((*c1 == '-') || (*c1 == 'x')) {
  128.             if (*c2 == '\0' && *(c2+8) < '|') return(0);
  129.             if (*c2 >= '0' && *c2 <= '9') return(0);
  130.             if (*(c2+2) >= '0' && *(c2+2) <= '9') return(0);
  131.             for(i=0; i<8; i++) if (*c2++ == '-') return(0);
  132.             return(1);
  133.             }
  134.  
  135.         if (*c1 == *(c2+8)  &&  (*c1 >= '|' || *c2 != '\0')) return(1);
  136.  
  137.         return(0);
  138.         }
  139.  
  140.     for (i=0; i<8; i++) {
  141.         if (*c1 == '\0') return(*c2 == ' ');
  142.         if (*c1++ != *c2++) return(0);
  143.         }
  144.  
  145.     return(1);
  146.     }
  147.  
  148.  
  149. intrp() {
  150.     register char *q;
  151.  
  152.     signal(2,1);
  153.     fout = 1;
  154.     *(&fout+1) = 1;
  155.     *(&fout+2) = 0;
  156.     *(&fout+3) = 0;
  157.  
  158.     q = ctime(buf+10);
  159.     printf("\ninterrupted at  %10.10s  %5.5s \n",
  160.         q, 11+q);
  161.  
  162.     exit();
  163.     }
  164. qintrp() {
  165.     register char *q;
  166.  
  167.     signal(3, &qintrp);
  168.     fout = 1;
  169.     *(&fout+1) = 1;
  170.     *(&fout+2) = 0;
  171.     *(&fout+3) = 0;
  172.  
  173.     q = ctime(buf+10);
  174.     printf("\ninterrupted at  %10.10s  %5.5s \n",
  175.         q, 11+q);
  176.  
  177.     }
  178.  
  179. /*
  180.  * NAMES:  bread(), brseek(), blseek()
  181.  *
  182.  * DESCRIPTION:
  183.  *     This is a buffered read package which simulates  read(), seek() and
  184.  *      lseek().
  185.  *       Bread may be called with a negative nbytes which causes it to
  186.  *      read backwards.  In this case, buffer should point to the first
  187.  *      byte following the buffer.  If only a partial read is possible
  188.  *      (due to beginning of file), only the last bytes of the buffer
  189.  *      will be filled.
  190.  */
  191.  
  192. int    i, j, k;
  193. int    nl, nr;
  194. char    *next;
  195. char    b[512];
  196.  
  197. bread(file, buff, nbytes)
  198. char *buff; {
  199.     register nb;
  200.  
  201.     if (nbytes > 0) {
  202.         for (nb=nbytes; nb>0; nb--) {
  203.             if (nr == 0) {
  204.                 nr = read(file, next=b, 512);
  205.                 nl = 0;
  206.                 if (nr < 0) return(-1);
  207.                 if (nr == 0) return(nbytes-nb);
  208.                 }
  209.             *buff++ = *next++;
  210.             nr--;
  211.             nl++;
  212.             }
  213.         }
  214.     else {
  215.         nbytes = -nbytes;
  216.         for (nb=nbytes; nb>0; nb--) {
  217.             if (nl == 0) {
  218.                 seek(file, -(512 + nr), 1);
  219.                 nl = read(file, b, 512);
  220.                 if (nl < 0) {
  221.                     for (k=511; k>0; k--) {
  222.                         seek(file, 1, 1);
  223.                         nl = read(file, b, k);
  224.                         if (nl >= 0) break;
  225.                         }
  226.                     if (nl < 0) return(nbytes-nb);
  227.                     }
  228.                 if (nl == 0) return(nbytes-nb);
  229.                 next = b + nl;
  230.                 nr = 0;
  231.                 }
  232.             *--buff = *--next;
  233.             nr++;
  234.             nl--;
  235.             }
  236.         }
  237.     return(nbytes);
  238.     }
  239.  
  240.  
  241. brseek(file, offset, flag) {
  242.     nl = 0;
  243.     nr = 0;
  244.     return(seek(file,offset,flag));
  245.     }
  246.  
  247.  
  248. blseek(file, offset, flag) 
  249. long offset; {
  250.     nl = 0;
  251.     nr = 0;
  252.     return(lseek(file,offset,flag));
  253.     }
  254.