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