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. 7: * 8: * Redistribution and use in source and binary forms are permitted 9: * provided that the above copyright notice and this paragraph are 10: * duplicated in all such forms and that any documentation, 11: * advertising materials, and other materials related to such 12: * distribution and use acknowledge that the software was developed 13: * by the University of California, Berkeley. The name of the 14: * University may not be used to endorse or promote products derived 15: * from this software without specific prior written permission. 16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19: */ 20: 21: #ifndef lint 22: static char sccsid[] = "@(#)lprint.c 5.9 (Berkeley) 2/7/90"; 23: #endif /* not lint */ 24: 25: #include <sys/types.h> 26: #include <sys/file.h> 27: #include <sys/stat.h> 28: #include <sys/time.h> 29: #include <tzfile.h> 30: #include <stdio.h> 31: #include <ctype.h> 32: #include "finger.h" 33: #include "pathnames.h" 34: 35: #define LINE_LEN 80 36: #define TAB_LEN 8 /* 8 spaces between tabs */ 37: #define _PATH_PLAN ".plan" 38: #define _PATH_PROJECT ".project" 39: 40: lflag_print() 41: { 42: extern int pplan; 43: register PERSON *pn; 44: 45: for (pn = phead;;) { 46: lprint(pn); 47: if (!pplan) { 48: (void)show_text(pn->dir, _PATH_PROJECT, "Project:"); 49: if (!show_text(pn->dir, _PATH_PLAN, "Plan:")) 50: (void)printf("No Plan.\n"); 51: } 52: if (!(pn = pn->next)) 53: break; 54: putchar('\n'); 55: } 56: } 57: 58: lprint(pn) 59: register PERSON *pn; 60: { 61: extern time_t now; 62: register struct tm *delta; 63: register WHERE *w; 64: register int cpr, len, maxlen; 65: int oddfield; 66: time_t time(); 67: char *t, *ctime(), *prphone(); 68: 69: /* 70: * long format -- 71: * login name 72: * real name 73: * home directory 74: * shell 75: * office, office phone, home phone if available 76: */ 77: (void)printf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s", 78: pn->name, pn->realname, pn->dir); 79: (void)printf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL); 80: 81: /* 82: * try and print office, office phone, and home phone on one line; 83: * if that fails, do line filling so it looks nice. 84: */ 85: #define OFFICE_TAG "Office" 86: #define OFFICE_PHONE_TAG "Office Phone" 87: oddfield = 0; 88: if (pn->office && pn->officephone && 89: strlen(pn->office) + strlen(pn->officephone) + 90: sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN) { 91: (void)sprintf(tbuf, "%s: %s, %s", OFFICE_TAG, pn->office, 92: prphone(pn->officephone)); 93: oddfield = demi_print(tbuf, oddfield); 94: } else { 95: if (pn->office) { 96: (void)sprintf(tbuf, "%s: %s", OFFICE_TAG, pn->office); 97: oddfield = demi_print(tbuf, oddfield); 98: } 99: if (pn->officephone) { 100: (void)sprintf(tbuf, "%s: %s", OFFICE_PHONE_TAG, 101: prphone(pn->officephone)); 102: oddfield = demi_print(tbuf, oddfield); 103: } 104: } 105: if (pn->homephone) { 106: (void)sprintf(tbuf, "%s: %s", "Home Phone", 107: prphone(pn->homephone)); 108: oddfield = demi_print(tbuf, oddfield); 109: } 110: if (oddfield) 111: putchar('\n'); 112: 113: /* 114: * long format con't: * if logged in 115: * terminal 116: * idle time 117: * if messages allowed 118: * where logged in from 119: * if not logged in 120: * when last logged in 121: */ 122: /* find out longest device name for this user for formatting */ 123: for (w = pn->whead, maxlen = -1; w != NULL; w = w->next) 124: if ((len = strlen(w->tty)) > maxlen) 125: maxlen = len; 126: /* find rest of entries for user */ 127: for (w = pn->whead; w != NULL; w = w->next) { 128: switch (w->info) { 129: case LOGGEDIN: 130: cpr = printf("On since %16.16s on %s", 131: ctime(&w->loginat), w->tty); 132: /* 133: * idle time is tough; if have one, print a comma, 134: * then spaces to pad out the device name, then the 135: * idle time. Follow with a comma if a remote login. 136: */ 137: delta = gmtime(&w->idletime); 138: if (delta->tm_yday || delta->tm_hour || delta->tm_min) { 139: cpr += printf("%-*s idle ", 140: maxlen - strlen(w->tty) + 1, ","); 141: if (delta->tm_yday > 0) { 142: cpr += printf("%d day%s ", 143: delta->tm_yday, 144: delta->tm_yday == 1 ? "" : "s"); 145: } 146: cpr += printf("%d:%02d", 147: delta->tm_hour, delta->tm_min); 148: if (*w->host) { 149: putchar(','); 150: ++cpr; 151: } 152: } 153: if (!w->writable) 154: cpr += printf(" (messages off)"); 155: break; 156: case LASTLOG: 157: if (w->loginat == 0) { 158: (void)printf("Never logged in."); 159: break; 160: } 161: t = ctime(&w->loginat); 162: if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2) 163: cpr = printf("Last login %10.10s, %4.4s on %s", 164: t, t + 20, w->tty); 165: else 166: cpr = printf("Last login %16.16s on %s", 167: t, w->tty); 168: break; 169: } 170: if (*w->host) { 171: if (LINE_LEN < (cpr + 6 + strlen(w->host))) 172: (void)printf("\n "); 173: (void)printf(" from %s", w->host); 174: } 175: putchar('\n'); 176: } 177: } 178: 179: demi_print(str, oddfield) 180: char *str; 181: int oddfield; 182: { 183: static int lenlast; 184: int lenthis, maxlen; 185: 186: lenthis = strlen(str); 187: if (oddfield) { 188: /* 189: * We left off on an odd number of fields. If we haven't 190: * crossed the midpoint of the screen, and we have room for 191: * the next field, print it on the same line; otherwise, 192: * print it on a new line. 193: * 194: * Note: we insist on having the right hand fields start 195: * no less than 5 tabs out. 196: */ 197: maxlen = 5 * TAB_LEN; 198: if (maxlen < lenlast) 199: maxlen = lenlast; 200: if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) + 201: lenthis) <= LINE_LEN) { 202: while(lenlast < (4 * TAB_LEN)) { 203: putchar('\t'); 204: lenlast += TAB_LEN; 205: } 206: (void)printf("\t%s\n", str); /* force one tab */ 207: } else { 208: (void)printf("\n%s", str); /* go to next line */ 209: oddfield = !oddfield; /* this'll be undone below */ 210: } 211: } else 212: (void)printf("%s", str); 213: oddfield = !oddfield; /* toggle odd/even marker */ 214: lenlast = lenthis; 215: return(oddfield); 216: } 217: 218: show_text(directory, file_name, header) 219: char *directory, *file_name, *header; 220: { 221: register int ch, lastc; 222: register FILE *fp; 223: 224: (void)sprintf(tbuf, "%s/%s", directory, file_name); 225: if ((fp = fopen(tbuf, "r")) == NULL) 226: return(0); 227: (void)printf("%s\n", header); 228: while ((ch = getc(fp)) != EOF) 229: vputc(lastc = ch); 230: if (lastc != '\n') 231: (void)putchar('\n'); 232: (void)fclose(fp); 233: return(1); 234: } 235: 236: vputc(ch) 237: register int ch; 238: { 239: int meta; 240: 241: if (!isascii(ch)) { 242: (void)putchar('M'); 243: (void)putchar('-'); 244: ch = toascii(ch); 245: meta = 1; 246: } else 247: meta = 0; 248: if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n')) 249: (void)putchar(ch); 250: else { 251: (void)putchar('^'); 252: (void)putchar(ch == '\177' ? '?' : ch | 0100); 253: } 254: }