Annotation of 3BSD/cmd/last.c, revision 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.