catman.c revision 1.5 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.5 1994/04/26 20:39:22 chopps Exp $";
33 #endif /* not lint */
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/wait.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <dirent.h>
42 #include <unistd.h>
43 #include <limits.h>
44 #include <errno.h>
45 #include <err.h>
46
47
48 int f_nowhatis;
49 int f_noaction;
50 int f_noformat;
51 int f_ignerr;
52 int f_noprint;
53
54 int dowhatis;
55
56 char manpath[] = "/usr/share/man";
57 char sections[] = "12345678lnop";
58 char *mp = manpath;
59 char *sp = 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, "knpwM:")) != 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 == 0)
107 usage ();
108 sp = *argv;
109
110 if (f_noformat == 0 || f_nowhatis == 0)
111 catman(mp, sp);
112 if (f_nowhatis == 0 && dowhatis)
113 makewhatis(mp);
114
115 exit(0);
116 }
117
118
119 void
120 catman(path, section)
121 const char *path;
122 char *section;
123 {
124 char mandir[PATH_MAX];
125 char catdir[PATH_MAX];
126 char manpage[PATH_MAX];
127 char catpage[PATH_MAX];
128 char sysbuf[1024];
129 struct stat manstat;
130 struct stat catstat;
131 struct dirent *dp;
132 DIR *dirp;
133 char *s, *tmp;
134 int sectlen, error;
135
136 for (s = section; *s; s += sectlen) {
137 tmp = s;
138 sectlen = 0;
139 if (isdigit(*tmp)) {
140 sectlen++;
141 tmp++;
142 while (*tmp && isdigit(*tmp) == 0) {
143 sectlen++;
144 tmp++;
145 }
146 }
147 if (sectlen == 0)
148 errx(1, "malformed section string");
149
150 sprintf(mandir, "%s/man%.*s", path, sectlen, s);
151 sprintf(catdir, "%s/cat%.*s", path, sectlen, s);
152
153 if ((dirp = opendir(mandir)) == 0) {
154 warn("can't open %s", mandir);
155 continue;
156 }
157
158 if (stat(catdir, &catstat) < 0) {
159 if (errno != ENOENT) {
160 warn("can't stat %s", catdir);
161 closedir(dirp);
162 continue;
163 }
164 if (f_noprint == 0)
165 printf("mkdir %s\n", catdir);
166 if (f_noaction == 0 && mkdir(catdir, 0755) < 0) {
167 warn("can't create %s", catdir);
168 closedir(dirp);
169 return;
170 }
171
172 }
173
174 while ((dp = readdir(dirp)) != NULL) {
175 if (strcmp(dp->d_name, ".") == 0 ||
176 strcmp(dp->d_name, "..") == 0)
177 continue;
178
179 sprintf(manpage, "%s/%s", mandir, dp->d_name);
180 sprintf(catpage, "%s/%s", catdir, dp->d_name);
181 if ((tmp = strrchr(catpage, '.')) != NULL)
182 strcpy(tmp, ".0");
183 else
184 continue;
185
186 if (stat(manpage, &manstat) < 0) {
187 warn("can't stat %s", manpage);
188 continue;
189 }
190
191 if (!S_ISREG(manstat.st_mode)) {
192 warnx("not a regular file %s", manpage);
193 continue;
194 }
195 if ((error = stat(catpage, &catstat)) &&
196 errno != ENOENT) {
197 warn("can't stat %s", catpage);
198 continue;
199 }
200
201 if ((error && errno == ENOENT) ||
202 manstat.st_mtime >= catstat.st_mtime) {
203 if (f_noformat)
204 dowhatis = 1;
205 else {
206 /*
207 * manpage is out of date,
208 * reformat
209 */
210 sprintf(sysbuf, "nroff -mandoc %s > %s",
211 manpage, catpage);
212 if (f_noprint == 0)
213 printf("%s\n", sysbuf);
214 if (f_noaction == 0)
215 dosystem(sysbuf);
216 dowhatis = 1;
217 }
218 }
219 }
220 closedir(dirp);
221 }
222 }
223
224 void
225 makewhatis(path)
226 const char *path;
227 {
228 char sysbuf[1024];
229
230 sprintf(sysbuf, "/usr/libexec/makewhatis %s", path);
231 if (f_noprint == 0)
232 printf("%s\n", sysbuf);
233 if (f_noaction == 0)
234 dosystem(sysbuf);
235 }
236
237 void
238 dosystem(cmd)
239 const char *cmd;
240 {
241 int status;
242
243 if ((status = system(cmd)) == 0)
244 return;
245
246 if (status == -1)
247 err(1, "cannot execute action");
248 if (WIFSIGNALED(status))
249 errx(1, "child was signaled to quit. aborting");
250 if (WIFSTOPPED(status))
251 errx(1, "child was stopped. aborting");
252 if (f_ignerr == 0)
253 errx(1,"*** Exited %d");
254 warnx("*** Exited %d (continuing)");
255 }
256
257 void
258 usage()
259 {
260 (void)fprintf(stderr, "usage: catman [-knpw] [-M manpath]"
261 " [sections]\n");
262 exit(1);
263 }
264