-/*
- * very hacky section of code to format phone numbers. filled with
- * magic constants like 4, 7 and 10.
- */
-char *
-phone(s, len, alldigits)
- register char *s;
- int len;
- char alldigits;
-{
- char fonebuf[15];
- register char *p = fonebuf;
- register i;
-
- if (!alldigits)
- return (strcpy(malloc(len + 1), s));
- switch (len) {
- case 4:
- *p++ = ' ';
- *p++ = 'x';
- *p++ = '2';
- *p++ = '-';
- for (i = 0; i < 4; i++)
- *p++ = *s++;
- break;
- case 7:
- for (i = 0; i < 3; i++)
- *p++ = *s++;
- *p++ = '-';
- for (i = 0; i < 4; i++)
- *p++ = *s++;
- break;
- case 10:
- for (i = 0; i < 3; i++)
- *p++ = *s++;
- *p++ = '-';
- for (i = 0; i < 3; i++)
- *p++ = *s++;
- *p++ = '-';
- for (i = 0; i < 4; i++)
- *p++ = *s++;
- break;
- case 0:
- return 0;
- default:
- return (strcpy(malloc(len + 1), s));
- }
- *p++ = 0;
- return (strcpy(malloc(p - fonebuf), fonebuf));
-}
-
-/*
- * decode the information in the gecos field of /etc/passwd
- */
-decode(pers)
- register struct person *pers;
-{
- char buffer[256];
- register char *bp, *gp, *lp;
- int alldigits;
- int hasspace;
- int len;
-
- pers->realname = 0;
- pers->office = 0;
- pers->officephone = 0;
- pers->homephone = 0;
- pers->random = 0;
- if (pers->pwd == 0)
- return;
- gp = pers->pwd->pw_gecos;
- bp = buffer;
- if (*gp == ASTERISK)
- gp++;
- while (*gp && *gp != COMMA) /* name */
- if (*gp == SAMENAME) {
- lp = pers->pwd->pw_name;
- if (islower(*lp))
- *bp++ = toupper(*lp++);
- while (*bp++ = *lp++)
- ;
- bp--;
- gp++;
- } else
- *bp++ = *gp++;
- *bp++ = 0;
- if ((len = bp - buffer) > 1)
- pers->realname = strcpy(malloc(len), buffer);
- if (*gp == COMMA) { /* office */
- gp++;
- hasspace = 0;
- bp = buffer;
- while (*gp && *gp != COMMA) {
- *bp = *gp++;
- if (*bp == ' ')
- hasspace = 1;
- /* leave 5 for Cory and Evans expansion */
- if (bp < buffer + sizeof buffer - 6)
- bp++;
- }
- *bp = 0;
- len = bp - buffer;
- bp--; /* point to last character */
- if (hasspace || len == 0)
- len++;
- else if (*bp == CORY) {
- strcpy(bp, " Cory");
- len += 5;
- } else if (*bp == EVANS) {
- strcpy(bp, " Evans");
- len += 6;
- } else
- len++;
- if (len > 1)
- pers->office = strcpy(malloc(len), buffer);
- }
- if (*gp == COMMA) { /* office phone */
- gp++;
- bp = buffer;
- alldigits = 1;
- while (*gp && *gp != COMMA) {
- *bp = *gp++;
- if (!isdigit(*bp))
- alldigits = 0;
- if (bp < buffer + sizeof buffer - 1)
- bp++;
- }
- *bp = 0;
- pers->officephone = phone(buffer, bp - buffer, alldigits);
- }
- if (*gp == COMMA) { /* home phone */
- gp++;
- bp = buffer;
- alldigits = 1;
- while (*gp && *gp != COMMA) {
- *bp = *gp++;
- if (!isdigit(*bp))
- alldigits = 0;
- if (bp < buffer + sizeof buffer - 1)
- bp++;
- }
- *bp = 0;
- pers->homephone = phone(buffer, bp - buffer, alldigits);
- }
- if (pers->loggedin)
- findidle(pers);
- else
- findwhen(pers);
-}
-
-/*
- * find the last log in of a user by checking the LASTLOG file.
- * the entry is indexed by the uid, so this can only be done if
- * the uid is known (which it isn't in quick mode)
- */
-
-fwopen()
-{
- if ((lf = open(LASTLOG, 0)) < 0)
- fprintf(stderr, "finger: %s open error\n", LASTLOG);
-}
-
-findwhen(pers)
- register struct person *pers;
-{
- struct lastlog ll;
- int i;
-
- if (lf >= 0) {
- lseek(lf, (long)pers->pwd->pw_uid * sizeof ll, 0);
- if ((i = read(lf, (char *)&ll, sizeof ll)) == sizeof ll) {
- bcopy(ll.ll_line, pers->tty, LMAX);
- pers->tty[LMAX] = 0;
- bcopy(ll.ll_host, pers->host, HMAX);
- pers->host[HMAX] = 0;
- pers->loginat = ll.ll_time;
- } else {
- if (i != 0)
- fprintf(stderr, "finger: %s read error\n",
- LASTLOG);
- pers->tty[0] = 0;
- pers->host[0] = 0;
- pers->loginat = 0L;
- }
- } else {
- pers->tty[0] = 0;
- pers->host[0] = 0;
- pers->loginat = 0L;
- }
-}
-
-fwclose()
-{
- if (lf >= 0)
- close(lf);
-}
-
-/*
- * find the idle time of a user by doing a stat on /dev/tty??,
- * where tty?? has been gotten from USERLOG, supposedly.
- */
-findidle(pers)
- register struct person *pers;
-{
- struct stat ttystatus;
- static char buffer[20] = "/dev/";
- long t;
-#define TTYLEN 5
-
- strcpy(buffer + TTYLEN, pers->tty);
- buffer[TTYLEN+LMAX] = 0;
- if (stat(buffer, &ttystatus) < 0) {
- fprintf(stderr, "finger: Can't stat %s\n", buffer);
- exit(4);
- }
- time(&t);
- if (t < ttystatus.st_atime)
- pers->idletime = 0L;
- else
- pers->idletime = t - ttystatus.st_atime;
- pers->writable = (ttystatus.st_mode & TALKABLE) == TALKABLE;
-}
-
-/*
- * print idle time in short format; this program always prints 4 characters;
- * if the idle time is zero, it prints 4 blanks.
- */
-stimeprint(dt)
- long *dt;
-{
- register struct tm *delta;
-
- delta = gmtime(dt);
- if (delta->tm_yday == 0)
- if (delta->tm_hour == 0)
- if (delta->tm_min == 0)
- printf(" ");
- else
- printf(" %2d", delta->tm_min);
- else
- if (delta->tm_hour >= 10)
- printf("%3d:", delta->tm_hour);
- else
- printf("%1d:%02d",
- delta->tm_hour, delta->tm_min);
- else
- printf("%3dd", delta->tm_yday);
-}
-
-/*
- * print idle time in long format with care being taken not to pluralize
- * 1 minutes or 1 hours or 1 days.
- * print "prefix" first.
- */
-ltimeprint(before, dt, after)
- long *dt;
- char *before, *after;
-{
- register struct tm *delta;
-
- delta = gmtime(dt);
- if (delta->tm_yday == 0 && delta->tm_hour == 0 && delta->tm_min == 0 &&
- delta->tm_sec <= 10)
- return (0);
- printf("%s", before);
- if (delta->tm_yday >= 10)
- printf("%d days", delta->tm_yday);
- else if (delta->tm_yday > 0)
- printf("%d day%s %d hour%s",
- delta->tm_yday, delta->tm_yday == 1 ? "" : "s",
- delta->tm_hour, delta->tm_hour == 1 ? "" : "s");
- else
- if (delta->tm_hour >= 10)
- printf("%d hours", delta->tm_hour);
- else if (delta->tm_hour > 0)
- printf("%d hour%s %d minute%s",
- delta->tm_hour, delta->tm_hour == 1 ? "" : "s",
- delta->tm_min, delta->tm_min == 1 ? "" : "s");
- else
- if (delta->tm_min >= 10)
- printf("%2d minutes", delta->tm_min);
- else if (delta->tm_min == 0)
- printf("%2d seconds", delta->tm_sec);
- else
- printf("%d minute%s %d second%s",
- delta->tm_min,
- delta->tm_min == 1 ? "" : "s",
- delta->tm_sec,
- delta->tm_sec == 1 ? "" : "s");
- printf("%s", after);
-}
-
-matchcmp(gname, login, given)
- register char *gname;
- char *login;
- char *given;
-{
- char buffer[100];
- register char *bp, *lp;
- register c;
-
- if (*gname == ASTERISK)
- gname++;
- lp = 0;
- bp = buffer;
- for (;;)
- switch (c = *gname++) {
- case SAMENAME:
- for (lp = login; bp < buffer + sizeof buffer
- && (*bp++ = *lp++);)
- ;
- bp--;
- break;
- case ' ':
- case COMMA:
- case '\0':
- *bp = 0;
- if (namecmp(buffer, given))
- return (1);
- if (c == COMMA || c == 0)
- return (0);
- bp = buffer;
- break;
- default:
- if (bp < buffer + sizeof buffer)
- *bp++ = c;
- }
- /*NOTREACHED*/
-}
-
-namecmp(name1, name2)
- register char *name1, *name2;
-{
- register c1, c2;
-
- for (;;) {
- c1 = *name1++;
- if (islower(c1))
- c1 = toupper(c1);
- c2 = *name2++;
- if (islower(c2))
- c2 = toupper(c2);
- if (c1 != c2)
- break;
- if (c1 == 0)
- return (1);
- }
- if (!c1) {
- for (name2--; isdigit(*name2); name2++)
- ;
- if (*name2 == 0)
- return (1);
- } else if (!c2) {
- for (name1--; isdigit(*name1); name1++)
- ;
- if (*name2 == 0)
- return (1);
- }
- return (0);
-}
-
-netfinger(name)
- char *name;
-{
- char *host;
- char fname[100];
- struct hostent *hp;
- struct servent *sp;
- struct sockaddr_in sin;
- int s;
- char *rindex();
- register FILE *f;
- register int c;
- register int lastc;
-
- if (name == NULL)
- return (0);
- host = rindex(name, '@');
- if (host == NULL)
- return (0);
- *host++ = 0;
- hp = gethostbyname(host);
- if (hp == NULL) {
- static struct hostent def;
- static struct in_addr defaddr;
- static char namebuf[128];
- int inet_addr();
-
- defaddr.s_addr = inet_addr(host);
- if (defaddr.s_addr == -1) {
- printf("unknown host: %s\n", host);
- return (1);
- }
- strcpy(namebuf, host);
- def.h_name = namebuf;
- def.h_addr = (char *)&defaddr;
- def.h_length = sizeof (struct in_addr);
- def.h_addrtype = AF_INET;
- def.h_aliases = 0;
- hp = &def;
- }
- printf("[%s]", hp->h_name);
- sp = getservbyname("finger", "tcp");
- if (sp == 0) {
- printf("tcp/finger: unknown service\n");
- return (1);
- }
- sin.sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
- sin.sin_port = sp->s_port;
- s = socket(hp->h_addrtype, SOCK_STREAM, 0);
- if (s < 0) {
- fflush(stdout);
- perror("socket");
- return (1);
- }
- if (connect(s, (char *)&sin, sizeof (sin)) < 0) {
- fflush(stdout);
- perror("connect");
- close(s);
- return (1);