Annotation of 3BSD/cmd/last.c, revision 1.1.1.1

1.1       root        1: #
                      2: /*
                      3:  * NAME: last
                      4:  *
                      5:  * SYNOPSIS: last [list]
                      6:  *
                      7:  * DESCRIPTION: Displays login history of named users or tty's.
                      8:  *             Last with no argument prints history for all users.
                      9:  *
                     10:  * AUTHOR - Howard P. Katseff
                     11:  */
                     12: 
                     13: # include <sys/types.h>
                     14: # include <stdio.h>
                     15: # include <stat.h>
                     16: # include <utmp.h>
                     17: 
                     18: char   yes =   1,
                     19:        no  =   0,
                     20: 
                     21:        *wtmp = "/usr/adm/wtmp",
                     22:        b [512],
                     23: 
                     24:        Arg       [25] [9],
                     25:        tty_names [48] [9],
                     26: 
                     27:        *ctime  (),
                     28:        *move   (),
                     29:        *rmchar ();
                     30: 
                     31: 
                     32: long   logouts [48],
                     33:        bl,
                     34:        rec,
                     35:        nblock;
                     36: 
                     37: struct utmp buf [128]; /* buf takes exactly 5 blocks */
                     38: 
                     39: main (argc, argv)
                     40: char **argv;
                     41: {
                     42:        char    f,
                     43:                narg,
                     44: 
                     45:                *bend,
                     46:                *p,
                     47:                *q;
                     48: 
                     49:        short   n_byte,
                     50:                n_record;
                     51: 
                     52:        long    i,
                     53:                k,
                     54:                ntime,
                     55:                otime,
                     56: 
                     57:                intrp ();
                     58: 
                     59:        struct  stat sbuf;
                     60:  
                     61:        for (i = 1; i < argc; i++)
                     62:        {
                     63:                if
                     64:                (
                     65:                        length (argv [i]) > 2 /* long tty or user name */
                     66:                        ||
                     67:                        equal (argv [i], "~") /* tilde */
                     68:                        ||
                     69:                        getpwnam (argv [i]) /* user name */
                     70:                )
                     71:                {
                     72:                        move (argv [i], Arg [narg++]);
                     73:                }
                     74:                else /* short tty name */
                     75:                {
                     76:                        move (argv [i], move ("tty", Arg [narg++]));
                     77:                }
                     78:        }
                     79:        f = open (wtmp, 0);
                     80:        if (f < 0)
                     81:        {
                     82:                perror (wtmp);
                     83:                fflush (stdout);
                     84:                exit ();
                     85:        }
                     86:        if (fstat (f, &sbuf) < 0)
                     87:        {
                     88:                perror ("/usr/adm/wtmp");
                     89:                fflush (stdout);
                     90:                exit ();
                     91:        }
                     92:        nblock = (sbuf.st_size + 2559) / 2560;
                     93:        signal (2, intrp);
                     94:        for (bl = nblock - 1; bl >= 0; bl--)
                     95:        {
                     96:                lseek (f, bl * 2560, 0);
                     97:                n_byte = read (f, buf, 2560);
                     98:                n_record = n_byte / sizeof buf [0];
                     99:                for (rec = n_record - 1; rec >= 0; rec--)
                    100:                {
                    101:                        
                    102:                        if (should_print ())
                    103:                        {
                    104:                                q = ctime (&buf[rec].ut_time);
                    105:                                printf
                    106:                                (
                    107:                                        "%-8.8s  %-8.8s  %10.10s %5.5s ",
                    108:                                        buf[rec].ut_name, buf[rec].ut_line, q, 11+q
                    109:                                );
                    110:                                otime = buf[rec].ut_time;
                    111:                        /*
                    112:                         * look up the logout time for the tty
                    113:                         */
                    114:                                for (i = 0;; i++)
                    115:                                {
                    116:                                        if (!*tty_names [i])
                    117:                                        /* not in the table, therefore add it */
                    118:                                        {
                    119:                                                move
                    120:                                                (
                    121:                                                        buf[rec].ut_line,
                    122:                                                        tty_names [i]
                    123:                                                );
                    124:                                                ntime = 0;
                    125:                                                break;
                    126:                                        }
                    127:                                        if
                    128:                                        (
                    129:                                                equal
                    130:                                                (
                    131:                                                        tty_names [i],
                    132:                                                        buf [rec].ut_line
                    133:                                                )
                    134:                                        )
                    135:                                        {
                    136:                                                ntime = logouts [i];
                    137:                                                break;
                    138:                                        }
                    139:                                }
                    140:                                if (ntime == 0)
                    141:                                {
                    142:                                        printf ("  still logged in\n");
                    143:                                }
                    144:                                else
                    145:                                {
                    146:                                        if (ntime < 0)
                    147:                                        {
                    148:                                                ntime = -ntime;
                    149:                                                printf ("- crash");
                    150:                                        }
                    151:                                        else 
                    152:                                        {
                    153:                                                printf ("- %5.5s", ctime (&ntime) + 11);
                    154:                                        }
                    155:                                /*
                    156:                                 * calculate how long logged in
                    157:                                 */
                    158:                                        otime = ntime - otime;
                    159:                                        otime += 231220830 + 10800;
                    160:                                        if (otime < 231220830 + 86400 + 10800)
                    161:                                        {
                    162:                                                printf
                    163:                                                (
                    164:                                                        "  (%5.5s)\n",
                    165:                                                        ctime (&otime) + 11
                    166:                                                );
                    167:                                        }
                    168:                                        else
                    169:                                        {
                    170:                                                printf
                    171:                                                (
                    172:                                                        " (%ld+%5.5s)\n",
                    173:                                                        (otime -
                    174:                                                        (231330830-86400-10800))/86400,
                    175:                                                        ctime (&otime) + 11
                    176:                                                );
                    177:                                        }
                    178:                                }
                    179:                                fflush (stdout);
                    180:                        }
                    181:                        if
                    182:                        (
                    183:                                equal (buf[rec].ut_line, "~")
                    184:                                ||
                    185:                                equal (buf[rec].ut_line, "tty~")
                    186:                        )
                    187:                        {
                    188:                                for (i = 0; *tty_names [i]; i++)
                    189:                                {
                    190:                                        logouts [i] = -buf[rec].ut_time;
                    191:                                }
                    192:                        }
                    193:                        else
                    194:                        {
                    195:                                for (k = 0;; k++)
                    196:                                {
                    197:                                        if (!*tty_names [k])
                    198:                                        {
                    199:                                                move
                    200:                                                (
                    201:                                                        buf[rec].ut_line,
                    202:                                                        tty_names [k]
                    203:                                                );
                    204:                                                logouts [k] = buf[rec].ut_time;
                    205:                                                break;
                    206:                                        }
                    207:                                        if (equal (tty_names [k], buf[rec].ut_line))
                    208:                                        {
                    209:                                                logouts [k] = buf[rec].ut_time;
                    210:                                                break;
                    211:                                        }
                    212:                                }
                    213:                        }
                    214:                }
                    215:        }
                    216:        q = ctime (&buf [0].ut_time);
                    217:        printf
                    218:        (
                    219:                "\nwtmp begins %10.10s %5.5s \n",
                    220:                q, q + 11
                    221:        );
                    222: }
                    223: 
                    224: equal (a, b)
                    225: char *a, *b;
                    226: {
                    227:        char i;
                    228: 
                    229:        for (i = 0; i < 8; i++)
                    230:        {
                    231:                if (!*a) return (!*b);
                    232:                if (*a++ != *b++) return (0);
                    233:        }
                    234:        return (1);
                    235: }
                    236: 
                    237: 
                    238: intrp ()
                    239: {
                    240:        char *q;
                    241: 
                    242:        signal (2, 1); /* ignore further interrupts */
                    243:        q = ctime (&buf[rec].ut_time);
                    244:        printf
                    245:        (
                    246:                "\ninterrupted %10.10s %5.5s \n",
                    247:                q, q + 11
                    248:        );
                    249:        exit ();
                    250: }
                    251: 
                    252: char *
                    253: rmchar (c, s)
                    254: char c, *s;
                    255: {
                    256:        for (; *s; s++)
                    257:        {
                    258:                if (*s == c)
                    259:                {
                    260:                        *s = 0;
                    261:                        return (s);
                    262:                }
                    263:        }
                    264:        return (0);
                    265: }
                    266: 
                    267: length (a)
                    268: char *a;
                    269: {
                    270:        char *b;
                    271: 
                    272:        for (b = a; *b; b++);
                    273:        return (b - a);
                    274: }
                    275: 
                    276: char *
                    277: move (a, b)
                    278: char *a, *b;
                    279: {
                    280:        while (*b++ = *a++);
                    281:        return (b - 1);
                    282: }
                    283: 
                    284: should_print ()
                    285: {
                    286:        short i;
                    287: 
                    288:        if (buf [rec].ut_name [0] == no) return no; /* a logout entry */
                    289:        if (!**Arg) return yes; /* no arguments? Print all login entries */
                    290:        for (i = 0; i < *Arg [i]; i++)
                    291:        {
                    292:                if 
                    293:                (
                    294:                        equal (Arg [i], buf[rec].ut_name)
                    295:                        ||
                    296:                        equal (Arg [i], buf[rec].ut_line)
                    297:                )
                    298:                return yes;
                    299:        }
                    300:        return no;
                    301: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.