[BACK]Return to util.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / finger

Annotation of src/usr.bin/finger/util.c, Revision 1.1

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