|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)catman.c 5.7 (Berkeley) 5/27/86";
15: #endif not lint
16:
17: /*
18: * catman: update cat'able versions of manual pages
19: * (whatis database also)
20: */
21: #include <stdio.h>
22: #include <sys/types.h>
23: #include <sys/stat.h>
24: #include <sys/file.h>
25: #include <sys/time.h>
26: #include <sys/dir.h>
27: #include <ctype.h>
28:
29: char buf[BUFSIZ];
30: char pflag;
31: char nflag;
32: char wflag;
33: char man[MAXNAMLEN+6] = "manx/";
34: int exstat = 0;
35: char cat[MAXNAMLEN+6] = "catx/";
36: char lncat[MAXNAMLEN+9] = "../catx/";
37: char *manpath = "/usr/man";
38: char *sections = "12345678ln";
39: char *makewhatis = "/usr/lib/makewhatis";
40: char *index(), *rindex();
41: char *strcpy();
42: char *getenv();
43:
44: main(ac, av)
45: int ac;
46: char *av[];
47: {
48: char *mp, *nextp;
49:
50: if ((mp = getenv("MANPATH")) != NULL)
51: manpath = mp;
52:
53: ac--, av++;
54: while (ac > 0 && av[0][0] == '-') {
55: switch (av[0][1]) {
56:
57: case 'p':
58: pflag++;
59: break;
60:
61: case 'n':
62: nflag++;
63: break;
64:
65: case 'w':
66: wflag++;
67: break;
68:
69: case 'M':
70: case 'P':
71: if (ac < 1) {
72: fprintf(stderr, "%s: missing path\n",
73: av[0]);
74: exit(1);
75: }
76: ac--, av++;
77: manpath = *av;
78: break;
79:
80: default:
81: goto usage;
82: }
83: ac--, av++;
84: }
85: if (ac > 1) {
86: usage:
87: printf("usage: catman [ -p ] [ -n ] [ -w ] [ -M path ] [ sections ]\n");
88: exit(-1);
89: }
90: if (ac == 1)
91: sections = *av;
92: for (mp = manpath; mp && ((nextp = index(mp, ':')), 1); mp = nextp) {
93: if (nextp)
94: *nextp++ = '\0';
95: doit(mp);
96: }
97: exit(exstat);
98: }
99:
100: doit(mandir)
101: char *mandir;
102: {
103: register char *msp, *csp, *sp;
104: int changed = 0;
105: int status;
106:
107: if (wflag)
108: goto whatis;
109: if (chdir(mandir) < 0) {
110: sprintf(buf, "catman: %s", mandir);
111: perror(buf);
112: /* exstat = 1; */
113: return;
114: }
115: if (pflag)
116: printf("cd %s\n", mandir);
117: msp = &man[5];
118: csp = &cat[5];
119: (void) umask(0);
120: for (sp = sections; *sp; sp++) {
121: register DIR *mdir;
122: register struct direct *dir;
123: struct stat sbuf;
124:
125: man[3] = cat[3] = *sp;
126: *msp = *csp = '\0';
127: if ((mdir = opendir(man)) == NULL) {
128: sprintf(buf, "catman: opendir: %s", man);
129: perror(buf);
130: /* exstat = 1; */
131: continue;
132: }
133: if (stat(cat, &sbuf) < 0) {
134: register char *cp;
135:
136: (void) strcpy(buf, cat);
137: cp = rindex(buf, '/');
138: if (cp && cp[1] == '\0')
139: *cp = '\0';
140: if (pflag)
141: printf("mkdir %s\n", buf);
142: else if (mkdir(buf, 0777) < 0) {
143: sprintf(buf, "catman: mkdir: %s", cat);
144: perror(buf);
145: exstat = 1;
146: continue;
147: }
148: (void) stat(cat, &sbuf);
149: }
150: if (access(cat, R_OK|W_OK|X_OK) == -1) {
151: sprintf(buf, "catman: %s", cat);
152: perror(buf);
153: exstat = 1;
154: continue;
155: }
156: if ((sbuf.st_mode & S_IFMT) != S_IFDIR) {
157: fprintf(stderr, "catman: %s: Not a directory\n", cat);
158: exstat = 1;
159: continue;
160: }
161: while ((dir = readdir(mdir)) != NULL) {
162: time_t time;
163: register char *tsp;
164: FILE *inf;
165: int makelink;
166:
167: if (dir->d_ino == 0 || dir->d_name[0] == '.')
168: continue;
169: /*
170: * Make sure this is a man file, i.e., that it
171: * ends in .[0-9] or .[0-9][a-z]
172: */
173: tsp = rindex(dir->d_name, '.');
174: if (tsp == NULL)
175: continue;
176: if (!isdigit(*++tsp) && *tsp != *sp)
177: continue;
178: if (*++tsp && !isalpha(*tsp))
179: continue;
180: if (*tsp && *++tsp)
181: continue;
182: (void) strcpy(msp, dir->d_name);
183: if ((inf = fopen(man, "r")) == NULL) {
184: sprintf(buf, "catman: %s");
185: perror(buf);
186: exstat = 1;
187: continue;
188: }
189: makelink = 0;
190: if (getc(inf) == '.' && getc(inf) == 's'
191: && getc(inf) == 'o') {
192: if (getc(inf) != ' ' ||
193: fgets(lncat+3, sizeof(lncat)-3, inf)==NULL) {
194: fclose(inf);
195: continue;
196: }
197: if (lncat[strlen(lncat)-1] == '\n')
198: lncat[strlen(lncat)-1] = '\0';
199: if (strncmp(lncat+3, "man", 3) != 0) {
200: fclose(inf);
201: continue;
202: }
203: bcopy("../cat", lncat, sizeof("../cat")-1);
204: makelink = 1;
205: }
206: fclose(inf);
207: (void) strcpy(csp, dir->d_name);
208: if (stat(cat, &sbuf) >= 0) {
209: time = sbuf.st_mtime;
210: (void) stat(man, &sbuf);
211: if (time >= sbuf.st_mtime)
212: continue;
213: (void) unlink(cat);
214: }
215: if (makelink) {
216: /*
217: * Don't unlink a directory by accident.
218: */
219: if (stat(lncat+3, &sbuf) >= 0 &&
220: (((sbuf.st_mode&S_IFMT)==S_IFREG) ||
221: ((sbuf.st_mode&S_IFMT)==S_IFLNK)))
222: (void) unlink(cat);
223: if (pflag)
224: printf("ln -s %s %s\n", lncat, cat);
225: else
226: if (symlink(lncat, cat) == -1) {
227: sprintf(buf, "catman: symlink: %s", cat);
228: perror(buf);
229: exstat = 1;
230: continue;
231: }
232: }
233: else {
234: sprintf(buf, "nroff -man %s > %s", man, cat);
235: if (pflag)
236: printf("%s\n", buf);
237: else if ((status = system(buf)) != 0) {
238: fprintf(stderr, "catman: nroff: %s: exit status %d: Owooooo!\n", cat, status);
239: exstat = 1;
240: continue;
241: }
242: }
243: changed = 1;
244: }
245: closedir(mdir);
246: }
247: if (changed && !nflag) {
248: whatis:
249: sprintf(buf, "%s %s", makewhatis, mandir);
250: if (pflag)
251: printf("%s\n", buf);
252: else if ((status = system(buf)) != 0) {
253: fprintf(stderr, "catman: %s: exit status %d\n",
254: buf, status);
255: exstat = 1;
256: }
257: }
258: return;
259: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.