xref: /csrg-svn/old/catman/catman.c (revision 30784)
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*30784Sbostic static char sccsid[] = "@(#)catman.c	5.8 (Berkeley) 04/06/87";
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>
2425892Sdonn #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/";
3425892Sdonn int	exstat = 0;
3511296Ssam char	cat[MAXNAMLEN+6] = "catx/";
3628839Smckusick char	lncat[MAXNAMLEN+9] = "../catx/";
3725892Sdonn char	*manpath = "/usr/man";
3825892Sdonn char	*sections = "12345678ln";
3925892Sdonn char	*makewhatis = "/usr/lib/makewhatis";
4025892Sdonn char	*index(), *rindex();
4125892Sdonn char	*strcpy();
4225892Sdonn char	*getenv();
43964Sbill 
main(ac,av)44964Sbill main(ac, av)
4511296Ssam 	int ac;
4611296Ssam 	char *av[];
4711296Ssam {
4825892Sdonn 	char *mp, *nextp;
49964Sbill 
5025892Sdonn 	if ((mp = getenv("MANPATH")) != NULL)
5125892Sdonn 		manpath = mp;
5225892Sdonn 
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) {
7225892Sdonn 				fprintf(stderr, "%s: missing path\n",
7318592Ssam 				    av[0]);
7418592Ssam 				exit(1);
7518592Ssam 			}
7618592Ssam 			ac--, av++;
7725892Sdonn 			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 	}
9025892Sdonn 	if (ac == 1)
9125892Sdonn 		sections = *av;
9225892Sdonn 	for (mp = manpath; mp && ((nextp = index(mp, ':')), 1); mp = nextp) {
9325892Sdonn 		if (nextp)
9425892Sdonn 			*nextp++ = '\0';
9525892Sdonn 		doit(mp);
9625892Sdonn 	}
9725892Sdonn 	exit(exstat);
9825892Sdonn }
9925892Sdonn 
doit(mandir)10025892Sdonn doit(mandir)
10125892Sdonn 	char *mandir;
10225892Sdonn {
10325892Sdonn 	register char *msp, *csp, *sp;
10425892Sdonn 	int changed = 0;
10525892Sdonn 	int status;
10625892Sdonn 
107964Sbill 	if (wflag)
108964Sbill 		goto whatis;
10918592Ssam 	if (chdir(mandir) < 0) {
11025892Sdonn 		sprintf(buf, "catman: %s", mandir);
11125892Sdonn 		perror(buf);
11225892Sdonn 		/* exstat = 1; */
11325892Sdonn 		return;
11418592Ssam 	}
11525892Sdonn 	if (pflag)
11625892Sdonn 		printf("cd %s\n", mandir);
117964Sbill 	msp = &man[5];
118964Sbill 	csp = &cat[5];
11926402Slepreau 	(void) umask(0);
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) {
12825892Sdonn 			sprintf(buf, "catman: opendir: %s", man);
12925892Sdonn 			perror(buf);
13025892Sdonn 			/* exstat = 1; */
131964Sbill 			continue;
132964Sbill 		}
133964Sbill 		if (stat(cat, &sbuf) < 0) {
13425892Sdonn 			register char *cp;
13511422Ssam 
13625892Sdonn 			(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);
14226402Slepreau 			else if (mkdir(buf, 0777) < 0) {
14311422Ssam 				sprintf(buf, "catman: mkdir: %s", cat);
14411422Ssam 				perror(buf);
14525892Sdonn 				exstat = 1;
14611422Ssam 				continue;
14711422Ssam 			}
14825892Sdonn 			(void) stat(cat, &sbuf);
149964Sbill 		}
15025892Sdonn 		if (access(cat, R_OK|W_OK|X_OK) == -1) {
15125892Sdonn 			sprintf(buf, "catman: %s", cat);
15225892Sdonn 			perror(buf);
15325892Sdonn 			exstat = 1;
15425892Sdonn 			continue;
15525892Sdonn 		}
15625892Sdonn 		if ((sbuf.st_mode & S_IFMT) != S_IFDIR) {
15725892Sdonn 			fprintf(stderr, "catman: %s: Not a directory\n", cat);
15825892Sdonn 			exstat = 1;
15925892Sdonn 			continue;
16025892Sdonn 		}
1616813Sedward 		while ((dir = readdir(mdir)) != NULL) {
16211296Ssam 			time_t time;
16325892Sdonn 			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;
18225892Sdonn 			(void) strcpy(msp, dir->d_name);
183964Sbill 			if ((inf = fopen(man, "r")) == NULL) {
184*30784Sbostic 				sprintf(buf, "catman: %s", man);
18525892Sdonn 				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) != ' ' ||
19328839Smckusick 				    fgets(lncat+3, sizeof(lncat)-3, inf)==NULL) {
19424205Smckusick 					fclose(inf);
19524205Smckusick 					continue;
19624205Smckusick 				}
19724205Smckusick 				if (lncat[strlen(lncat)-1] == '\n')
19824205Smckusick 					lncat[strlen(lncat)-1] = '\0';
19928839Smckusick 				if (strncmp(lncat+3, "man", 3) != 0) {
20024205Smckusick 					fclose(inf);
20124205Smckusick 					continue;
20224205Smckusick 				}
20328839Smckusick 				bcopy("../cat", lncat, sizeof("../cat")-1);
20424205Smckusick 				makelink = 1;
205964Sbill 			}
206964Sbill 			fclose(inf);
20725892Sdonn 			(void) strcpy(csp, dir->d_name);
208964Sbill 			if (stat(cat, &sbuf) >= 0) {
209964Sbill 				time = sbuf.st_mtime;
21025892Sdonn 				(void) stat(man, &sbuf);
211964Sbill 				if (time >= sbuf.st_mtime)
212964Sbill 					continue;
21325892Sdonn 				(void) unlink(cat);
214964Sbill 			}
21524205Smckusick 			if (makelink) {
21624205Smckusick 				/*
21724205Smckusick 				 * Don't unlink a directory by accident.
21824205Smckusick 				 */
21928839Smckusick 				if (stat(lncat+3, &sbuf) >= 0 &&
22028839Smckusick 				    (((sbuf.st_mode&S_IFMT)==S_IFREG) ||
22128839Smckusick 				     ((sbuf.st_mode&S_IFMT)==S_IFLNK)))
22225892Sdonn 					(void) unlink(cat);
22324205Smckusick 				if (pflag)
22428839Smckusick 					printf("ln -s %s %s\n", lncat, cat);
22524205Smckusick 				else
22628839Smckusick 					if (symlink(lncat, cat) == -1) {
22728839Smckusick 						sprintf(buf, "catman: symlink: %s", cat);
22825892Sdonn 						perror(buf);
22925892Sdonn 						exstat = 1;
23025892Sdonn 						continue;
23125892Sdonn 					}
23224205Smckusick 			}
23324205Smckusick 			else {
23424205Smckusick 				sprintf(buf, "nroff -man %s > %s", man, cat);
23525892Sdonn 				if (pflag)
23625892Sdonn 					printf("%s\n", buf);
23725892Sdonn 				else if ((status = system(buf)) != 0) {
23825892Sdonn 					fprintf(stderr, "catman: nroff: %s: exit status %d: Owooooo!\n", cat, status);
23925892Sdonn 					exstat = 1;
24025892Sdonn 					continue;
24125892Sdonn 				}
24224205Smckusick 			}
243964Sbill 			changed = 1;
244964Sbill 		}
2456813Sedward 		closedir(mdir);
246964Sbill 	}
247964Sbill 	if (changed && !nflag) {
248964Sbill whatis:
24925892Sdonn 		sprintf(buf, "%s %s", makewhatis, mandir);
25025892Sdonn 		if (pflag)
25125892Sdonn 			printf("%s\n", buf);
25225892Sdonn 		else if ((status = system(buf)) != 0) {
25325892Sdonn 			fprintf(stderr, "catman: %s: exit status %d\n",
25425892Sdonn 			    buf, status);
255964Sbill 			exstat = 1;
25625892Sdonn 		}
257964Sbill 	}
25825892Sdonn 	return;
259964Sbill }
260