home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume5 / pd-last / last.c < prev   
Encoding:
C/C++ Source or Header  |  1989-02-03  |  2.9 KB  |  135 lines

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <utmp.h>
  6.  
  7.  
  8. #define     OWTMP_FILE        "/usr/adm/acct/nite/owtmp"        /* file to search after /etc/wtmp */
  9.  
  10. static char *prog;
  11. static char *wtmpfile[] = { OWTMP_FILE, WTMP_FILE, NULL };
  12.  
  13. struct list {
  14.         struct utmp rec;
  15.         struct list *next;
  16.         struct list *previous;
  17. };
  18.  
  19.  
  20.  
  21. main(argc, argv)            /* last: show recent logins in last-to-first order */
  22. int argc;
  23. char *argv[];
  24. {
  25.     int    i;
  26.     void   prproc();
  27.     struct list *listp = NULL, *p, *addlist();
  28.     struct utmp *entry;
  29.     extern void utmpname();
  30.     extern struct utmp *getutent();
  31.  
  32.     prog = argv[0];
  33.  
  34.     for (i = 0; wtmpfile[i] != NULL; i++) {
  35.         utmpname(wtmpfile[i]);
  36.         while ((entry = getutent()) != NULL)
  37.             listp = addlist(listp, entry);
  38.     }
  39.  
  40.     /* listp points to most recent wtmp entry */
  41.  
  42.     for (p = listp; p != NULL; p = p->previous)
  43.         if (p->rec.ut_type == USER_PROCESS) {
  44.             if (argc == 1)
  45.                 prproc(p, listp);
  46.             else
  47.                 for (i = 1; i < argc; i++) {
  48.                     if (strcmp(p->rec.ut_user, argv[i]) == 0) {
  49.                         prproc(p, listp);
  50.                         break;
  51.                     }
  52.                 }
  53.         }
  54.  
  55.     return (0);
  56. }
  57.  
  58.  
  59.  
  60. struct list *addlist(head, wtmp)    /* add new wtmp entry to head of list */
  61. struct list *head;
  62. struct utmp *wtmp;
  63. {
  64.     void     errexit();
  65.     register struct list *new;
  66.     extern     char *malloc();
  67.  
  68.     if ((new = (struct list *) malloc(sizeof(struct list))) == NULL)
  69.         errexit("memory error", NULL);
  70.     else {
  71.         new->rec = *wtmp;
  72.         new->next = new;        /* no next yet */
  73.         new->previous = head;
  74.         if (head != NULL)
  75.             head->next = new;
  76.     }
  77.     return (new);
  78. }
  79.  
  80.  
  81.  
  82. void prproc(start, last)        /* print entries for process */
  83. struct list *start, *last;
  84. {
  85.     void     prentry();
  86.     register struct list *p;
  87.  
  88.     prentry(start->rec);
  89.     for (p = start->next; p != last; p = p->next)
  90.         if (p->rec.ut_pid == start->rec.ut_pid)
  91.             prentry(p->rec);
  92.     putchar('\n');
  93. }
  94.  
  95.  
  96.     
  97. void prentry(wtmp)            /* print wtmp entry */
  98. struct utmp wtmp;
  99. {
  100.     static char *wkday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  101.     static char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  102.  
  103.     char   line[12 + 1], user[8 + 1];            /* magic numbers courtesy of /usr/include/utmp.h */
  104.     struct tm *time;
  105.     extern struct tm *localtime();
  106.  
  107.     strncpy(line, wtmp.ut_line, 12);
  108.     strncpy(user, wtmp.ut_user, 8);
  109.     line[12] = user[8] = '\0';
  110.     time = localtime(&wtmp.ut_time);
  111.     switch (wtmp.ut_type) {
  112.     case USER_PROCESS:
  113.         printf("%-8s %-12s %s %s %2d %02d:%02d",
  114.             user, line, wkday[time->tm_wday], month[time->tm_mon], time->tm_mday, time->tm_hour, time->tm_min);
  115.         break;
  116.     case DEAD_PROCESS:
  117.         printf("  -  %02d:%02d %s", time->tm_hour, time->tm_min, wkday[time->tm_wday]);
  118.         break;
  119.     default:
  120.         sprintf(line, "%d", wtmp.ut_type);
  121.         errexit("illegal wtmp.ut_type entry:", line);
  122.     }
  123. }
  124.  
  125.  
  126.  
  127. void errexit(s1, s2)            /* print error message and die */
  128. char s1[], s2[];
  129. {
  130.     extern void exit();
  131.  
  132.     fprintf(stderr, s2 == NULL ? "%s: %s\n" : "%s: %s %s\n", prog, s1, s2);
  133.     exit(-1);
  134. }
  135.