|
|
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: char copyright[] = ! 25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: #endif /* not lint */ ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)finger.c 5.21 (Berkeley) 6/24/90"; ! 31: #endif /* not lint */ ! 32: ! 33: /* ! 34: * Finger prints out information about users. It is not portable since ! 35: * certain fields (e.g. the full user name, office, and phone numbers) are ! 36: * extracted from the gecos field of the passwd file which other UNIXes ! 37: * may not have or may use for other things. ! 38: * ! 39: * There are currently two output formats; the short format is one line ! 40: * per user and displays login name, tty, login time, real name, idle time, ! 41: * and office location/phone number. The long format gives the same ! 42: * information (in a more legible format) as well as home directory, shell, ! 43: * mail info, and .plan/.project files. ! 44: */ ! 45: ! 46: #include <sys/param.h> ! 47: #include <sys/file.h> ! 48: #include <stdio.h> ! 49: #include "finger.h" ! 50: ! 51: time_t now; ! 52: int lflag, sflag, mflag, pplan; ! 53: char tbuf[1024]; ! 54: ! 55: main(argc, argv) ! 56: int argc; ! 57: char **argv; ! 58: { ! 59: extern int optind; ! 60: int ch; ! 61: time_t time(); ! 62: ! 63: while ((ch = getopt(argc, argv, "lmps")) != EOF) ! 64: switch(ch) { ! 65: case 'l': ! 66: lflag = 1; /* long format */ ! 67: break; ! 68: case 'm': ! 69: mflag = 1; /* force exact match of names */ ! 70: break; ! 71: case 'p': ! 72: pplan = 1; /* don't show .plan/.project */ ! 73: break; ! 74: case 's': ! 75: sflag = 1; /* short format */ ! 76: break; ! 77: case '?': ! 78: default: ! 79: (void)fprintf(stderr, ! 80: "usage: finger [-lmps] [login ...]\n"); ! 81: exit(1); ! 82: } ! 83: argc -= optind; ! 84: argv += optind; ! 85: ! 86: (void)time(&now); ! 87: setpassent(1); ! 88: if (!*argv) { ! 89: /* ! 90: * Assign explicit "small" format if no names given and -l ! 91: * not selected. Force the -s BEFORE we get names so proper ! 92: * screening will be done. ! 93: */ ! 94: if (!lflag) ! 95: sflag = 1; /* if -l not explicit, force -s */ ! 96: loginlist(); ! 97: if (entries == 0) ! 98: (void)printf("No one logged on.\n"); ! 99: } else { ! 100: userlist(argc, argv); ! 101: /* ! 102: * Assign explicit "large" format if names given and -s not ! 103: * explicitly stated. Force the -l AFTER we get names so any ! 104: * remote finger attempts specified won't be mishandled. ! 105: */ ! 106: if (!sflag) ! 107: lflag = 1; /* if -s not explicit, force -l */ ! 108: } ! 109: if (entries != 0) { ! 110: if (lflag) ! 111: lflag_print(); ! 112: else ! 113: sflag_print(); ! 114: } ! 115: exit(0); ! 116: } ! 117: ! 118: loginlist() ! 119: { ! 120: register PERSON *pn; ! 121: struct passwd *pw; ! 122: struct utmp user; ! 123: char name[UT_NAMESIZE + 1]; ! 124: ! 125: if (!freopen(_PATH_UTMP, "r", stdin)) { ! 126: (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP); ! 127: exit(2); ! 128: } ! 129: name[UT_NAMESIZE] = NULL; ! 130: while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { ! 131: if (!user.ut_name[0]) ! 132: continue; ! 133: if ((pn = find_person(user.ut_name)) == NULL) { ! 134: bcopy(user.ut_name, name, UT_NAMESIZE); ! 135: if ((pw = getpwnam(name)) == NULL) ! 136: continue; ! 137: pn = enter_person(pw); ! 138: } ! 139: enter_where(&user, pn); ! 140: } ! 141: for (pn = phead; lflag && pn != NULL; pn = pn->next) ! 142: enter_lastlog(pn); ! 143: } ! 144: ! 145: userlist(argc, argv) ! 146: register argc; ! 147: register char **argv; ! 148: { ! 149: register i; ! 150: register PERSON *pn; ! 151: PERSON *nethead; ! 152: struct utmp user; ! 153: struct passwd *pw; ! 154: int dolocal, *used; ! 155: char *index(); ! 156: ! 157: if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) { ! 158: (void)fprintf(stderr, "finger: out of space.\n"); ! 159: exit(1); ! 160: } ! 161: ! 162: /* pull out all network requests */ ! 163: for (i = 0, dolocal = 0, nethead = NULL; i < argc; i++) { ! 164: if (!index(argv[i], '@')) { ! 165: dolocal = 1; ! 166: continue; ! 167: } ! 168: pn = palloc(); ! 169: pn->next = nethead; ! 170: nethead = pn; ! 171: pn->name = argv[i]; ! 172: used[i] = -1; ! 173: } ! 174: ! 175: if (!dolocal) ! 176: goto net; ! 177: ! 178: /* ! 179: * traverse the list of possible login names and check the login name ! 180: * and real name against the name specified by the user. ! 181: */ ! 182: if (mflag) { ! 183: for (i = 0; i < argc; i++) ! 184: if (used[i] >= 0 && (pw = getpwnam(argv[i]))) { ! 185: enter_person(pw); ! 186: used[i] = 1; ! 187: } ! 188: } else while (pw = getpwent()) ! 189: for (i = 0; i < argc; i++) ! 190: if (used[i] >= 0 && ! 191: (!strcasecmp(pw->pw_name, argv[i]) || ! 192: match(pw, argv[i]))) { ! 193: enter_person(pw); ! 194: used[i] = 1; ! 195: } ! 196: ! 197: /* list errors */ ! 198: for (i = 0; i < argc; i++) ! 199: if (!used[i]) ! 200: (void)fprintf(stderr, ! 201: "finger: %s: no such user.\n", argv[i]); ! 202: ! 203: /* handle network requests */ ! 204: net: for (pn = nethead; pn; pn = pn->next) { ! 205: netfinger(pn->name); ! 206: if (pn->next || entries) ! 207: putchar('\n'); ! 208: } ! 209: ! 210: if (entries == 0) ! 211: return; ! 212: ! 213: /* ! 214: * Scan thru the list of users currently logged in, saving ! 215: * appropriate data whenever a match occurs. ! 216: */ ! 217: if (!freopen(_PATH_UTMP, "r", stdin)) { ! 218: (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP); ! 219: exit(1); ! 220: } ! 221: while (fread((char *)&user, sizeof(user), 1, stdin) == 1) { ! 222: if (!user.ut_name[0]) ! 223: continue; ! 224: if ((pn = find_person(user.ut_name)) == NULL) ! 225: continue; ! 226: enter_where(&user, pn); ! 227: } ! 228: for (pn = phead; pn != NULL; pn = pn->next) ! 229: enter_lastlog(pn); ! 230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.