1: #ifndef lint
   2: static char sccsid[]    = "@(#)man.c	1.10 (Berkeley) 9/19/83";
   3: #endif
   4: 
   5: #include <whoami.h>
   6: #include <stdio.h>
   7: #include <ctype.h>
   8: #include <sgtty.h>
   9: #include <sys/types.h>
  10: #include <stat.h>
  11: #include <signal.h>
  12: /*
  13:  * man
  14:  * link also to apropos and whatis
  15:  * This version uses cat -s for eliminating multiple blank lines,
  16:  * and more for underlining and paging.
  17:  */
  18: #define MANDIR  "/usr/man"      /* this is deeply embedded */
  19: #define NROFFCAT "nroff -man"       /* for nroffing to cat file */
  20: #define SSP "cat -s"        /* compression for cat file */
  21: #define NROFF   "nroff -man"        /* for nroffing to tty */
  22: #define MORE    "more -s"       /* paging filter */
  23: #define CAT "cat"           /* for '-' opt (no more) */
  24: #define TROFF1  "troff -man"        /* for -t option */
  25: #define TROFF2  ""          /* for troff to pipe to */
  26: /*  for vtroff:
  27:   #define TROFF1 "troff -t -man /usr/lib/tmac/tmac.vcat"
  28:   #define TROFF2 "| /usr/lib/rvsort |/usr/lib/vpr -t"
  29: */
  30: 
  31: #define ALLSECT "1unl6823457p"  /* order to look through sections */
  32: #define SECT1   "1unl"      /* sections to look at if 1 is specified */
  33: #define SUBSEC1 "mcg"       /* subsections to look for in sect. 1 */
  34: #define SUBSEC2 "jv"        /* subsections, section 2 */
  35: #define SUBSEC3 "jxmsf"     /* subsections, section 3 */
  36: 
  37: #if !defined(VMUNIX) && !defined(VIRUS_VFORK)
  38: #define vfork   fork
  39: #endif
  40: 
  41: int nomore;
  42: char    *strcpy();
  43: char    *strcat();
  44: char    *trim();
  45: int remove();
  46: int section;
  47: int subsec;
  48: int troffit;
  49: 
  50: #define eq(a,b) (strcmp(a,b) == 0)
  51: 
  52: main(argc, argv)
  53:     int argc;
  54:     char *argv[];
  55: {
  56: 
  57:     if (signal(SIGINT, SIG_IGN) == SIG_DFL) {
  58:         signal(SIGINT, remove);
  59:         signal(SIGQUIT, remove);
  60:         signal(SIGTERM, remove);
  61:     }
  62:     umask(0);
  63:     if (chdir(MANDIR) < 0) {
  64:         fprintf(stderr, "Can't chdir to %s.\n", MANDIR);
  65:         exit(1);
  66:     }
  67:     if (strcmp(argv[0], "apropos") == 0) {
  68:         apropos(argc-1, argv+1);
  69:         exit(0);
  70:     }
  71:     if (strcmp(argv[0], "whatis") == 0) {
  72:         whatis(argc-1, argv+1);
  73:         exit(0);
  74:     }
  75:     if (argc <= 1) {
  76:         fprintf(stderr, "Usage: man [ section ] name ...\n");
  77:         exit(1);
  78:     }
  79:     argc--, argv++;
  80:     while (argc > 0 && argv[0][0] == '-') {
  81:         switch(argv[0][1]) {
  82: 
  83:         case 0:
  84:             nomore++;
  85:             break;
  86: 
  87:         case 't':
  88:             troffit++;
  89:             break;
  90: 
  91:         case 'k':
  92:             apropos(argc-1, argv+1);
  93:             exit(0);
  94: 
  95:         case 'f':
  96:             whatis(argc-1, argv+1);
  97:             exit(0);
  98:         }
  99:         argc--, argv++;
 100:     }
 101:     if (troffit == 0 && nomore == 0 && !isatty(1))
 102:         nomore++;
 103:     section = 0;
 104:     do {
 105:         if (eq(argv[0], "local")) {
 106:             section = 'l';
 107:             goto sectin;
 108:         } else if (eq(argv[0], "new")) {
 109:             section = 'n';
 110:             goto sectin;
 111:         } else if (eq(argv[0], "public")) {
 112:             section = 'p';
 113:             goto sectin;
 114:         } else if (eq(argv[0], "ucb")) {
 115:             section = 'u';
 116:             goto sectin;
 117:         } else if (argv[0][0] >= '0' && argv[0][0] <= '9' && (argv[0][1] == 0 || argv[0][2] == 0)) {
 118:             section = argv[0][0];
 119:             subsec = argv[0][1];
 120: sectin:
 121:             argc--, argv++;
 122:             if (argc == 0) {
 123:                 fprintf(stderr, "But what do you want from section %s?\n", argv[-1]);
 124:                 exit(1);
 125:             }
 126:             continue;
 127:         }
 128:         manual(section, argv[0]);
 129:         argc--, argv++;
 130:     } while (argc > 0);
 131:     exit(0);
 132: }
 133: 
 134: manual(sec, name)
 135:     char sec;
 136:     char *name;
 137: {
 138:     char section = sec;
 139:     char work[100], work2[100], cmdbuf[150];
 140:     struct stat stbuf, stbuf2;
 141:     int last;
 142:     char *sp = ALLSECT;
 143: 
 144:     strcpy(work, "manx/");
 145:     strcat(work, name);
 146:     strcat(work, ".x");
 147:     last = strlen(work) - 1;
 148:     if (section == '1') {
 149:         sp = SECT1;
 150:         section = 0;
 151:     }
 152:     if (section == 0) {
 153:         for (section = *sp++; section; section = *sp++) {
 154:             work[3] = section;
 155:             work[last] = section;
 156:             work[last+1] = 0;
 157:             work[last+2] = 0;
 158:             if (stat(work, &stbuf) >= 0)
 159:                 break;
 160:             if (work[last] >= '1' && work[last] <= '3') {
 161:                 char *cp;
 162: search:
 163:                 switch (work[last]) {
 164:                 case '1': cp = SUBSEC1; break;
 165:                 case '2': cp = SUBSEC2; break;
 166:                 case '3': cp = SUBSEC3; break;
 167:                 }
 168:                 while (*cp) {
 169:                     work[last+1] = *cp++;
 170:                     if (stat(work, &stbuf) >= 0)
 171:                         goto found;
 172:                 }
 173:                 work[last+1] = 0;
 174:             }
 175:         }
 176:         if (section == 0) {
 177:             if (sec == 0)
 178:                 printf("No manual entry for %s.\n", name);
 179:             else
 180:                 printf("No entry for %s in section %c of the manual.\n", name, sec);
 181:             return;
 182:         }
 183:     } else {
 184:         work[3] = section;
 185:         work[last] = section;
 186:         work[last+1] = subsec;
 187:         work[last+2] = 0;
 188:         if (stat(work, &stbuf) < 0) {
 189:             if ((section >= '1' && section <= '3') && subsec == 0) {
 190:                 sp = "\0";
 191:                 goto search;
 192:             }
 193:             printf("No entry for %s in section %c", name, section);
 194:             if (subsec)
 195:                 putchar(subsec);
 196:             printf(" of the manual.\n");
 197:             return;
 198:         }
 199:     }
 200: found:
 201:     if (troffit)
 202:         troff(work);
 203:     else {
 204:         FILE *it;
 205:         char abuf[BUFSIZ];
 206: 
 207:         if (!nomore) {
 208:             it = fopen(work, "r");
 209:             if (fgets(abuf, BUFSIZ-1, it) &&
 210:                abuf[0] == '.' && abuf[1] == 's' &&
 211:                abuf[2] == 'o' && abuf[3] == ' ') {
 212:                 register char *cp = abuf+strlen(".so ");
 213:                 char *dp;
 214: 
 215:                 while (*cp && *cp != '\n')
 216:                     cp++;
 217:                 *cp = 0;
 218:                 while (cp > abuf && *--cp != '/')
 219:                     ;
 220:                 dp = ".so /usr/man/man";
 221:                 if (cp != abuf+strlen(dp)+1) {
 222: tohard:
 223:                     strcpy(work, abuf+4);
 224:                     goto hardway;
 225:                 }
 226:                 for (cp = abuf; *cp == *dp && *cp; cp++, dp++)
 227:                     ;
 228:                 if (*dp)
 229:                     goto tohard;
 230:                 strcpy(work, cp-3);
 231:                 (void) stat(abuf+strlen(".so "), &stbuf);
 232:             }
 233:             fclose(it);
 234:             strcpy(work2, "cat");
 235:             strcpy(work2+3, work+3);
 236:             work2[4] = 0;
 237:             if (stat(work2, &stbuf2) < 0)
 238:                 goto hardway;
 239:             strcpy(work2+3, work+3);
 240:             if (stat(work2, &stbuf2) < 0
 241:                 || stbuf2.st_mtime < stbuf.st_mtime) {
 242:                 printf("Reformatting page.  Wait...");
 243:                 fflush(stdout);
 244:                 unlink(work2);
 245:                 sprintf(cmdbuf,
 246:             "%s %s |%s> /tmp/man%d; trap '' 1 15; mv /tmp/man%d %s",
 247:                 NROFFCAT, work, SSP, getpid(), getpid(), work2);
 248:                 if (system(cmdbuf)) {
 249:                     printf(" aborted (sorry)\n");
 250:                     remove();
 251:                     /*NOTREACHED*/
 252:                 }
 253:                 printf(" done\n");
 254:             }
 255:             strcpy(work, work2);
 256:         }
 257: hardway:
 258:         nroff(work);
 259:     }
 260: }
 261: 
 262: nroff(cp)
 263:     char *cp;
 264: {
 265:     char cmd[BUFSIZ];
 266: 
 267:     if (cp[0] == 'c')
 268:         sprintf(cmd, "%s %s", nomore? CAT : MORE, cp);
 269:     else
 270:         sprintf(cmd, nomore? "%s %s" : "%s %s|%s", NROFF, cp, MORE);
 271:     system(cmd);
 272: }
 273: 
 274: troff(cp)
 275:     char *cp;
 276: {
 277:     char cmdbuf[BUFSIZ];
 278: 
 279:     sprintf(cmdbuf, "%s %s %s", TROFF1, cp, TROFF2);
 280:     system(cmdbuf);
 281: }
 282: 
 283: any(c, sp)
 284:     register int c;
 285:     register char *sp;
 286: {
 287:     register int d;
 288: 
 289:     while (d = *sp++)
 290:         if (c == d)
 291:             return (1);
 292:     return (0);
 293: }
 294: 
 295: remove()
 296: {
 297:     char name[15];
 298: 
 299:     sprintf(name, "/tmp/man%d", getpid());
 300:     unlink(name);
 301:     exit(1);
 302: }
 303: 
 304: apropos(argc, argv)
 305:     int argc;
 306:     char **argv;
 307: {
 308:     char buf[BUFSIZ];
 309:     char *gotit;
 310:     register char **vp;
 311: 
 312:     if (argc == 0) {
 313:         fprintf(stderr, "apropos what?\n");
 314:         exit(1);
 315:     }
 316:     if (freopen("/usr/lib/whatis", "r", stdin) == NULL) {
 317:         perror("/usr/lib/whatis");
 318:         exit (1);
 319:     }
 320:     gotit = (char *) calloc(1, blklen(argv));
 321:     while (fgets(buf, sizeof buf, stdin) != NULL)
 322:         for (vp = argv; *vp; vp++)
 323:             if (match(buf, *vp)) {
 324:                 printf("%s", buf);
 325:                 gotit[vp - argv] = 1;
 326:                 for (vp++; *vp; vp++)
 327:                     if (match(buf, *vp))
 328:                         gotit[vp - argv] = 1;
 329:                 break;
 330:             }
 331:     for (vp = argv; *vp; vp++)
 332:         if (gotit[vp - argv] == 0)
 333:             printf("%s: nothing apropriate\n", *vp);
 334: }
 335: 
 336: match(buf, str)
 337:     char *buf, *str;
 338: {
 339:     register char *bp;
 340: 
 341:     bp = buf;
 342:     for (;;) {
 343:         if (*bp == 0)
 344:             return (0);
 345:         if (amatch(bp, str))
 346:             return (1);
 347:         bp++;
 348:     }
 349: }
 350: 
 351: amatch(cp, dp)
 352:     register char *cp, *dp;
 353: {
 354: 
 355:     while (*cp && *dp && lmatch(*cp, *dp))
 356:         cp++, dp++;
 357:     if (*dp == 0)
 358:         return (1);
 359:     return (0);
 360: }
 361: 
 362: lmatch(c, d)
 363:     char c, d;
 364: {
 365: 
 366:     if (c == d)
 367:         return (1);
 368:     if (!isalpha(c) || !isalpha(d))
 369:         return (0);
 370:     if (islower(c))
 371:         c = toupper(c);
 372:     if (islower(d))
 373:         d = toupper(d);
 374:     return (c == d);
 375: }
 376: 
 377: blklen(ip)
 378:     register char **ip;
 379: {
 380:     register int i = 0;
 381: 
 382:     while (*ip++)
 383:         i++;
 384:     return (i);
 385: }
 386: 
 387: whatis(argc, argv)
 388:     int argc;
 389:     char **argv;
 390: {
 391:     register char **avp;
 392: 
 393:     if (argc == 0) {
 394:         fprintf(stderr, "whatis what?\n");
 395:         exit(1);
 396:     }
 397:     if (freopen("/usr/lib/whatis", "r", stdin) == NULL) {
 398:         perror("/usr/lib/whatis");
 399:         exit (1);
 400:     }
 401:     for (avp = argv; *avp; avp++)
 402:         *avp = trim(*avp);
 403:     whatisit(argv);
 404:     exit(0);
 405: }
 406: 
 407: whatisit(argv)
 408:     char **argv;
 409: {
 410:     char buf[BUFSIZ];
 411:     register char *gotit;
 412:     register char **vp;
 413: 
 414:     gotit = (char *)calloc(1, blklen(argv));
 415:     while (fgets(buf, sizeof buf, stdin) != NULL)
 416:         for (vp = argv; *vp; vp++)
 417:             if (wmatch(buf, *vp)) {
 418:                 printf("%s", buf);
 419:                 gotit[vp - argv] = 1;
 420:                 for (vp++; *vp; vp++)
 421:                     if (wmatch(buf, *vp))
 422:                         gotit[vp - argv] = 1;
 423:                 break;
 424:             }
 425:     for (vp = argv; *vp; vp++)
 426:         if (gotit[vp - argv] == 0)
 427:             printf("%s: not found\n", *vp);
 428: }
 429: 
 430: wmatch(buf, str)
 431:     char *buf, *str;
 432: {
 433:     register char *bp, *cp;
 434: 
 435:     bp = buf;
 436: again:
 437:     cp = str;
 438:     while (*bp && *cp && lmatch(*bp, *cp))
 439:         bp++, cp++;
 440:     if (*cp == 0 && (*bp == '(' || *bp == ',' || *bp == '\t' || *bp == ' '))
 441:         return (1);
 442:     while (isalpha(*bp) || isdigit(*bp))
 443:         bp++;
 444:     if (*bp != ',')
 445:         return (0);
 446:     bp++;
 447:     while (isspace(*bp))
 448:         bp++;
 449:     goto again;
 450: }
 451: 
 452: char *
 453: trim(cp)
 454:     register char *cp;
 455: {
 456:     register char *dp;
 457: 
 458:     for (dp = cp; *dp; dp++)
 459:         if (*dp == '/')
 460:             cp = dp + 1;
 461:     if (cp[0] != '.') {
 462:         if (cp + 3 <= dp && dp[-2] == '.' && any(dp[-1], "cosa12345678npP"))
 463:             dp[-2] = 0;
 464:         if (cp + 4 <= dp && dp[-3] == '.' && any(dp[-2], "13") && isalpha(dp[-1]))
 465:             dp[-3] = 0;
 466:     }
 467:     return (cp);
 468: }
 469: 
 470: system(s)
 471: char *s;
 472: {
 473:     int status, pid, w;
 474: 
 475:     if ((pid = vfork()) == 0) {
 476:         execl("/bin/sh", "sh", "-c", s, 0);
 477:         _exit(127);
 478:     }
 479:     while ((w = wait(&status)) != pid && w != -1)
 480:         ;
 481:     if (w == -1)
 482:         status = -1;
 483:     return (status);
 484: }

Defined functions

amatch defined in line 351; used 1 times
any defined in line 283; used 2 times
apropos defined in line 304; used 2 times
blklen defined in line 377; used 2 times
lmatch defined in line 362; used 2 times
main defined in line 52; never used
manual defined in line 134; used 1 times
match defined in line 336; used 2 times
nroff defined in line 262; used 1 times
remove defined in line 295; used 5 times
system defined in line 470; used 3 times
trim defined in line 452; used 2 times
troff defined in line 274; used 1 times
whatis defined in line 387; used 2 times
whatisit defined in line 407; used 1 times
wmatch defined in line 430; used 2 times

Defined variables

nomore defined in line 41; used 6 times
sccsid defined in line 2; never used
section defined in line 46; used 22 times
subsec defined in line 47; used 5 times
troffit defined in line 48; used 3 times

Defined macros

ALLSECT defined in line 31; used 1 times
CAT defined in line 23; used 1 times
MANDIR defined in line 18; used 2 times
MORE defined in line 22; used 2 times
NROFF defined in line 21; used 1 times
NROFFCAT defined in line 19; used 1 times
SECT1 defined in line 32; used 1 times
SSP defined in line 20; used 1 times
SUBSEC1 defined in line 33; used 1 times
SUBSEC2 defined in line 34; used 1 times
SUBSEC3 defined in line 35; used 1 times
TROFF1 defined in line 24; used 1 times
TROFF2 defined in line 25; used 1 times
eq defined in line 50; used 4 times
vfork defined in line 38; used 1 times
Last modified: 1983-09-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1396
Valid CSS Valid XHTML 1.0 Strict