# 2.11BSD#431 - /usr/src/ucb/finger/util.c

##### Functions

    enter_lastlog     X
    enter_person      X
    enter_where       X
    find_idle_and_ttywriteX
    find_person       X
    hash              X
    match             X
    palloc            X
    prphone           X
    userinfo          X
    walloc            X

##### Macros

    TALKABLE          X

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

#### Defined functions

enter_lastlog defined in line 123; used 2 times

- in /usr/src/ucb/finger/finger.c line 141, 228

enter_person defined in line 188; used 4 times

- in /usr/src/ucb/finger/finger.c line 136, 184, 192
- in /usr/src/ucb/finger/finger.h line 66

enter_where defined in line 173; used 2 times

- in /usr/src/ucb/finger/finger.c line 138, 225

find_idle_and_ttywrite defined in line 35; used 1 times

- in line 185

find_person defined in line 216; used 3 times

- in /usr/src/ucb/finger/finger.c line 132, 223
- in /usr/src/ucb/finger/finger.h line 66

hash defined in line 230; used 2 times

- in line 194, 223

match defined in line 95; used 1 times

- in /usr/src/ucb/finger/finger.c line 191

palloc defined in line 242; used 3 times

- in line 199
- in /usr/src/ucb/finger/finger.c line 167
- in /usr/src/ucb/finger/finger.h line 66

prphone defined in line 274; used 6 times

- in /usr/src/ucb/finger/lprint.c line 67, 92, 101, 107
- in /usr/src/ucb/finger/sprint.c line 42, 96

userinfo defined in line 54; used 1 times

- in line 210

walloc defined in line 254; used 3 times

- in line 163, 177
- in /usr/src/ucb/finger/finger.h line 67

#### Defined variables

sccsid defined in line 22; never used

#### Defined macros

TALKABLE defined in line 50; used 2 times

- in line 51(2)

Last modified: 1996-01-13 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1598 |