xref: /csrg-svn/old/catman/catman.c (revision 25214)
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*25214Smckusick static char sccsid[] = "@(#)catman.c	5.4 (Berkeley) 10/15/85";
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>
2413549Ssam #include <sys/time.h>
2513549Ssam #include <sys/dir.h>
2611296Ssam #include <ctype.h>
27964Sbill 
2811296Ssam #define	SYSTEM(str)	(pflag ? printf("%s\n", str) : system(str))
29964Sbill 
3011296Ssam char	buf[BUFSIZ];
3111296Ssam char	pflag;
3211296Ssam char	nflag;
3311296Ssam char	wflag;
3411296Ssam char	man[MAXNAMLEN+6] = "manx/";
3511296Ssam char	cat[MAXNAMLEN+6] = "catx/";
3624205Smckusick char	lncat[MAXNAMLEN+6] = "catx/";
3718592Ssam char	*mandir = "/usr/man";
3811296Ssam char	*rindex();
39964Sbill 
40964Sbill main(ac, av)
4111296Ssam 	int ac;
4211296Ssam 	char *av[];
4311296Ssam {
4411296Ssam 	register char *msp, *csp, *sp;
4511296Ssam 	register char *sections;
4611296Ssam 	register int exstat = 0;
4711296Ssam 	register char changed = 0;
48964Sbill 
4918592Ssam 	ac--, av++;
5018593Ssam 	while (ac > 0 && av[0][0] == '-') {
5118592Ssam 		switch (av[0][1]) {
5218592Ssam 
5318592Ssam 		case 'p':
54964Sbill 			pflag++;
5518592Ssam 			break;
5618592Ssam 
5718592Ssam 		case 'n':
58964Sbill 			nflag++;
5918592Ssam 			break;
6018592Ssam 
6118592Ssam 		case 'w':
62964Sbill 			wflag++;
6318592Ssam 			break;
6418592Ssam 
6518592Ssam 		case 'M':
6618592Ssam 		case 'P':
6718592Ssam 			if (ac < 1) {
6818592Ssam 				fprintf(stderr, "%s: missing directory\n",
6918592Ssam 				    av[0]);
7018592Ssam 				exit(1);
7118592Ssam 			}
7218592Ssam 			ac--, av++;
7318592Ssam 			mandir = *av;
7418592Ssam 			break;
7518592Ssam 
7618592Ssam 		default:
77964Sbill 			goto usage;
7818592Ssam 		}
7918592Ssam 		ac--, av++;
80964Sbill 	}
8118593Ssam 	if (ac > 1) {
82964Sbill usage:
8318592Ssam 		printf("usage: catman [ -p ] [ -n ] [ -w ] [ -M path ] [ sections ]\n");
84964Sbill 		exit(-1);
85964Sbill 	}
8618593Ssam 	sections = (ac == 1) ? *av : "12345678ln";
87964Sbill 	if (wflag)
88964Sbill 		goto whatis;
8918592Ssam 	if (chdir(mandir) < 0) {
9018592Ssam 		fprintf(stderr, "catman: "), perror(mandir);
9118592Ssam 		exit(1);
9218592Ssam 	}
93964Sbill 	msp = &man[5];
94964Sbill 	csp = &cat[5];
9524232Smckusick 	umask(02);
96964Sbill 	for (sp = sections; *sp; sp++) {
9711296Ssam 		register DIR *mdir;
9811296Ssam 		register struct direct *dir;
9911296Ssam 		struct stat sbuf;
10011296Ssam 
101964Sbill 		man[3] = cat[3] = *sp;
102964Sbill 		*msp = *csp = '\0';
1036813Sedward 		if ((mdir = opendir(man)) == NULL) {
1046813Sedward 			fprintf(stderr, "opendir:");
105964Sbill 			perror(man);
106964Sbill 			exstat = 1;
107964Sbill 			continue;
108964Sbill 		}
109964Sbill 		if (stat(cat, &sbuf) < 0) {
11011422Ssam 			char buf[MAXNAMLEN + 6], *cp, *rindex();
11111422Ssam 
11211422Ssam 			strcpy(buf, cat);
11311422Ssam 			cp = rindex(buf, '/');
11411422Ssam 			if (cp && cp[1] == '\0')
11511422Ssam 				*cp = '\0';
11611422Ssam 			if (pflag)
11711422Ssam 				printf("mkdir %s\n", buf);
11824232Smckusick 			else if (mkdir(buf, 0775) < 0) {
11911422Ssam 				sprintf(buf, "catman: mkdir: %s", cat);
12011422Ssam 				perror(buf);
12111422Ssam 				continue;
12211422Ssam 			}
123964Sbill 			stat(cat, &sbuf);
124964Sbill 		}
12524232Smckusick 		if ((sbuf.st_mode & 0777) != 0775)
12624232Smckusick 			chmod(cat, 0775);
1276813Sedward 		while ((dir = readdir(mdir)) != NULL) {
12811296Ssam 			time_t time;
12911296Ssam 			char *tsp;
13011296Ssam 			FILE *inf;
13124205Smckusick 			int  makelink;
13211296Ssam 
1336813Sedward 			if (dir->d_ino == 0 || dir->d_name[0] == '.')
134964Sbill 				continue;
135964Sbill 			/*
13611296Ssam 			 * Make sure this is a man file, i.e., that it
137964Sbill 			 * ends in .[0-9] or .[0-9][a-z]
138964Sbill 			 */
1396813Sedward 			tsp = rindex(dir->d_name, '.');
140964Sbill 			if (tsp == NULL)
141964Sbill 				continue;
14216079Sralph 			if (!isdigit(*++tsp) && *tsp != *sp)
143964Sbill 				continue;
14411296Ssam 			if (*++tsp && !isalpha(*tsp))
14511296Ssam 				continue;
14611296Ssam 			if (*tsp && *++tsp)
14711296Ssam 				continue;
1486813Sedward 			strcpy(msp, dir->d_name);
149964Sbill 			if ((inf = fopen(man, "r")) == NULL) {
150964Sbill 				perror(man);
151964Sbill 				exstat = 1;
152964Sbill 				continue;
153964Sbill 			}
15424205Smckusick 			makelink = 0;
155964Sbill 			if (getc(inf) == '.' && getc(inf) == 's'
156964Sbill 			    && getc(inf) == 'o') {
15724205Smckusick 				if (getc(inf) != ' ' ||
15824205Smckusick 				    fgets(lncat, sizeof(lncat), inf)==NULL) {
15924205Smckusick 					fclose(inf);
16024205Smckusick 					continue;
16124205Smckusick 				}
16224205Smckusick 				if (lncat[strlen(lncat)-1] == '\n')
16324205Smckusick 					lncat[strlen(lncat)-1] = '\0';
16424205Smckusick 				if (strncmp(lncat, "man", 3) != 0) {
16524205Smckusick 					fclose(inf);
16624205Smckusick 					continue;
16724205Smckusick 				}
16824205Smckusick 				lncat[0] = 'c';
16924205Smckusick 				lncat[1] = 'a';
17024205Smckusick 				lncat[2] = 't';
17124205Smckusick 				makelink = 1;
172964Sbill 			}
173964Sbill 			fclose(inf);
1746813Sedward 			strcpy(csp, dir->d_name);
175964Sbill 			if (stat(cat, &sbuf) >= 0) {
176964Sbill 				time = sbuf.st_mtime;
177964Sbill 				stat(man, &sbuf);
178964Sbill 				if (time >= sbuf.st_mtime)
179964Sbill 					continue;
180964Sbill 				unlink(cat);
181964Sbill 			}
18224205Smckusick 			if (makelink) {
18324205Smckusick 				/*
18424205Smckusick 				 * Don't unlink a directory by accident.
18524205Smckusick 				 */
18624205Smckusick 				if (stat(lncat, &sbuf) >= 0 &&
187*25214Smckusick 				    ((sbuf.st_mode&S_IFMT)==S_IFREG))
18824205Smckusick 					unlink(cat);
18924205Smckusick 				if (pflag)
19024205Smckusick 					printf("ln %s %s\n", lncat, cat);
19124205Smckusick 				else
19224205Smckusick 					link(lncat, cat);
19324205Smckusick 			}
19424205Smckusick 			else {
19524205Smckusick 				sprintf(buf, "nroff -man %s > %s", man, cat);
19624205Smckusick 				SYSTEM(buf);
19724205Smckusick 			}
198964Sbill 			changed = 1;
199964Sbill 		}
2006813Sedward 		closedir(mdir);
201964Sbill 	}
202964Sbill 	if (changed && !nflag) {
203964Sbill whatis:
20418592Ssam 		if (!pflag) {
20518592Ssam 			execl("/bin/sh", "/bin/sh",
20618592Ssam 			    "/usr/lib/makewhatis", mandir, 0);
207964Sbill 			perror("/bin/sh /usr/lib/makewhatis");
208964Sbill 			exstat = 1;
20918592Ssam 		} else
21018592Ssam 			printf("/bin/sh /usr/lib/makewhatis %s\n", mandir);
211964Sbill 	}
212964Sbill 	exit(exstat);
213964Sbill }
214