xref: /csrg-svn/old/catman/catman.c (revision 25892)
122487Sdist /*
222487Sdist  * Copyright (c) 1980 Regents of the University of California.
322487Sdist  * All rights reserved.  The Berkeley software License Agreement
422487Sdist  * specifies the terms and conditions for redistribution.
522487Sdist  */
622487Sdist 
711296Ssam #ifndef lint
822487Sdist char copyright[] =
922487Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1022487Sdist  All rights reserved.\n";
1122487Sdist #endif not lint
12964Sbill 
1322487Sdist #ifndef lint
14*25892Sdonn static char sccsid[] = "@(#)catman.c	5.5 (Berkeley) 01/13/86";
1522487Sdist #endif not lint
1622487Sdist 
1711296Ssam /*
1811296Ssam  * catman: update cat'able versions of manual pages
1911296Ssam  *  (whatis database also)
2011296Ssam  */
2111296Ssam #include <stdio.h>
2211296Ssam #include <sys/types.h>
2313549Ssam #include <sys/stat.h>
24*25892Sdonn #include <sys/file.h>
2513549Ssam #include <sys/time.h>
2613549Ssam #include <sys/dir.h>
2711296Ssam #include <ctype.h>
28964Sbill 
2911296Ssam char	buf[BUFSIZ];
3011296Ssam char	pflag;
3111296Ssam char	nflag;
3211296Ssam char	wflag;
3311296Ssam char	man[MAXNAMLEN+6] = "manx/";
34*25892Sdonn int	exstat = 0;
3511296Ssam char	cat[MAXNAMLEN+6] = "catx/";
3624205Smckusick char	lncat[MAXNAMLEN+6] = "catx/";
37*25892Sdonn char	*manpath = "/usr/man";
38*25892Sdonn char	*sections = "12345678ln";
39*25892Sdonn char	*makewhatis = "/usr/lib/makewhatis";
40*25892Sdonn char	*index(), *rindex();
41*25892Sdonn char	*strcpy();
42*25892Sdonn char	*getenv();
43964Sbill 
44964Sbill main(ac, av)
4511296Ssam 	int ac;
4611296Ssam 	char *av[];
4711296Ssam {
48*25892Sdonn 	char *mp, *nextp;
49964Sbill 
50*25892Sdonn 	if ((mp = getenv("MANPATH")) != NULL)
51*25892Sdonn 		manpath = mp;
52*25892Sdonn 
5318592Ssam 	ac--, av++;
5418593Ssam 	while (ac > 0 && av[0][0] == '-') {
5518592Ssam 		switch (av[0][1]) {
5618592Ssam 
5718592Ssam 		case 'p':
58964Sbill 			pflag++;
5918592Ssam 			break;
6018592Ssam 
6118592Ssam 		case 'n':
62964Sbill 			nflag++;
6318592Ssam 			break;
6418592Ssam 
6518592Ssam 		case 'w':
66964Sbill 			wflag++;
6718592Ssam 			break;
6818592Ssam 
6918592Ssam 		case 'M':
7018592Ssam 		case 'P':
7118592Ssam 			if (ac < 1) {
72*25892Sdonn 				fprintf(stderr, "%s: missing path\n",
7318592Ssam 				    av[0]);
7418592Ssam 				exit(1);
7518592Ssam 			}
7618592Ssam 			ac--, av++;
77*25892Sdonn 			manpath = *av;
7818592Ssam 			break;
7918592Ssam 
8018592Ssam 		default:
81964Sbill 			goto usage;
8218592Ssam 		}
8318592Ssam 		ac--, av++;
84964Sbill 	}
8518593Ssam 	if (ac > 1) {
86964Sbill usage:
8718592Ssam 		printf("usage: catman [ -p ] [ -n ] [ -w ] [ -M path ] [ sections ]\n");
88964Sbill 		exit(-1);
89964Sbill 	}
90*25892Sdonn 	if (ac == 1)
91*25892Sdonn 		sections = *av;
92*25892Sdonn 	for (mp = manpath; mp && ((nextp = index(mp, ':')), 1); mp = nextp) {
93*25892Sdonn 		if (nextp)
94*25892Sdonn 			*nextp++ = '\0';
95*25892Sdonn 		doit(mp);
96*25892Sdonn 	}
97*25892Sdonn 	exit(exstat);
98*25892Sdonn }
99*25892Sdonn 
100*25892Sdonn doit(mandir)
101*25892Sdonn 	char *mandir;
102*25892Sdonn {
103*25892Sdonn 	register char *msp, *csp, *sp;
104*25892Sdonn 	int changed = 0;
105*25892Sdonn 	int status;
106*25892Sdonn 
107964Sbill 	if (wflag)
108964Sbill 		goto whatis;
10918592Ssam 	if (chdir(mandir) < 0) {
110*25892Sdonn 		sprintf(buf, "catman: %s", mandir);
111*25892Sdonn 		perror(buf);
112*25892Sdonn 		/* exstat = 1; */
113*25892Sdonn 		return;
11418592Ssam 	}
115*25892Sdonn 	if (pflag)
116*25892Sdonn 		printf("cd %s\n", mandir);
117964Sbill 	msp = &man[5];
118964Sbill 	csp = &cat[5];
119*25892Sdonn 	(void) umask(02);
120964Sbill 	for (sp = sections; *sp; sp++) {
12111296Ssam 		register DIR *mdir;
12211296Ssam 		register struct direct *dir;
12311296Ssam 		struct stat sbuf;
12411296Ssam 
125964Sbill 		man[3] = cat[3] = *sp;
126964Sbill 		*msp = *csp = '\0';
1276813Sedward 		if ((mdir = opendir(man)) == NULL) {
128*25892Sdonn 			sprintf(buf, "catman: opendir: %s", man);
129*25892Sdonn 			perror(buf);
130*25892Sdonn 			/* exstat = 1; */
131964Sbill 			continue;
132964Sbill 		}
133964Sbill 		if (stat(cat, &sbuf) < 0) {
134*25892Sdonn 			register char *cp;
13511422Ssam 
136*25892Sdonn 			(void) strcpy(buf, cat);
13711422Ssam 			cp = rindex(buf, '/');
13811422Ssam 			if (cp && cp[1] == '\0')
13911422Ssam 				*cp = '\0';
14011422Ssam 			if (pflag)
14111422Ssam 				printf("mkdir %s\n", buf);
14224232Smckusick 			else if (mkdir(buf, 0775) < 0) {
14311422Ssam 				sprintf(buf, "catman: mkdir: %s", cat);
14411422Ssam 				perror(buf);
145*25892Sdonn 				exstat = 1;
14611422Ssam 				continue;
14711422Ssam 			}
148*25892Sdonn 			(void) stat(cat, &sbuf);
149964Sbill 		}
150*25892Sdonn 		if (access(cat, R_OK|W_OK|X_OK) == -1) {
151*25892Sdonn 			sprintf(buf, "catman: %s", cat);
152*25892Sdonn 			perror(buf);
153*25892Sdonn 			exstat = 1;
154*25892Sdonn 			continue;
155*25892Sdonn 		}
156*25892Sdonn 		if ((sbuf.st_mode & S_IFMT) != S_IFDIR) {
157*25892Sdonn 			fprintf(stderr, "catman: %s: Not a directory\n", cat);
158*25892Sdonn 			exstat = 1;
159*25892Sdonn 			continue;
160*25892Sdonn 		}
1616813Sedward 		while ((dir = readdir(mdir)) != NULL) {
16211296Ssam 			time_t time;
163*25892Sdonn 			register char *tsp;
16411296Ssam 			FILE *inf;
16524205Smckusick 			int  makelink;
16611296Ssam 
1676813Sedward 			if (dir->d_ino == 0 || dir->d_name[0] == '.')
168964Sbill 				continue;
169964Sbill 			/*
17011296Ssam 			 * Make sure this is a man file, i.e., that it
171964Sbill 			 * ends in .[0-9] or .[0-9][a-z]
172964Sbill 			 */
1736813Sedward 			tsp = rindex(dir->d_name, '.');
174964Sbill 			if (tsp == NULL)
175964Sbill 				continue;
17616079Sralph 			if (!isdigit(*++tsp) && *tsp != *sp)
177964Sbill 				continue;
17811296Ssam 			if (*++tsp && !isalpha(*tsp))
17911296Ssam 				continue;
18011296Ssam 			if (*tsp && *++tsp)
18111296Ssam 				continue;
182*25892Sdonn 			(void) strcpy(msp, dir->d_name);
183964Sbill 			if ((inf = fopen(man, "r")) == NULL) {
184*25892Sdonn 				sprintf(buf, "catman: %s");
185*25892Sdonn 				perror(buf);
186964Sbill 				exstat = 1;
187964Sbill 				continue;
188964Sbill 			}
18924205Smckusick 			makelink = 0;
190964Sbill 			if (getc(inf) == '.' && getc(inf) == 's'
191964Sbill 			    && getc(inf) == 'o') {
19224205Smckusick 				if (getc(inf) != ' ' ||
19324205Smckusick 				    fgets(lncat, sizeof(lncat), inf)==NULL) {
19424205Smckusick 					fclose(inf);
19524205Smckusick 					continue;
19624205Smckusick 				}
19724205Smckusick 				if (lncat[strlen(lncat)-1] == '\n')
19824205Smckusick 					lncat[strlen(lncat)-1] = '\0';
19924205Smckusick 				if (strncmp(lncat, "man", 3) != 0) {
20024205Smckusick 					fclose(inf);
20124205Smckusick 					continue;
20224205Smckusick 				}
20324205Smckusick 				lncat[0] = 'c';
20424205Smckusick 				lncat[1] = 'a';
20524205Smckusick 				lncat[2] = 't';
20624205Smckusick 				makelink = 1;
207964Sbill 			}
208964Sbill 			fclose(inf);
209*25892Sdonn 			(void) strcpy(csp, dir->d_name);
210964Sbill 			if (stat(cat, &sbuf) >= 0) {
211964Sbill 				time = sbuf.st_mtime;
212*25892Sdonn 				(void) stat(man, &sbuf);
213964Sbill 				if (time >= sbuf.st_mtime)
214964Sbill 					continue;
215*25892Sdonn 				(void) unlink(cat);
216964Sbill 			}
21724205Smckusick 			if (makelink) {
21824205Smckusick 				/*
21924205Smckusick 				 * Don't unlink a directory by accident.
22024205Smckusick 				 */
22124205Smckusick 				if (stat(lncat, &sbuf) >= 0 &&
22225214Smckusick 				    ((sbuf.st_mode&S_IFMT)==S_IFREG))
223*25892Sdonn 					(void) unlink(cat);
22424205Smckusick 				if (pflag)
22524205Smckusick 					printf("ln %s %s\n", lncat, cat);
22624205Smckusick 				else
227*25892Sdonn 					if (link(lncat, cat) == -1) {
228*25892Sdonn 						sprintf(buf, "catman: link: %s", cat);
229*25892Sdonn 						perror(buf);
230*25892Sdonn 						exstat = 1;
231*25892Sdonn 						continue;
232*25892Sdonn 					}
23324205Smckusick 			}
23424205Smckusick 			else {
23524205Smckusick 				sprintf(buf, "nroff -man %s > %s", man, cat);
236*25892Sdonn 				if (pflag)
237*25892Sdonn 					printf("%s\n", buf);
238*25892Sdonn 				else if ((status = system(buf)) != 0) {
239*25892Sdonn 					fprintf(stderr, "catman: nroff: %s: exit status %d: Owooooo!\n", cat, status);
240*25892Sdonn 					exstat = 1;
241*25892Sdonn 					continue;
242*25892Sdonn 				}
24324205Smckusick 			}
244964Sbill 			changed = 1;
245964Sbill 		}
2466813Sedward 		closedir(mdir);
247964Sbill 	}
248964Sbill 	if (changed && !nflag) {
249964Sbill whatis:
250*25892Sdonn 		sprintf(buf, "%s %s", makewhatis, mandir);
251*25892Sdonn 		if (pflag)
252*25892Sdonn 			printf("%s\n", buf);
253*25892Sdonn 		else if ((status = system(buf)) != 0) {
254*25892Sdonn 			fprintf(stderr, "catman: %s: exit status %d\n",
255*25892Sdonn 			    buf, status);
256964Sbill 			exstat = 1;
257*25892Sdonn 		}
258964Sbill 	}
259*25892Sdonn 	return;
260964Sbill }
261