137660Sbostic /* 237660Sbostic * Copyright (c) 1989 The Regents of the University of California. 337660Sbostic * All rights reserved. 437660Sbostic * 540027Sbostic * This code is derived from software contributed to Berkeley by 640027Sbostic * Tony Nardo of the Johns Hopkins University/Applied Physics Lab. 740027Sbostic * 842731Sbostic * %sccs.include.redist.c% 937660Sbostic */ 1037660Sbostic 1137660Sbostic #ifndef lint 12*50595Sbostic static char sccsid[] = "@(#)lprint.c 5.14 (Berkeley) 07/27/91"; 1337660Sbostic #endif /* not lint */ 1437660Sbostic 1537660Sbostic #include <sys/types.h> 1637660Sbostic #include <sys/file.h> 1737660Sbostic #include <sys/stat.h> 1837660Sbostic #include <sys/time.h> 1937660Sbostic #include <tzfile.h> 2037660Sbostic #include <stdio.h> 2138901Sbostic #include <ctype.h> 2243857Sbostic #include <paths.h> 2337660Sbostic #include "finger.h" 2437660Sbostic 2537660Sbostic #define LINE_LEN 80 2637660Sbostic #define TAB_LEN 8 /* 8 spaces between tabs */ 27*50595Sbostic #define _PATH_FORWARD ".forward" 2837660Sbostic #define _PATH_PLAN ".plan" 2937660Sbostic #define _PATH_PROJECT ".project" 3037660Sbostic 3137660Sbostic lflag_print() 3237660Sbostic { 3337660Sbostic extern int pplan; 3437660Sbostic register PERSON *pn; 3537660Sbostic 3637664Sedward for (pn = phead;;) { 3737660Sbostic lprint(pn); 3837660Sbostic if (!pplan) { 39*50595Sbostic (void)show_text(pn->dir, 40*50595Sbostic _PATH_FORWARD, "Mail forwarded to"); 41*50595Sbostic (void)show_text(pn->dir, _PATH_PROJECT, "Project"); 42*50595Sbostic if (!show_text(pn->dir, _PATH_PLAN, "Plan")) 4337660Sbostic (void)printf("No Plan.\n"); 4437660Sbostic } 4537660Sbostic if (!(pn = pn->next)) 4637660Sbostic break; 4737660Sbostic putchar('\n'); 4837660Sbostic } 4937660Sbostic } 5037660Sbostic 5137660Sbostic lprint(pn) 5237660Sbostic register PERSON *pn; 5337660Sbostic { 5437660Sbostic extern time_t now; 5537660Sbostic register struct tm *delta; 5637664Sedward register WHERE *w; 5737660Sbostic register int cpr, len, maxlen; 5842919Sbostic struct tm *tp; 5937660Sbostic int oddfield; 6037660Sbostic time_t time(); 6142919Sbostic char *t, *tzn, *prphone(); 6237660Sbostic 6337660Sbostic /* 6437660Sbostic * long format -- 6537660Sbostic * login name 6637660Sbostic * real name 6737660Sbostic * home directory 6837660Sbostic * shell 6937660Sbostic * office, office phone, home phone if available 7037660Sbostic */ 7137660Sbostic (void)printf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s", 7237660Sbostic pn->name, pn->realname, pn->dir); 7337660Sbostic (void)printf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL); 7437660Sbostic 7537660Sbostic /* 7637660Sbostic * try and print office, office phone, and home phone on one line; 7737660Sbostic * if that fails, do line filling so it looks nice. 7837660Sbostic */ 7937660Sbostic #define OFFICE_TAG "Office" 8037660Sbostic #define OFFICE_PHONE_TAG "Office Phone" 8137660Sbostic oddfield = 0; 8237660Sbostic if (pn->office && pn->officephone && 8337660Sbostic strlen(pn->office) + strlen(pn->officephone) + 8437660Sbostic sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN) { 85*50595Sbostic (void)snprintf(tbuf, sizeof(tbuf), "%s: %s, %s", 86*50595Sbostic OFFICE_TAG, pn->office, prphone(pn->officephone)); 8737660Sbostic oddfield = demi_print(tbuf, oddfield); 8837660Sbostic } else { 8937660Sbostic if (pn->office) { 90*50595Sbostic (void)snprintf(tbuf, sizeof(tbuf), "%s: %s", 91*50595Sbostic OFFICE_TAG, pn->office); 9237660Sbostic oddfield = demi_print(tbuf, oddfield); 9337660Sbostic } 9437660Sbostic if (pn->officephone) { 95*50595Sbostic (void)snprintf(tbuf, sizeof(tbuf), "%s: %s", 96*50595Sbostic OFFICE_PHONE_TAG, prphone(pn->officephone)); 9737660Sbostic oddfield = demi_print(tbuf, oddfield); 9837660Sbostic } 9937660Sbostic } 10037660Sbostic if (pn->homephone) { 101*50595Sbostic (void)snprintf(tbuf, sizeof(tbuf), "%s: %s", "Home Phone", 10238052Sbostic prphone(pn->homephone)); 10337660Sbostic oddfield = demi_print(tbuf, oddfield); 10437660Sbostic } 10537660Sbostic if (oddfield) 10637660Sbostic putchar('\n'); 10737660Sbostic 10837660Sbostic /* 10937664Sedward * long format con't: * if logged in 11037660Sbostic * terminal 11137660Sbostic * idle time 11237660Sbostic * if messages allowed 11337660Sbostic * where logged in from 11437664Sedward * if not logged in 11537664Sedward * when last logged in 11637660Sbostic */ 11737664Sedward /* find out longest device name for this user for formatting */ 11837775Sbostic for (w = pn->whead, maxlen = -1; w != NULL; w = w->next) 11937664Sedward if ((len = strlen(w->tty)) > maxlen) 12037664Sedward maxlen = len; 12137664Sedward /* find rest of entries for user */ 12237664Sedward for (w = pn->whead; w != NULL; w = w->next) { 12337664Sedward switch (w->info) { 12437664Sedward case LOGGEDIN: 12542919Sbostic tp = localtime(&w->loginat); 12642919Sbostic t = asctime(tp); 12742919Sbostic tzn = tp->tm_zone; 12845455Sbostic cpr = printf("On since %.16s (%s) on %s", 12942919Sbostic t, tzn, w->tty); 13037660Sbostic /* 13137660Sbostic * idle time is tough; if have one, print a comma, 13237660Sbostic * then spaces to pad out the device name, then the 13337660Sbostic * idle time. Follow with a comma if a remote login. 13437660Sbostic */ 13537664Sedward delta = gmtime(&w->idletime); 13637660Sbostic if (delta->tm_yday || delta->tm_hour || delta->tm_min) { 13737660Sbostic cpr += printf("%-*s idle ", 13837664Sedward maxlen - strlen(w->tty) + 1, ","); 13937660Sbostic if (delta->tm_yday > 0) { 14037660Sbostic cpr += printf("%d day%s ", 14137660Sbostic delta->tm_yday, 14237660Sbostic delta->tm_yday == 1 ? "" : "s"); 14337660Sbostic } 14437660Sbostic cpr += printf("%d:%02d", 14537660Sbostic delta->tm_hour, delta->tm_min); 14637664Sedward if (*w->host) { 14737660Sbostic putchar(','); 14837660Sbostic ++cpr; 14937660Sbostic } 15037660Sbostic } 15137664Sedward if (!w->writable) 15237660Sbostic cpr += printf(" (messages off)"); 15337664Sedward break; 15437664Sedward case LASTLOG: 15537664Sedward if (w->loginat == 0) { 15637664Sedward (void)printf("Never logged in."); 15737664Sedward break; 15837660Sbostic } 15942919Sbostic tp = localtime(&w->loginat); 16042919Sbostic t = asctime(tp); 16142919Sbostic tzn = tp->tm_zone; 16237664Sedward if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2) 16345455Sbostic cpr = 16445455Sbostic printf("Last login %.16s %.4s (%s) on %s", 16542919Sbostic t, t + 20, tzn, w->tty); 16637664Sedward else 16745455Sbostic cpr = printf("Last login %.16s (%s) on %s", 16842919Sbostic t, tzn, w->tty); 16937664Sedward break; 17037660Sbostic } 17137664Sedward if (*w->host) { 17237664Sedward if (LINE_LEN < (cpr + 6 + strlen(w->host))) 17337660Sbostic (void)printf("\n "); 17437664Sedward (void)printf(" from %s", w->host); 17537660Sbostic } 17637660Sbostic putchar('\n'); 17737660Sbostic } 17837660Sbostic } 17937660Sbostic 18037660Sbostic demi_print(str, oddfield) 18137660Sbostic char *str; 18237660Sbostic int oddfield; 18337660Sbostic { 18437660Sbostic static int lenlast; 18537660Sbostic int lenthis, maxlen; 18637660Sbostic 18737660Sbostic lenthis = strlen(str); 18837660Sbostic if (oddfield) { 18937660Sbostic /* 19037660Sbostic * We left off on an odd number of fields. If we haven't 19137660Sbostic * crossed the midpoint of the screen, and we have room for 19237660Sbostic * the next field, print it on the same line; otherwise, 19337660Sbostic * print it on a new line. 19437660Sbostic * 19537660Sbostic * Note: we insist on having the right hand fields start 19637660Sbostic * no less than 5 tabs out. 19737660Sbostic */ 19837660Sbostic maxlen = 5 * TAB_LEN; 19937660Sbostic if (maxlen < lenlast) 20037660Sbostic maxlen = lenlast; 20137660Sbostic if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) + 20237660Sbostic lenthis) <= LINE_LEN) { 20337660Sbostic while(lenlast < (4 * TAB_LEN)) { 20437660Sbostic putchar('\t'); 20537660Sbostic lenlast += TAB_LEN; 20637660Sbostic } 20737660Sbostic (void)printf("\t%s\n", str); /* force one tab */ 20837660Sbostic } else { 20937660Sbostic (void)printf("\n%s", str); /* go to next line */ 21037660Sbostic oddfield = !oddfield; /* this'll be undone below */ 21137660Sbostic } 21237660Sbostic } else 21337660Sbostic (void)printf("%s", str); 21437660Sbostic oddfield = !oddfield; /* toggle odd/even marker */ 21537660Sbostic lenlast = lenthis; 21637660Sbostic return(oddfield); 21737660Sbostic } 21837660Sbostic 21937660Sbostic show_text(directory, file_name, header) 22037660Sbostic char *directory, *file_name, *header; 22137660Sbostic { 222*50595Sbostic struct stat sb; 22339241Sedward register FILE *fp; 224*50595Sbostic register int ch, cnt, lastc; 225*50595Sbostic register char *p; 226*50595Sbostic int fd, nr; 22737660Sbostic 228*50595Sbostic (void)snprintf(tbuf, sizeof(tbuf), "%s/%s", directory, file_name); 229*50595Sbostic if ((fd = open(tbuf, O_RDONLY)) < 0 || fstat(fd, &sb) || 230*50595Sbostic sb.st_size == 0) 23137660Sbostic return(0); 232*50595Sbostic 233*50595Sbostic /* If short enough, and no newlines, show it on a single line.*/ 234*50595Sbostic if (sb.st_size <= LINE_LEN - strlen(header) - 5) { 235*50595Sbostic nr = read(fd, tbuf, sizeof(tbuf)); 236*50595Sbostic if (nr <= 0) { 237*50595Sbostic (void)close(fd); 238*50595Sbostic return(0); 239*50595Sbostic } 240*50595Sbostic for (p = tbuf, cnt = nr; cnt--; ++p) 241*50595Sbostic if (*p == '\n') 242*50595Sbostic break; 243*50595Sbostic if (cnt <= 1) { 244*50595Sbostic (void)printf("%s: ", header); 245*50595Sbostic for (p = tbuf, cnt = nr; cnt--; ++p) 246*50595Sbostic vputc(lastc = *p); 247*50595Sbostic if (lastc != '\n') 248*50595Sbostic (void)putchar('\n'); 249*50595Sbostic (void)close(fd); 250*50595Sbostic return(1); 251*50595Sbostic } 252*50595Sbostic else 253*50595Sbostic (void)lseek(fd, 0L, SEEK_SET); 254*50595Sbostic } 255*50595Sbostic if ((fp = fdopen(fd, "r")) == NULL) 256*50595Sbostic return(0); 257*50595Sbostic (void)printf("%s:\n", header); 25839241Sedward while ((ch = getc(fp)) != EOF) 25939241Sedward vputc(lastc = ch); 26039241Sedward if (lastc != '\n') 26138901Sbostic (void)putchar('\n'); 26239241Sedward (void)fclose(fp); 26337660Sbostic return(1); 26437660Sbostic } 26538901Sbostic 26638901Sbostic vputc(ch) 26738901Sbostic register int ch; 26838901Sbostic { 26938901Sbostic int meta; 27038901Sbostic 27138901Sbostic if (!isascii(ch)) { 27238901Sbostic (void)putchar('M'); 27338901Sbostic (void)putchar('-'); 27438901Sbostic ch = toascii(ch); 27538901Sbostic meta = 1; 27638901Sbostic } else 27738901Sbostic meta = 0; 27838912Sbostic if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n')) 27938901Sbostic (void)putchar(ch); 28038901Sbostic else { 28138901Sbostic (void)putchar('^'); 28238901Sbostic (void)putchar(ch == '\177' ? '?' : ch | 0100); 28338901Sbostic } 28438901Sbostic } 285