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