00001
00002
00003
00004
00005
00006
00007 #ifndef lint
00008 static char sccsid[] = "@(#)finger.c 1.1 87/12/21 SMI";
00009 #endif
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <sys/types.h>
00047 #include <ctype.h>
00048 #include <errno.h>
00049 #include <fcntl.h>
00050 #include <pwd.h>
00051 #include <stdio.h>
00052 #include <stdlib.h>
00053 #include <string.h>
00054 #include <time.h>
00055 #include <unistd.h>
00056 #include <utmp.h>
00057 #include <sys/ioctl.h>
00058 #include <sys/stat.h>
00059 #include <net/gen/in.h>
00060 #include <net/gen/inet.h>
00061 #include <net/gen/netdb.h>
00062 #include <net/gen/socket.h>
00063 #include <net/gen/tcp.h>
00064 #include <net/gen/tcp_hdr.h>
00065 #include <net/gen/tcp_io.h>
00066 #include <net/hton.h>
00067 #include <net/netlib.h>
00068
00069 #define NONOTHING 1
00070
00071 #define NONET 0
00072
00073 #define ASTERISK '*'
00074 #define COMMA ','
00075 #define COMMAND '-'
00076 #define SAMENAME '&'
00077 #define TALKABLE 0220
00078
00079 struct utmp user;
00080 #define NMAX sizeof(user.ut_name)
00081 #define LMAX sizeof(user.ut_line)
00082 #define HMAX sizeof(user.ut_host)
00083
00084 struct person {
00085 char *name;
00086 char tty[LMAX+1];
00087 char host[HMAX+1];
00088 long loginat;
00089 long idletime;
00090 char *realname;
00091 struct passwd *pwd;
00092 char loggedin;
00093 char writable;
00094 char original;
00095 struct person *link;
00096 char *where;
00097 char hostt[HMAX+1];
00098 };
00099
00100 #include <minix/paths.h>
00101
00102 char LASTLOG[] = _PATH_LASTLOG;
00103 char USERLOG[] = _PATH_UTMP;
00104 char PLAN[] = "/.plan";
00105 char PROJ[] = "/.project";
00106
00107 int unbrief = 1;
00108 int header = 1;
00109 int hack = 1;
00110 int idle = 0;
00111 int large = 0;
00112 int match = 1;
00113 int plan = 1;
00114 int unquick = 1;
00115 int small = 0;
00116 int wide = 1;
00117
00118 int unshort;
00119 int lf;
00120 struct person *person1;
00121 long tloc;
00122
00123 #if !_MINIX
00124 char *strcpy();
00125 char *ctime();
00126 #endif
00127
00128 char *prog_name;
00129
00130 int main (int argc, char *argv[]);
00131 static void doall(void);
00132 static void donames(char **args);
00133 static void print(void);
00134 static void fwopen(void);
00135 static void decode(struct person *pers);
00136 static void fwclose(void);
00137 static int netfinger (char *name);
00138 static int matchcmp (char *gname, char *login, char *given);
00139 static void quickprint (struct person *pers);
00140 static void shortprint (struct person *pers);
00141 static void personprint (struct person *pers);
00142 static int AlreadyPrinted(int uid);
00143 static int AnyMail (char *name);
00144 static struct passwd *pwdcopy(struct passwd *pfrom);
00145 static void findidle (struct person *pers);
00146 static int ltimeprint (char *dt, long *before, char *after);
00147 static void stimeprint (long *dt);
00148 static void findwhen (struct person *pers);
00149 static int namecmp (char *name1, char *name2);
00150
00151 main(argc, argv)
00152 int argc;
00153 register char **argv;
00154 {
00155 FILE *fp;
00156 register char *s;
00157
00158 prog_name= argv[0];
00159
00160
00161 while (*++argv && **argv == COMMAND)
00162 for (s = *argv + 1; *s; s++)
00163 switch (*s) {
00164 case 'b':
00165 unbrief = 0;
00166 break;
00167 case 'f':
00168 header = 0;
00169 break;
00170 case 'h':
00171 hack = 0;
00172 break;
00173 case 'i':
00174 idle = 1;
00175 unquick = 0;
00176 break;
00177 case 'l':
00178 large = 1;
00179 break;
00180 case 'm':
00181 match = 0;
00182 break;
00183 case 'p':
00184 plan = 0;
00185 break;
00186 case 'q':
00187 unquick = 0;
00188 break;
00189 case 's':
00190 small = 1;
00191 break;
00192 case 'w':
00193 wide = 0;
00194 break;
00195 default:
00196 fprintf(stderr, "Usage: finger [-bfhilmpqsw] [login1 [login2 ...] ]\n");
00197 exit(1);
00198 }
00199 if (unquick || idle)
00200 time(&tloc);
00201
00202
00203
00204 if (*argv == 0)
00205 doall();
00206 else
00207 donames(argv);
00208 if (person1)
00209 print();
00210 exit(0);
00211 }
00212
00213 static void doall()
00214 {
00215 register struct person *p;
00216 register struct passwd *pw;
00217 int uf;
00218 char name[NMAX + 1];
00219
00220 unshort = large;
00221 if ((uf = open(USERLOG, 0)) < 0) {
00222 fprintf(stderr, "finger: error opening %s\n", USERLOG);
00223 exit(2);
00224 }
00225 if (unquick) {
00226 setpwent();
00227 fwopen();
00228 }
00229 while (read(uf, (char *)&user, sizeof user) == sizeof user) {
00230 if (user.ut_name[0] == 0)
00231 continue;
00232 if (person1 == 0)
00233 p = person1 = (struct person *) malloc(sizeof *p);
00234 else {
00235 p->link = (struct person *) malloc(sizeof *p);
00236 p = p->link;
00237 }
00238 bcopy(user.ut_name, name, NMAX);
00239 name[NMAX] = 0;
00240 bcopy(user.ut_line, p->tty, LMAX);
00241 p->tty[LMAX] = 0;
00242 bcopy(user.ut_host, p->host, HMAX);
00243 p->host[HMAX] = 0;
00244 p->loginat = user.ut_time;
00245 p->pwd = 0;
00246 p->loggedin = 1;
00247 p->where = NULL;
00248 if (unquick && (pw = getpwnam(name))) {
00249 p->pwd = pwdcopy(pw);
00250 decode(p);
00251 p->name = p->pwd->pw_name;
00252 } else
00253 p->name = strcpy(malloc(strlen(name) + 1), name);
00254 }
00255 if (unquick) {
00256 fwclose();
00257 endpwent();
00258 }
00259 close(uf);
00260 if (person1 == 0) {
00261 printf("No one logged on\n");
00262 return;
00263 }
00264 p->link = 0;
00265 }
00266
00267 static void donames(argv)
00268 char **argv;
00269 {
00270 register struct person *p;
00271 register struct passwd *pw;
00272 int uf;
00273
00274
00275
00276
00277
00278 unshort = !small;
00279 for (; *argv != 0; argv++) {
00280 if (netfinger(*argv))
00281 continue;
00282 if (person1 == 0)
00283 p = person1 = (struct person *) malloc(sizeof *p);
00284 else {
00285 p->link = (struct person *) malloc(sizeof *p);
00286 p = p->link;
00287 }
00288 p->name = *argv;
00289 p->loggedin = 0;
00290 p->original = 1;
00291 p->pwd = 0;
00292 }
00293 if (person1 == 0)
00294 return;
00295 p->link = 0;
00296
00297
00298
00299 if (unquick) {
00300 setpwent();
00301 if (!match) {
00302 for (p = person1; p != 0; p = p->link)
00303 if (pw = getpwnam(p->name))
00304 p->pwd = pwdcopy(pw);
00305 } else while ((pw = getpwent()) != 0) {
00306 for (p = person1; p != 0; p = p->link) {
00307 if (!p->original)
00308 continue;
00309 if (strcmp(p->name, pw->pw_name) != 0 &&
00310 !matchcmp(pw->pw_gecos, pw->pw_name, p->name))
00311 continue;
00312 if (p->pwd == 0)
00313 p->pwd = pwdcopy(pw);
00314 else {
00315 struct person *new;
00316
00317
00318
00319
00320 new = (struct person *)
00321 malloc(sizeof *new);
00322 new->pwd = pwdcopy(pw);
00323 new->name = p->name;
00324 new->original = 1;
00325 new->loggedin = 0;
00326 new->link = p->link;
00327 p->original = 0;
00328 p->link = new;
00329 p = new;
00330 }
00331 }
00332 }
00333 endpwent();
00334 }
00335
00336 if ((uf = open(USERLOG, 0)) < 0) {
00337 fprintf(stderr, "finger: error opening %s\n", USERLOG);
00338 exit(2);
00339 }
00340 while (read(uf, (char *)&user, sizeof user) == sizeof user) {
00341 if (*user.ut_name == 0)
00342 continue;
00343 for (p = person1; p != 0; p = p->link) {
00344 if (p->loggedin == 2)
00345 continue;
00346 if (strncmp(p->pwd ? p->pwd->pw_name : p->name,
00347 user.ut_name, NMAX) != 0)
00348 continue;
00349 if (p->loggedin == 0) {
00350 bcopy(user.ut_line, p->tty, LMAX);
00351 p->tty[LMAX] = 0;
00352 bcopy(user.ut_host, p->host, HMAX);
00353 p->host[HMAX] = 0;
00354 p->loginat = user.ut_time;
00355 p->loggedin = 1;
00356 } else {
00357 struct person *new;
00358 new = (struct person *) malloc(sizeof *new);
00359 new->name = p->name;
00360 bcopy(user.ut_line, new->tty, LMAX);
00361 new->tty[LMAX] = 0;
00362 bcopy(user.ut_host, new->host, HMAX);
00363 new->host[HMAX] = 0;
00364 new->loginat = user.ut_time;
00365 new->pwd = p->pwd;
00366 new->loggedin = 1;
00367 new->original = 0;
00368 new->link = p->link;
00369 p->loggedin = 2;
00370 p->link = new;
00371 p = new;
00372 }
00373 }
00374 }
00375 close(uf);
00376 if (unquick) {
00377 fwopen();
00378 for (p = person1; p != 0; p = p->link)
00379 decode(p);
00380 fwclose();
00381 }
00382 }
00383
00384 static void print()
00385 {
00386 register FILE *fp;
00387 register struct person *p;
00388 register char *s;
00389 register c;
00390
00391
00392
00393
00394 if (header) {
00395 if (unquick) {
00396 if (!unshort)
00397 if (wide)
00398 printf("Login Name TTY Idle When Where\n");
00399 else
00400 printf("Login TTY Idle When Where\n");
00401 } else {
00402 printf("Login TTY When");
00403 if (idle)
00404 printf(" Idle");
00405 putchar('\n');
00406 }
00407 }
00408 for (p = person1; p != 0; p = p->link) {
00409 if (!unquick) {
00410 quickprint(p);
00411 continue;
00412 }
00413 if (!unshort) {
00414 shortprint(p);
00415 continue;
00416 }
00417 personprint(p);
00418 if (p->pwd != 0 && !AlreadyPrinted(p->pwd->pw_uid)) {
00419 AnyMail(p->pwd->pw_name);
00420 if (hack) {
00421 s = malloc(strlen(p->pwd->pw_dir) +
00422 sizeof PROJ);
00423 strcpy(s, p->pwd->pw_dir);
00424 strcat(s, PROJ);
00425 if ((fp = fopen(s, "r")) != 0) {
00426 printf("Project: ");
00427 while ((c = getc(fp)) != EOF) {
00428 if (c == '\n')
00429 break;
00430 if (isprint(c) || isspace(c))
00431 putchar(c);
00432 else
00433 putchar(c ^ 100);
00434 }
00435 fclose(fp);
00436 putchar('\n');
00437 }
00438 free(s);
00439 }
00440 if (plan) {
00441 s = malloc(strlen(p->pwd->pw_dir) +
00442 sizeof PLAN);
00443 strcpy(s, p->pwd->pw_dir);
00444 strcat(s, PLAN);
00445 if ((fp = fopen(s, "r")) == 0) {
00446 if (!NONOTHING) printf("No Plan.\n");
00447 } else {
00448 printf("Plan:\n");
00449 while ((c = getc(fp)) != EOF)
00450 if (isprint(c) || isspace(c))
00451 putchar(c);
00452 else
00453 putchar(c ^ 100);
00454 fclose(fp);
00455 }
00456 free(s);
00457 }
00458 }
00459 if (p->link != 0)
00460 putchar('\n');
00461 }
00462 }
00463
00464
00465
00466
00467
00468 static struct passwd *
00469 pwdcopy(pfrom)
00470 register struct passwd *pfrom;
00471 {
00472 register struct passwd *pto;
00473
00474 pto = (struct passwd *) malloc(sizeof *pto);
00475 #define savestr(s) strcpy(malloc(strlen(s) + 1), s)
00476 pto->pw_name = savestr(pfrom->pw_name);
00477 pto->pw_uid = pfrom->pw_uid;
00478 pto->pw_gecos = savestr(pfrom->pw_gecos);
00479 pto->pw_dir = savestr(pfrom->pw_dir);
00480 pto->pw_shell = savestr(pfrom->pw_shell);
00481 #undef savestr
00482 return pto;
00483 }
00484
00485
00486
00487
00488
00489 static void quickprint(pers)
00490 register struct person *pers;
00491 {
00492 printf("%-*.*s ", NMAX, NMAX, pers->name);
00493 if (pers->loggedin) {
00494 if (idle) {
00495 findidle(pers);
00496 printf("%c%-*s %-16.16s", pers->writable ? ' ' : '*',
00497 LMAX, pers->tty, ctime(&pers->loginat));
00498 ltimeprint(" ", &pers->idletime, "");
00499 } else
00500 printf(" %-*s %-16.16s", LMAX,
00501 pers->tty, ctime(&pers->loginat));
00502 putchar('\n');
00503 } else
00504 printf(" Not Logged In\n");
00505 }
00506
00507
00508
00509
00510
00511 static void shortprint(pers)
00512 register struct person *pers;
00513 {
00514 char *p;
00515 char dialup;
00516
00517 if (pers->pwd == 0) {
00518 printf("%-15s ???\n", pers->name);
00519 return;
00520 }
00521 printf("%-*s", NMAX, pers->pwd->pw_name);
00522 dialup = 0;
00523 if (wide) {
00524 if (pers->realname)
00525 printf(" %-20.20s", pers->realname);
00526 else
00527 printf(" ??? ");
00528 }
00529 putchar(' ');
00530 if (pers->loggedin && !pers->writable)
00531 putchar('*');
00532 else
00533 putchar(' ');
00534 if (*pers->tty) {
00535 if (pers->tty[0] == 't' && pers->tty[1] == 't' &&
00536 pers->tty[2] == 'y') {
00537 if (pers->tty[3] == 'd' && pers->loggedin)
00538 dialup = 1;
00539 printf("%-2.2s ", pers->tty + 3);
00540 } else
00541 printf("%-2.2s ", pers->tty);
00542 } else
00543 printf(" ");
00544 p = ctime(&pers->loginat);
00545 if (pers->loggedin) {
00546 stimeprint(&pers->idletime);
00547 printf(" %3.3s %-5.5s ", p, p + 11);
00548 } else if (pers->loginat == 0)
00549 printf(" < . . . . >");
00550 else if (tloc - pers->loginat >= 180L * 24 * 60 * 60)
00551 printf(" <%-6.6s, %-4.4s>", p + 4, p + 20);
00552 else
00553 printf(" <%-12.12s>", p + 4);
00554 if (pers->host[0])
00555 printf(" %-20.20s", pers->host);
00556 putchar('\n');
00557 }
00558
00559
00560
00561
00562
00563
00564 static void
00565 personprint(pers)
00566 register struct person *pers;
00567 {
00568 if (pers->pwd == 0) {
00569 printf("Login name: %-10s\t\t\tIn real life: ???\n",
00570 pers->name);
00571 return;
00572 }
00573 printf("Login name: %-10s", pers->pwd->pw_name);
00574 if (pers->loggedin && !pers->writable)
00575 printf(" (messages off) ");
00576 else
00577 printf(" ");
00578 if (pers->realname)
00579 printf("In real life: %s", pers->realname);
00580 if (unbrief) {
00581 printf("\nDirectory: %-25s", pers->pwd->pw_dir);
00582 if (*pers->pwd->pw_shell)
00583 printf("\tShell: %-s", pers->pwd->pw_shell);
00584 }
00585 if (pers->loggedin) {
00586 register char *ep = ctime(&pers->loginat);
00587 if (*pers->host) {
00588 printf("\nOn since %15.15s on %s from %s",
00589 &ep[4], pers->tty, pers->host);
00590 ltimeprint("\n", &pers->idletime, " Idle Time");
00591 } else {
00592 printf("\nOn since %15.15s on %-*s",
00593 &ep[4], LMAX, pers->tty);
00594 ltimeprint("\t", &pers->idletime, " Idle Time");
00595 }
00596 } else if (pers->loginat == 0) {
00597 if (lf >= 0) printf("\nNever logged in.");
00598 } else if (tloc - pers->loginat > 180L * 24 * 60 * 60) {
00599 register char *ep = ctime(&pers->loginat);
00600 printf("\nLast login %10.10s, %4.4s on %s",
00601 ep, ep+20, pers->tty);
00602 if (*pers->host)
00603 printf(" from %s", pers->host);
00604 } else {
00605 register char *ep = ctime(&pers->loginat);
00606 printf("\nLast login %16.16s on %s", ep, pers->tty);
00607 if (*pers->host)
00608 printf(" from %s", pers->host);
00609 }
00610 putchar('\n');
00611 }
00612
00613
00614
00615
00616
00617 static void
00618 decode(pers)
00619 register struct person *pers;
00620 {
00621 char buffer[256];
00622 register char *bp, *gp, *lp;
00623 int alldigits;
00624 int hasspace;
00625 int len;
00626
00627 pers->realname = 0;
00628 if (pers->pwd == 0)
00629 return;
00630 gp = pers->pwd->pw_gecos;
00631 bp = buffer;
00632 if (*gp == ASTERISK)
00633 gp++;
00634 while (*gp && *gp != COMMA)
00635 if (*gp == SAMENAME) {
00636 lp = pers->pwd->pw_name;
00637 if (islower(*lp))
00638 *bp++ = toupper(*lp++);
00639 while (*bp++ = *lp++)
00640 ;
00641 bp--;
00642 gp++;
00643 } else
00644 *bp++ = *gp++;
00645 *bp++ = 0;
00646 if ((len = bp - buffer) > 1)
00647 pers->realname = strcpy(malloc(len), buffer);
00648 if (pers->loggedin)
00649 findidle(pers);
00650 else
00651 findwhen(pers);
00652 }
00653
00654
00655
00656
00657
00658
00659
00660 static void
00661 fwopen()
00662 {
00663 if ((lf = open(LASTLOG, 0)) < 0) {
00664 if (errno == ENOENT) return;
00665 fprintf(stderr, "finger: %s open error\n", LASTLOG);
00666 }
00667 }
00668
00669 static void
00670 findwhen(pers)
00671 register struct person *pers;
00672 {
00673 struct utmp ll;
00674 #define ll_line ut_line
00675 #define ll_host ut_host
00676 #define ll_time ut_time
00677
00678 int i;
00679
00680 if (lf >= 0) {
00681 lseek(lf, (long)pers->pwd->pw_uid * sizeof ll, 0);
00682 if ((i = read(lf, (char *)&ll, sizeof ll)) == sizeof ll) {
00683 bcopy(ll.ll_line, pers->tty, LMAX);
00684 pers->tty[LMAX] = 0;
00685 bcopy(ll.ll_host, pers->host, HMAX);
00686 pers->host[HMAX] = 0;
00687 pers->loginat = ll.ll_time;
00688 } else {
00689 if (i != 0)
00690 fprintf(stderr, "finger: %s read error\n",
00691 LASTLOG);
00692 pers->tty[0] = 0;
00693 pers->host[0] = 0;
00694 pers->loginat = 0L;
00695 }
00696 } else {
00697 pers->tty[0] = 0;
00698 pers->host[0] = 0;
00699 pers->loginat = 0L;
00700 }
00701 }
00702
00703 static void fwclose()
00704 {
00705 if (lf >= 0)
00706 close(lf);
00707 }
00708
00709
00710
00711
00712
00713 static void
00714 findidle(pers)
00715 register struct person *pers;
00716 {
00717 struct stat ttystatus;
00718 static char buffer[20] = "/dev/";
00719 long t;
00720 #define TTYLEN 5
00721
00722 strcpy(buffer + TTYLEN, pers->tty);
00723 buffer[TTYLEN+LMAX] = 0;
00724 if (stat(buffer, &ttystatus) < 0) {
00725 fprintf(stderr, "finger: Can't stat %s\n", buffer);
00726 exit(4);
00727 }
00728 time(&t);
00729 if (t < ttystatus.st_atime)
00730 pers->idletime = 0L;
00731 else
00732 pers->idletime = t - ttystatus.st_atime;
00733 pers->writable = (ttystatus.st_mode & TALKABLE) == TALKABLE;
00734 }
00735
00736
00737
00738
00739
00740 static void
00741 stimeprint(dt)
00742 long *dt;
00743 {
00744 register struct tm *delta;
00745
00746 delta = gmtime(dt);
00747 if (delta->tm_yday == 0)
00748 if (delta->tm_hour == 0)
00749 if (delta->tm_min == 0)
00750 printf(" ");
00751 else
00752 printf(" %2d", delta->tm_min);
00753 else
00754 if (delta->tm_hour >= 10)
00755 printf("%3d:", delta->tm_hour);
00756 else
00757 printf("%1d:%02d",
00758 delta->tm_hour, delta->tm_min);
00759 else
00760 printf("%3dd", delta->tm_yday);
00761 }
00762
00763
00764
00765
00766
00767
00768 static int
00769 ltimeprint(before, dt, after)
00770 long *dt;
00771 char *before, *after;
00772 {
00773 register struct tm *delta;
00774
00775 delta = gmtime(dt);
00776 if (delta->tm_yday == 0 && delta->tm_hour == 0 && delta->tm_min == 0 &&
00777 delta->tm_sec <= 10)
00778 return (0);
00779 printf("%s", before);
00780 if (delta->tm_yday >= 10)
00781 printf("%d days", delta->tm_yday);
00782 else if (delta->tm_yday > 0)
00783 printf("%d day%s %d hour%s",
00784 delta->tm_yday, delta->tm_yday == 1 ? "" : "s",
00785 delta->tm_hour, delta->tm_hour == 1 ? "" : "s");
00786 else
00787 if (delta->tm_hour >= 10)
00788 printf("%d hours", delta->tm_hour);
00789 else if (delta->tm_hour > 0)
00790 printf("%d hour%s %d minute%s",
00791 delta->tm_hour, delta->tm_hour == 1 ? "" : "s",
00792 delta->tm_min, delta->tm_min == 1 ? "" : "s");
00793 else
00794 if (delta->tm_min >= 10)
00795 printf("%2d minutes", delta->tm_min);
00796 else if (delta->tm_min == 0)
00797 printf("%2d seconds", delta->tm_sec);
00798 else
00799 printf("%d minute%s %d second%s",
00800 delta->tm_min,
00801 delta->tm_min == 1 ? "" : "s",
00802 delta->tm_sec,
00803 delta->tm_sec == 1 ? "" : "s");
00804 printf("%s", after);
00805 }
00806
00807 static int
00808 matchcmp(gname, login, given)
00809 register char *gname;
00810 char *login;
00811 char *given;
00812 {
00813 char buffer[100];
00814 register char *bp, *lp;
00815 register c;
00816
00817 if (*gname == ASTERISK)
00818 gname++;
00819 lp = 0;
00820 bp = buffer;
00821 for (;;)
00822 switch (c = *gname++) {
00823 case SAMENAME:
00824 for (lp = login; bp < buffer + sizeof buffer
00825 && (*bp++ = *lp++);)
00826 ;
00827 bp--;
00828 break;
00829 case ' ':
00830 case COMMA:
00831 case '\0':
00832 *bp = 0;
00833 if (namecmp(buffer, given))
00834 return (1);
00835 if (c == COMMA || c == 0)
00836 return (0);
00837 bp = buffer;
00838 break;
00839 default:
00840 if (bp < buffer + sizeof buffer)
00841 *bp++ = c;
00842 }
00843
00844 }
00845
00846 static int
00847 namecmp(name1, name2)
00848 register char *name1, *name2;
00849 {
00850 register c1, c2;
00851
00852 for (;;) {
00853 c1 = *name1++;
00854 if (islower(c1))
00855 c1 = toupper(c1);
00856 c2 = *name2++;
00857 if (islower(c2))
00858 c2 = toupper(c2);
00859 if (c1 != c2)
00860 break;
00861 if (c1 == 0)
00862 return (1);
00863 }
00864 if (!c1) {
00865 for (name2--; isdigit(*name2); name2++)
00866 ;
00867 if (*name2 == 0)
00868 return (1);
00869 } else if (!c2) {
00870 for (name1--; isdigit(*name1); name1++)
00871 ;
00872 if (*name2 == 0)
00873 return (1);
00874 }
00875 return (0);
00876 }
00877
00878 #if NONET
00879 static int
00880 netfinger(name)
00881 char *name;
00882 {
00883 return 0;
00884 }
00885 #else
00886 static int
00887 netfinger(name)
00888 char *name;
00889 {
00890 char *host;
00891 char fname[100];
00892 struct hostent *hp;
00893 struct servent *sp;
00894 int s, result;
00895 #if !_MINIX
00896 char *rindex();
00897 #endif
00898 register FILE *f;
00899 register int c;
00900 register int lastc;
00901 nwio_tcpconf_t tcpconf;
00902 nwio_tcpcl_t tcpconnopt;
00903 char *tcp_device;
00904
00905 if (name == NULL)
00906 return (0);
00907 host = rindex(name, '@');
00908 if (host == NULL)
00909 return (0);
00910 *host++ = 0;
00911 hp = gethostbyname(host);
00912 if (hp == NULL) {
00913 static struct hostent def;
00914 static ipaddr_t defaddr;
00915 static char namebuf[128];
00916
00917 defaddr = inet_addr(host);
00918 if (defaddr == -1) {
00919 printf("unknown host: %s\n", host);
00920 return (1);
00921 }
00922 strcpy(namebuf, host);
00923 def.h_name = namebuf;
00924 def.h_addr = (char *)&defaddr;
00925 def.h_length = sizeof (ipaddr_t);
00926 def.h_addrtype = AF_INET;
00927 def.h_aliases = 0;
00928 hp = &def;
00929 }
00930 printf("[%s] ", hp->h_name);
00931 fflush(stdout);
00932
00933 tcp_device= getenv("TCP_DEVICE");
00934 if (tcp_device == NULL)
00935 tcp_device= TCP_DEVICE;
00936 s= open (tcp_device, O_RDWR);
00937 if (s == -1)
00938 {
00939 fprintf(stderr, "%s: unable to open %s (%s)\n",
00940 prog_name, tcp_device, strerror(errno));
00941 exit(1);
00942 }
00943 tcpconf.nwtc_flags= NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
00944 tcpconf.nwtc_remaddr= *(ipaddr_t *)hp->h_addr;
00945 tcpconf.nwtc_remport= htons(TCPPORT_FINGER);
00946
00947 result= ioctl (s, NWIOSTCPCONF, &tcpconf);
00948 if (result<0)
00949 {
00950 fprintf(stderr, "%s\n", strerror(errno));
00951 exit(1);
00952 }
00953
00954 tcpconnopt.nwtcl_flags= 0;
00955
00956 do
00957 {
00958 result= ioctl (s, NWIOTCPCONN, &tcpconnopt);
00959 if (result<0 && errno== EAGAIN)
00960 {
00961 fprintf(stderr, "got EAGAIN error, sleeping 2s\n");
00962 sleep(2);
00963 }
00964 } while (result<0 && errno == EAGAIN);
00965 if (result<0)
00966 {
00967 fprintf(stderr, "%s\n", strerror(errno));
00968 exit(1);
00969 }
00970 printf("\r\n");
00971 if (large) write(s, "/W ", 3);
00972 write(s, name, strlen(name));
00973 write(s, "\r\n", 2);
00974 f = fdopen(s, "r");
00975 while ((c = getc(f)) != EOF) {
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 c &= ~0200;
00990 if (c == '\r')
00991 {
00992 c= getc(f) & ~0200;
00993 if (c == '\012')
00994 {
00995 lastc= c;
00996 putchar('\n');
00997 continue;
00998 }
00999 else
01000 putchar('\r');
01001 }
01002 lastc = c;
01003 if (isprint(c) || isspace(c))
01004 putchar(c);
01005 else
01006 putchar(c ^ 100);
01007 }
01008 if (lastc != '\n')
01009 putchar('\n');
01010 (void)fclose(f);
01011 return (1);
01012 }
01013 #endif
01014
01015
01016
01017
01018
01019
01020 #define preamble "/usr/spool/mail/"
01021 static int
01022 AnyMail(name)
01023 char *name;
01024 {
01025 struct stat buf;
01026 char *mbxdir = preamble;
01027 char *mbxpath;
01028
01029 #if !_MINIX
01030 char *ctime();
01031 #endif
01032 char *timestr;
01033
01034 mbxpath = malloc(strlen(name) + strlen(preamble) + 1);
01035
01036 strcpy(mbxpath, mbxdir);
01037 strcat(mbxpath, name);
01038
01039 if (stat(mbxpath, &buf) == -1 || buf.st_size == 0) {
01040
01041 if (!NONOTHING) printf("No unread mail\n");
01042 } else {
01043 if (buf.st_mtime == buf.st_atime) {
01044
01045
01046
01047
01048
01049 printf("Unread mail since ");
01050 printf(ctime(&buf.st_mtime));
01051 } else {
01052
01053
01054
01055
01056
01057
01058 printf("New mail received ");
01059 timestr = ctime(&buf.st_mtime);
01060 timestr[24] = '\0';
01061 printf(timestr);
01062 printf(";\n unread since ");
01063 printf(ctime(&buf.st_atime));
01064 }
01065 }
01066
01067 free(mbxpath);
01068 }
01069
01070
01071
01072
01073
01074 #define PPMAX 200
01075 int PlanPrinted[PPMAX+1];
01076 int PPIndex = 0;
01077
01078 static int
01079 AlreadyPrinted(uid)
01080 int uid;
01081 {
01082 int i = 0;
01083
01084 while (i++ < PPIndex) {
01085 if (PlanPrinted[i] == uid)
01086 return(1);
01087 }
01088 if (i < PPMAX) {
01089 PlanPrinted[i] = uid;
01090 PPIndex++;
01091 }
01092 return(0);
01093 }