1 #ifndef lint 2 static char *sccsid = "@(#)last.c 4.8 (Berkeley) 09/25/83"; 3 #endif 4 5 /* 6 * last 7 */ 8 #include <sys/types.h> 9 #include <stdio.h> 10 #include <signal.h> 11 #include <sys/stat.h> 12 #include <utmp.h> 13 14 #define NMAX sizeof(buf[0].ut_name) 15 #define LMAX sizeof(buf[0].ut_line) 16 #define HMAX sizeof(buf[0].ut_host) 17 #define SECDAY (24*60*60) 18 19 #define lineq(a,b) (!strncmp(a,b,LMAX)) 20 #define nameq(a,b) (!strncmp(a,b,NMAX)) 21 #define hosteq(a,b) (!strncmp(a,b,HMAX)) 22 23 #define MAXTTYS 256 24 25 char **argv; 26 int argc; 27 int nameargs; 28 29 struct utmp buf[128]; 30 char ttnames[MAXTTYS][LMAX+1]; 31 long logouts[MAXTTYS]; 32 33 char *ctime(), *strspl(); 34 int onintr(); 35 36 main(ac, av) 37 char **av; 38 { 39 register int i, k; 40 int bl, wtmp; 41 char *ct; 42 register struct utmp *bp; 43 long otime; 44 struct stat stb; 45 int print; 46 char * crmsg = (char *)0; 47 long crtime; 48 long outrec = 0; 49 long maxrec = 0x7fffffffL; 50 51 time(&buf[0].ut_time); 52 ac--, av++; 53 nameargs = argc = ac; 54 argv = av; 55 for (i = 0; i < argc; i++) { 56 if (argv[i][0] == '-' && 57 argv[i][1] >= '0' && argv[i][1] <= '9') { 58 maxrec = atoi(argv[i]+1); 59 nameargs--; 60 continue; 61 } 62 if (strlen(argv[i])>2) 63 continue; 64 if (!strcmp(argv[i], "~")) 65 continue; 66 if (!strcmp(argv[i], "ftp")) 67 continue; 68 if (getpwnam(argv[i])) 69 continue; 70 argv[i] = strspl("tty", argv[i]); 71 } 72 wtmp = open("/usr/adm/wtmp", 0); 73 if (wtmp < 0) { 74 perror("/usr/adm/wtmp"); 75 exit(1); 76 } 77 fstat(wtmp, &stb); 78 bl = (stb.st_size + sizeof (buf)-1) / sizeof (buf); 79 if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 80 signal(SIGINT, onintr); 81 signal(SIGQUIT, onintr); 82 } 83 for (bl--; bl >= 0; bl--) { 84 lseek(wtmp, bl * sizeof (buf), 0); 85 bp = &buf[read(wtmp, buf, sizeof (buf)) / sizeof(buf[0]) - 1]; 86 for ( ; bp >= buf; bp--) { 87 print = want(bp); 88 if (print) { 89 ct = ctime(&bp->ut_time); 90 printf("%-*.*s %-*.*s %-*.*s %10.10s %5.5s ", 91 NMAX, NMAX, bp->ut_name, 92 LMAX, LMAX, bp->ut_line, 93 HMAX, HMAX, bp->ut_host, 94 ct, 11+ct); 95 } 96 for (i = 0; i < MAXTTYS; i++) { 97 if (ttnames[i][0] == 0) { 98 strncpy(ttnames[i], bp->ut_line, 99 sizeof(bp->ut_line)); 100 otime = logouts[i]; 101 logouts[i] = bp->ut_time; 102 break; 103 } 104 if (lineq(ttnames[i], bp->ut_line)) { 105 otime = logouts[i]; 106 logouts[i] = bp->ut_time; 107 break; 108 } 109 } 110 if (print) { 111 if (lineq(bp->ut_line, "~")) 112 printf("\n"); 113 else if (otime == 0) 114 printf(" still logged in\n"); 115 else { 116 long delta; 117 if (otime < 0) { 118 otime = -otime; 119 printf("- %s", crmsg); 120 } else 121 printf("- %5.5s", 122 ctime(&otime)+11); 123 delta = otime - bp->ut_time; 124 if (delta < SECDAY) 125 printf(" (%5.5s)\n", 126 asctime(gmtime(&delta))+11); 127 else 128 printf(" (%ld+%5.5s)\n", 129 delta / SECDAY, 130 asctime(gmtime(&delta))+11); 131 } 132 fflush(stdout); 133 if (++outrec >= maxrec) 134 exit(0); 135 } 136 if (lineq(bp->ut_line, "~")) { 137 for (i = 0; i < MAXTTYS; i++) 138 logouts[i] = -bp->ut_time; 139 if (nameq(bp->ut_name, "shutdown")) 140 crmsg = "down "; 141 else 142 crmsg = "crash"; 143 } 144 } 145 } 146 ct = ctime(&buf[0].ut_time); 147 printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11); 148 exit(0); 149 } 150 151 onintr(signo) 152 int signo; 153 { 154 char *ct; 155 156 if (signo == SIGQUIT) 157 signal(SIGQUIT, onintr); 158 ct = ctime(&buf[0].ut_time); 159 printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11); 160 if (signo == SIGINT) 161 exit(1); 162 } 163 164 want(bp) 165 struct utmp *bp; 166 { 167 register char **av; 168 register int ac; 169 170 if (bp->ut_line[0] == '~' && bp->ut_name[0] == '\0') 171 strcpy(bp->ut_name, "reboot"); /* bandaid */ 172 if (strncmp(bp->ut_line, "ftp", 3) == 0) 173 bp->ut_line[3] = '\0'; 174 if (bp->ut_name[0] == 0) 175 return (0); 176 if (nameargs == 0) 177 return (1); 178 av = argv; 179 for (ac = 0; ac < argc; ac++, av++) { 180 if (av[0][0] == '-') 181 continue; 182 if (nameq(*av, bp->ut_name) || lineq(*av, bp->ut_line)) 183 return (1); 184 } 185 return (0); 186 } 187 188 char * 189 strspl(left, right) 190 char *left, *right; 191 { 192 char *res = (char *)malloc(strlen(left)+strlen(right)+1); 193 194 strcpy(res, left); 195 strcat(res, right); 196 return (res); 197 } 198