📄 finger.c
字号:
printf(" < . . . . >"); else if (tloc - pers->loginat >= 180L * 24 * 60 * 60) printf(" <%-6.6s, %-4.4s>", p + 4, p + 20); else printf(" <%-12.12s>", p + 4); if (pers->host[0]) printf(" %-20.20s", pers->host); putchar('\n');}/* * print out a person in long format giving all possible information. * directory and shell are inhibited if unbrief is clear. */static voidpersonprint(pers) register struct person *pers;{ if (pers->pwd == 0) { printf("Login name: %-10s\t\t\tIn real life: ???\n", pers->name); return; } printf("Login name: %-10s", pers->pwd->pw_name); if (pers->loggedin && !pers->writable) printf(" (messages off) "); else printf(" "); if (pers->realname) printf("In real life: %s", pers->realname); if (unbrief) { printf("\nDirectory: %-25s", pers->pwd->pw_dir); if (*pers->pwd->pw_shell) printf("\tShell: %-s", pers->pwd->pw_shell); } if (pers->loggedin) { register char *ep = ctime(&pers->loginat); if (*pers->host) { printf("\nOn since %15.15s on %s from %s", &ep[4], pers->tty, pers->host); ltimeprint("\n", &pers->idletime, " Idle Time"); } else { printf("\nOn since %15.15s on %-*s", &ep[4], LMAX, pers->tty); ltimeprint("\t", &pers->idletime, " Idle Time"); } } else if (pers->loginat == 0) { if (lf >= 0) printf("\nNever logged in."); } else if (tloc - pers->loginat > 180L * 24 * 60 * 60) { register char *ep = ctime(&pers->loginat); printf("\nLast login %10.10s, %4.4s on %s", ep, ep+20, pers->tty); if (*pers->host) printf(" from %s", pers->host); } else { register char *ep = ctime(&pers->loginat); printf("\nLast login %16.16s on %s", ep, pers->tty); if (*pers->host) printf(" from %s", pers->host); } putchar('\n');}/* * decode the information in the gecos field of /etc/passwd */static voiddecode(pers) register struct person *pers;{ char buffer[256]; register char *bp, *gp, *lp; int alldigits; int hasspace; int len; pers->realname = 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 (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) */static voidfwopen(){ if ((lf = open(LASTLOG, 0)) < 0) { if (errno == ENOENT) return; fprintf(stderr, "finger: %s open error\n", LASTLOG); }}static voidfindwhen(pers) register struct person *pers;{ struct utmp ll;#define ll_line ut_line#define ll_host ut_host#define ll_time ut_time 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; }}static void 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. */static voidfindidle(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. */static voidstimeprint(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. */static intltimeprint(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);}static intmatchcmp(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*/}static intnamecmp(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);}#if NONETstatic intnetfinger(name)char *name;{ return 0;}#elsestatic intnetfinger(name) char *name;{ char *host; char fname[100]; struct hostent *hp; struct servent *sp; int s, result;#if !_MINIX char *rindex();#endif register FILE *f; register int c; register int lastc; nwio_tcpconf_t tcpconf; nwio_tcpcl_t tcpconnopt; char *tcp_device; 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 ipaddr_t defaddr; static char namebuf[128]; defaddr = inet_addr(host); if (defaddr == -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 (ipaddr_t); def.h_addrtype = AF_INET; def.h_aliases = 0; hp = &def; } printf("[%s] ", hp->h_name); fflush(stdout); tcp_device= getenv("TCP_DEVICE"); if (tcp_device == NULL) tcp_device= TCP_DEVICE; s= open (tcp_device, O_RDWR); if (s == -1) { fprintf(stderr, "%s: unable to open %s (%s)\n", prog_name, tcp_device, strerror(errno)); exit(1); } tcpconf.nwtc_flags= NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP; tcpconf.nwtc_remaddr= *(ipaddr_t *)hp->h_addr; tcpconf.nwtc_remport= htons(TCPPORT_FINGER); result= ioctl (s, NWIOSTCPCONF, &tcpconf); if (result<0) { fprintf(stderr, "%s\n", strerror(errno)); exit(1); } tcpconnopt.nwtcl_flags= 0; do { result= ioctl (s, NWIOTCPCONN, &tcpconnopt); if (result<0 && errno== EAGAIN) { fprintf(stderr, "got EAGAIN error, sleeping 2s\n"); sleep(2); } } while (result<0 && errno == EAGAIN); if (result<0) { fprintf(stderr, "%s\n", strerror(errno)); exit(1); } printf("\r\n"); if (large) write(s, "/W ", 3); write(s, name, strlen(name)); write(s, "\r\n", 2); f = fdopen(s, "r"); while ((c = getc(f)) != EOF) {/* switch(c) { case 0210: case 0211: case 0212: case 0214: c -= 0200; break; case 0215: c = '\n'; break; }*/ c &= ~0200; if (c == '\r') { c= getc(f) & ~0200; if (c == '\012') { lastc= c; putchar('\n'); continue; } else putchar('\r'); } lastc = c; if (isprint(c) || isspace(c)) putchar(c); else putchar(c ^ 100); } if (lastc != '\n') putchar('\n'); (void)fclose(f); return (1);}#endif/* * AnyMail - takes a username (string pointer thereto), and * prints on standard output whether there is any unread mail, * and if so, how old it is. (JCM@Shasta 15 March 80) */#define preamble "/usr/spool/mail/" /* mailboxes are there */static intAnyMail(name)char *name;{ struct stat buf; /* space for file status buffer */ char *mbxdir = preamble; /* string with path preamble */ char *mbxpath; /* space for entire pathname */#if !_MINIX char *ctime(); /* convert longword time to ascii */#endif char *timestr; mbxpath = malloc(strlen(name) + strlen(preamble) + 1); strcpy(mbxpath, mbxdir); /* copy preamble into path name */ strcat(mbxpath, name); /* concatenate user name to path */ if (stat(mbxpath, &buf) == -1 || buf.st_size == 0) { /* Mailbox is empty or nonexistent */ if (!NONOTHING) printf("No unread mail\n"); } else { if (buf.st_mtime == buf.st_atime) { /* There is something in the mailbox, but we can't really * be sure whether it is mail held there by the user * or a (single) new message that was placed in a newly * recreated mailbox, so we punt and call it "unread mail." */ printf("Unread mail since "); printf(ctime(&buf.st_mtime)); } else { /* New mail has definitely arrived since the last time * mail was read. mtime is the time the most recent * message arrived; atime is either the time the oldest * unread message arrived, or the last time the mail * was read. */ printf("New mail received "); timestr = ctime(&buf.st_mtime); /* time last modified */ timestr[24] = '\0'; /* suppress newline (ugh) */ printf(timestr); printf(";\n unread since "); printf(ctime(&buf.st_atime)); /* time last accessed */ } } free(mbxpath);}/* * return true iff we've already printed project/plan for this uid; * if not, enter this uid into table (so this function has a side-effect.) */#define PPMAX 200 /* assume no more than 200 logged-in users */int PlanPrinted[PPMAX+1];int PPIndex = 0; /* index of next unused table entry */static intAlreadyPrinted(uid)int uid;{ int i = 0; while (i++ < PPIndex) { if (PlanPrinted[i] == uid) return(1); } if (i < PPMAX) { PlanPrinted[i] = uid; PPIndex++; } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -