catman.c revision 1.6 1 /*
2 * Copyright (c) 1993 Winning Strategies, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Winning Strategies, Inc.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef lint
32 static char rcsid[] = "$Id: catman.c,v 1.6 1994/04/27 22:37:12 cgd Exp $";
33 #endif /* not lint */
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/wait.h>
38 #include <dirent.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <limits.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46 #include <paths.h>
47
48 #include "pathnames.h"
49
50 int f_nowhatis;
51 int f_noaction;
52 int f_noformat;
53 int f_ignerr;
54 int f_noprint;
55
56 int dowhatis;
57
58 char *mp = _PATH_MAN;
59 char *sp = _MAN_SECTIONS;
60
61 void usage __P((void));
62 void catman __P((const char *, char *));
63 void makewhatis __P((const char *));
64 void dosystem __P((const char *));
65
66 int
67 main(argc, argv)
68 int argc;
69 char **argv;
70 {
71 int c;
72
73 while ((c = getopt(argc, argv, "knpswM:")) != EOF) {
74 switch (c) {
75 case 'k':
76 f_ignerr = 1;
77 break;
78 case 'n':
79 f_nowhatis = 1;
80 break;
81 case 'p':
82 f_noaction = 1;
83 break;
84 case 's':
85 f_noprint = 1;
86 break;
87 case 'w':
88 f_noformat = 1;
89 break;
90 case 'M':
91 mp = optarg;
92 break;
93
94 case '?':
95 default:
96 usage();
97 }
98 }
99
100 argc -= optind;
101 argv += optind;
102
103 if (f_noprint && f_noaction)
104 f_noprint = 0;
105
106 if (argc > 1)
107 usage();
108 if (argc == 1)
109 sp = *argv;
110
111 if (f_noformat == 0 || f_nowhatis == 0)
112 catman(mp, sp);
113 if (f_nowhatis == 0 && dowhatis)
114 makewhatis(mp);
115
116 exit(0);
117 }
118
119
120 void
121 catman(path, section)
122 const char *path;
123 char *section;
124 {
125 char mandir[PATH_MAX];
126 char catdir[PATH_MAX];
127 char manpage[PATH_MAX];
128 char catpage[PATH_MAX];
129 char sysbuf[1024];
130 struct stat manstat;
131 struct stat catstat;
132 struct dirent *dp;
133 DIR *dirp;
134 char *s, *tmp;
135 int sectlen, error;
136
137 for (s = section; *s; s += sectlen) {
138 #ifdef notdef
139 tmp = s;
140 sectlen = 0;
141 if (isdigit(*tmp)) {
142 sectlen++;
143 tmp++;
144 while (*tmp && isdigit(*tmp) == 0) {
145 sectlen++;
146 tmp++;
147 }
148 }
149 #else
150 sectlen = 1;
151 #endif
152 if (sectlen == 0)
153 errx(1, "malformed section string");
154
155 sprintf(mandir, "%s/%s%.*s", path, _PATH_MANPAGES, sectlen, s);
156 sprintf(catdir, "%s/%s%.*s", path, _PATH_CATPAGES, sectlen, s);
157
158 if ((dirp = opendir(mandir)) == 0) {
159 warn("can't open %s", mandir);
160 continue;
161 }
162
163 if (stat(catdir, &catstat) < 0) {
164 if (errno != ENOENT) {
165 warn("can't stat %s", catdir);
166 closedir(dirp);
167 continue;
168 }
169 if (f_noprint == 0)
170 printf("mkdir %s\n", catdir);
171 if (f_noaction == 0 && mkdir(catdir, 0755) < 0) {
172 warn("can't create %s", catdir);
173 closedir(dirp);
174 return;
175 }
176
177 }
178
179 while ((dp = readdir(dirp)) != NULL) {
180 if (strcmp(dp->d_name, ".") == 0 ||
181 strcmp(dp->d_name, "..") == 0)
182 continue;
183
184 sprintf(manpage, "%s/%s", mandir, dp->d_name);
185 sprintf(catpage, "%s/%s", catdir, dp->d_name);
186 if ((tmp = strrchr(catpage, '.')) != NULL)
187 strcpy(tmp, ".0");
188 else
189 continue;
190
191 if (stat(manpage, &manstat) < 0) {
192 warn("can't stat %s", manpage);
193 continue;
194 }
195
196 if (!S_ISREG(manstat.st_mode)) {
197 warnx("not a regular file %s", manpage);
198 continue;
199 }
200 if ((error = stat(catpage, &catstat)) &&
201 errno != ENOENT) {
202 warn("can't stat %s", catpage);
203 continue;
204 }
205
206 if ((error && errno == ENOENT) ||
207 manstat.st_mtime >= catstat.st_mtime) {
208 if (f_noformat)
209 dowhatis = 1;
210 else {
211 /*
212 * manpage is out of date,
213 * reformat
214 */
215 sprintf(sysbuf, "nroff -mandoc %s > %s",
216 manpage, catpage);
217 if (f_noprint == 0)
218 printf("%s\n", sysbuf);
219 if (f_noaction == 0)
220 dosystem(sysbuf);
221 dowhatis = 1;
222 }
223 }
224 }
225 closedir(dirp);
226 }
227 }
228
229 void
230 makewhatis(path)
231 const char *path;
232 {
233 char sysbuf[1024];
234
235 sprintf(sysbuf, "%s %s", _PATH_MAKEWHATIS, path);
236 if (f_noprint == 0)
237 printf("%s\n", sysbuf);
238 if (f_noaction == 0)
239 dosystem(sysbuf);
240 }
241
242 void
243 dosystem(cmd)
244 const char *cmd;
245 {
246 int status;
247
248 if ((status = system(cmd)) == 0)
249 return;
250
251 if (status == -1)
252 err(1, "cannot execute action");
253 if (WIFSIGNALED(status))
254 errx(1, "child was signaled to quit. aborting");
255 if (WIFSTOPPED(status))
256 errx(1, "child was stopped. aborting");
257 if (f_ignerr == 0)
258 errx(1,"*** Exited %d");
259 warnx("*** Exited %d (continuing)");
260 }
261
262 void
263 usage()
264 {
265 (void)fprintf(stderr,
266 "usage: catman [-knpsw] [-M manpath] [sections]\n");
267 exit(1);
268 }
269