|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.