Annotation of 43BSDReno/usr.bin/finger/util.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1989 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms are permitted provided
        !             9:  * that: (1) source distributions retain this entire copyright notice and
        !            10:  * comment, and (2) distributions including binaries display the following
        !            11:  * acknowledgement:  ``This product includes software developed by the
        !            12:  * University of California, Berkeley and its contributors'' in the
        !            13:  * documentation or other materials provided with the distribution and in
        !            14:  * all advertising materials mentioning features or use of this software.
        !            15:  * Neither the name of the University nor the names of its contributors may
        !            16:  * be used to endorse or promote products derived from this software without
        !            17:  * specific prior written permission.
        !            18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            19:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            20:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            21:  */
        !            22: 
        !            23: #ifndef lint
        !            24: static char sccsid[] = "@(#)util.c     5.13 (Berkeley) 6/24/90";
        !            25: #endif /* not lint */
        !            26: 
        !            27: #include <sys/param.h>
        !            28: #include <sys/stat.h>
        !            29: #include <sys/file.h>
        !            30: #include <stdio.h>
        !            31: #include <ctype.h>
        !            32: #include <string.h>
        !            33: #include <paths.h>
        !            34: #include "finger.h"
        !            35: 
        !            36: find_idle_and_ttywrite(w)
        !            37:        register WHERE *w;
        !            38: {
        !            39:        extern time_t now;
        !            40:        extern int errno;
        !            41:        struct stat sb;
        !            42:        char *strerror();
        !            43: 
        !            44:        (void)sprintf(tbuf, "%s/%s", _PATH_DEV, w->tty);
        !            45:        if (stat(tbuf, &sb) < 0) {
        !            46:                (void)fprintf(stderr,
        !            47:                    "finger: %s: %s\n", tbuf, strerror(errno));
        !            48:                exit(1);
        !            49:        }
        !            50:        w->idletime = now < sb.st_atime ? 0 : now - sb.st_atime;
        !            51: 
        !            52: #define        TALKABLE        0220            /* tty is writable if 220 mode */
        !            53:        w->writable = ((sb.st_mode & TALKABLE) == TALKABLE);
        !            54: }
        !            55: 
        !            56: userinfo(pn, pw)
        !            57:        register PERSON *pn;
        !            58:        register struct passwd *pw;
        !            59: {
        !            60:        register char *p, *t;
        !            61:        char *bp, name[1024];
        !            62: 
        !            63:        pn->realname = pn->office = pn->officephone = pn->homephone = NULL;
        !            64: 
        !            65:        pn->uid = pw->pw_uid;
        !            66:        pn->name = strdup(pw->pw_name);
        !            67:        pn->dir = strdup(pw->pw_dir);
        !            68:        pn->shell = strdup(pw->pw_shell);
        !            69: 
        !            70:        /* why do we skip asterisks!?!? */
        !            71:        (void)strcpy(bp = tbuf, pw->pw_gecos);
        !            72:        if (*bp == '*')
        !            73:                ++bp;
        !            74: 
        !            75:        /* ampersands get replaced by the login name */
        !            76:        if (!(p = strsep(&bp, ",")))
        !            77:                return;
        !            78:        for (t = name; *t = *p; ++p)
        !            79:                if (*t == '&') {
        !            80:                        (void)strcpy(t, pw->pw_name);
        !            81:                        if (islower(*t))
        !            82:                                *t = toupper(*t);
        !            83:                        while (*++t);
        !            84:                }
        !            85:                else
        !            86:                        ++t;
        !            87:        pn->realname = strdup(name);
        !            88:        pn->office = ((p = strsep(&bp, ",")) && *p) ?
        !            89:            strdup(p) : NULL;
        !            90:        pn->officephone = ((p = strsep(&bp, ",")) && *p) ?
        !            91:            strdup(p) : NULL;
        !            92:        pn->homephone = ((p = strsep(&bp, ",")) && *p) ?
        !            93:            strdup(p) : NULL;
        !            94: }
        !            95: 
        !            96: match(pw, user)
        !            97:        struct passwd *pw;
        !            98:        char *user;
        !            99: {
        !           100:        register char *p, *t;
        !           101:        char name[1024];
        !           102: 
        !           103:        /* why do we skip asterisks!?!? */
        !           104:        (void)strcpy(p = tbuf, pw->pw_gecos);
        !           105:        if (*p == '*')
        !           106:                ++p;
        !           107: 
        !           108:        /* ampersands get replaced by the login name */
        !           109:        if (!(p = strtok(p, ",")))
        !           110:                return(0);
        !           111:        for (t = name; *t = *p; ++p)
        !           112:                if (*t == '&') {
        !           113:                        (void)strcpy(t, pw->pw_name);
        !           114:                        while (*++t);
        !           115:                }
        !           116:                else
        !           117:                        ++t;
        !           118:        for (t = name; p = strtok(t, "\t "); t = (char *)NULL)
        !           119:                if (!strcasecmp(p, user))
        !           120:                        return(1);
        !           121:        return(0);
        !           122: }
        !           123: 
        !           124: enter_lastlog(pn)
        !           125:        register PERSON *pn;
        !           126: {
        !           127:        register WHERE *w;
        !           128:        static int opened, fd;
        !           129:        struct lastlog ll;
        !           130:        char doit = 0;
        !           131:        off_t lseek();
        !           132: 
        !           133:        /* some systems may not maintain lastlog, don't report errors. */
        !           134:        if (!opened) {
        !           135:                fd = open(_PATH_LASTLOG, O_RDONLY, 0);
        !           136:                opened = 1;
        !           137:        }
        !           138:        if (fd == -1 ||
        !           139:            lseek(fd, (long)pn->uid * sizeof(ll), L_SET) !=
        !           140:            (long)pn->uid * sizeof(ll) ||
        !           141:            read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) {
        !           142:                        /* as if never logged in */
        !           143:                        ll.ll_line[0] = ll.ll_host[0] = NULL;
        !           144:                        ll.ll_time = 0;
        !           145:                }
        !           146:        if ((w = pn->whead) == NULL)
        !           147:                doit = 1;
        !           148:        else if (ll.ll_time != 0) {
        !           149:                /* if last login is earlier than some current login */
        !           150:                for (; !doit && w != NULL; w = w->next)
        !           151:                        if (w->info == LOGGEDIN && w->loginat < ll.ll_time)
        !           152:                                doit = 1;
        !           153:                /*
        !           154:                 * and if it's not any of the current logins
        !           155:                 * can't use time comparison because there may be a small
        !           156:                 * discrepency since login calls time() twice
        !           157:                 */
        !           158:                for (w = pn->whead; doit && w != NULL; w = w->next)
        !           159:                        if (w->info == LOGGEDIN &&
        !           160:                            strncmp(w->tty, ll.ll_line, UT_LINESIZE) == 0)
        !           161:                                doit = 0;
        !           162:        }
        !           163:        if (doit) {
        !           164:                w = walloc(pn);
        !           165:                w->info = LASTLOG;
        !           166:                bcopy(ll.ll_line, w->tty, UT_LINESIZE);
        !           167:                w->tty[UT_LINESIZE] = 0;
        !           168:                bcopy(ll.ll_host, w->host, UT_HOSTSIZE);
        !           169:                w->host[UT_HOSTSIZE] = 0;
        !           170:                w->loginat = ll.ll_time;
        !           171:        }
        !           172: }
        !           173: 
        !           174: enter_where(ut, pn)
        !           175:        struct utmp *ut;
        !           176:        PERSON *pn;
        !           177: {
        !           178:        register WHERE *w = walloc(pn);
        !           179: 
        !           180:        w->info = LOGGEDIN;
        !           181:        bcopy(ut->ut_line, w->tty, UT_LINESIZE);
        !           182:        w->tty[UT_LINESIZE] = 0;
        !           183:        bcopy(ut->ut_host, w->host, UT_HOSTSIZE);
        !           184:        w->host[UT_HOSTSIZE] = 0;
        !           185:        w->loginat = (time_t)ut->ut_time;
        !           186:        find_idle_and_ttywrite(w);
        !           187: }
        !           188: 
        !           189: PERSON *
        !           190: enter_person(pw)
        !           191:        register struct passwd *pw;
        !           192: {
        !           193:        register PERSON *pn, **pp;
        !           194: 
        !           195:        for (pp = htab + hash(pw->pw_name);
        !           196:             *pp != NULL && strcmp((*pp)->name, pw->pw_name) != 0;
        !           197:             pp = &(*pp)->hlink)
        !           198:                ;
        !           199:        if ((pn = *pp) == NULL) {
        !           200:                pn = palloc();
        !           201:                entries++;
        !           202:                if (phead == NULL)
        !           203:                        phead = ptail = pn;
        !           204:                else {
        !           205:                        ptail->next = pn;
        !           206:                        ptail = pn;
        !           207:                }
        !           208:                pn->next = NULL;
        !           209:                pn->hlink = NULL;
        !           210:                *pp = pn;
        !           211:                userinfo(pn, pw);
        !           212:                pn->whead = NULL;
        !           213:        }
        !           214:        return(pn);
        !           215: }
        !           216: 
        !           217: PERSON *
        !           218: find_person(name)
        !           219:        char *name;
        !           220: {
        !           221:        register PERSON *pn;
        !           222: 
        !           223:        /* name may be only UT_NAMESIZE long and not terminated */
        !           224:        for (pn = htab[hash(name)];
        !           225:             pn != NULL && strncmp(pn->name, name, UT_NAMESIZE) != 0;
        !           226:             pn = pn->hlink)
        !           227:                ;
        !           228:        return(pn);
        !           229: }
        !           230: 
        !           231: hash(name)
        !           232:        register char *name;
        !           233: {
        !           234:        register int h, i;
        !           235: 
        !           236:        h = 0;
        !           237:        /* name may be only UT_NAMESIZE long and not terminated */
        !           238:        for (i = UT_NAMESIZE; --i >= 0 && *name;)
        !           239:                h = ((h << 2 | h >> HBITS - 2) ^ *name++) & HMASK;
        !           240:        return(h);
        !           241: }
        !           242: 
        !           243: PERSON *
        !           244: palloc()
        !           245: {
        !           246:        PERSON *p;
        !           247: 
        !           248:        if ((p = (PERSON *)malloc((u_int) sizeof(PERSON))) == NULL) {
        !           249:                (void)fprintf(stderr, "finger: out of space.\n");
        !           250:                exit(1);
        !           251:        }
        !           252:        return(p);
        !           253: }
        !           254: 
        !           255: WHERE *
        !           256: walloc(pn)
        !           257:        register PERSON *pn;
        !           258: {
        !           259:        register WHERE *w;
        !           260: 
        !           261:        if ((w = (WHERE *)malloc((u_int) sizeof(WHERE))) == NULL) {
        !           262:                (void)fprintf(stderr, "finger: out of space.\n");
        !           263:                exit(1);
        !           264:        }
        !           265:        if (pn->whead == NULL)
        !           266:                pn->whead = pn->wtail = w;
        !           267:        else {
        !           268:                pn->wtail->next = w;
        !           269:                pn->wtail = w;
        !           270:        }
        !           271:        w->next = NULL;
        !           272:        return(w);
        !           273: }
        !           274: 
        !           275: char *
        !           276: prphone(num)
        !           277:        char *num;
        !           278: {
        !           279:        register char *p;
        !           280:        int len;
        !           281:        static char pbuf[15];
        !           282: 
        !           283:        /* don't touch anything if the user has their own formatting */
        !           284:        for (p = num; *p; ++p)
        !           285:                if (!isdigit(*p))
        !           286:                        return(num);
        !           287:        len = p - num;
        !           288:        p = pbuf;
        !           289:        switch(len) {
        !           290:        case 11:                        /* +0-123-456-7890 */
        !           291:                *p++ = '+';
        !           292:                *p++ = *num++;
        !           293:                *p++ = '-';
        !           294:                /* FALLTHROUGH */
        !           295:        case 10:                        /* 012-345-6789 */
        !           296:                *p++ = *num++;
        !           297:                *p++ = *num++;
        !           298:                *p++ = *num++;
        !           299:                *p++ = '-';
        !           300:                /* FALLTHROUGH */
        !           301:        case 7:                         /* 012-3456 */
        !           302:                *p++ = *num++;
        !           303:                *p++ = *num++;
        !           304:                *p++ = *num++;
        !           305:                break;
        !           306:        case 5:                         /* x0-1234 */
        !           307:                *p++ = 'x';
        !           308:                *p++ = *num++;
        !           309:                break;
        !           310:        default:
        !           311:                return(num);
        !           312:        }
        !           313:        *p++ = '-';
        !           314:        *p++ = *num++;
        !           315:        *p++ = *num++;
        !           316:        *p++ = *num++;
        !           317:        *p++ = *num++;
        !           318:        *p = '\0';
        !           319:        return(pbuf);
        !           320: }

unix.superglobalmegacorp.com

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