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
enter_person defined in line 188; used 4 times
enter_where defined in line 173; used 2 times
find_idle_and_ttywrite defined in line 35; used 1 times
find_person defined in line 216; used 3 times
hash defined in line 230; used 2 times
match defined in line 95; used 1 times
palloc defined in line 242; used 3 times
prphone defined in line 274; used 6 times
userinfo defined in line 54; used 1 times
walloc defined in line 254; used 3 times

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: 4374
Valid CSS Valid XHTML 1.0 Strict