6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012, Josef 'Jeff' Sipek <jeffpc@31bits.net>. All rights reserved.
25 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
26 */
27
28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T. */
29 /* All rights reserved. */
30
31 /*
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
35 *
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
39 */
40
41 /*
42 * Find and display reference manual pages. This version includes makewhatis
43 * functionality as well.
44 */
45
65 #include <unistd.h>
66
67 #include "man.h"
68
69
70 /* Mapping of old directories to new directories */
71 static const struct map_entry {
72 char *old_name;
73 char *new_name;
74 } map[] = {
75 { "3b", "3ucb" },
76 { "3e", "3elf" },
77 { "3g", "3gen" },
78 { "3k", "3kstat" },
79 { "3n", "3socket" },
80 { "3r", "3rt" },
81 { "3s", "3c" },
82 { "3t", "3thr" },
83 { "3x", "3curses" },
84 { "3xc", "3xcurses" },
85 { "3xn", "3xnet" }
86 };
87
88 struct suffix {
89 char *ds;
90 char *fs;
91 };
92
93 /*
94 * Flags that control behavior of build_manpath()
95 *
96 * BMP_ISPATH pathv is a vector constructed from PATH.
97 * Perform appropriate path translations for
98 * manpath.
99 * BMP_APPEND_DEFMANDIR Add DEFMANDIR to the end if it hasn't
100 * already appeared earlier.
101 * BMP_FALLBACK_DEFMANDIR Append /usr/share/man only if no other
102 * manpath (including derived from PATH)
103 * elements are valid.
104 */
105 #define BMP_ISPATH 1
141 { NULL, NULL, 0, 0 }
142 };
143
144 struct man_node {
145 char *path; /* mandir path */
146 char **secv; /* submandir suffices */
147 int defsrch; /* hint for man -p */
148 int frompath; /* hint for man -d */
149 struct man_node *next;
150 };
151
152 static int all = 0;
153 static int apropos = 0;
154 static int debug = 0;
155 static int found = 0;
156 static int list = 0;
157 static int makewhatis = 0;
158 static int printmp = 0;
159 static int sargs = 0;
160 static int psoutput = 0;
161 static int whatis = 0;
162 static int makewhatishere = 0;
163
164 static char *mansec;
165 static char *pager;
166
167 static char *addlocale(char *);
168 static struct man_node *build_manpath(char **, int);
169 static void do_makewhatis(struct man_node *);
170 static char *check_config(char *);
171 static int cmp(const void *, const void *);
172 static int dupcheck(struct man_node *, struct dupnode **);
173 static int format(char *, char *, char *, char *);
174 static void free_dupnode(struct dupnode *);
175 static void free_manp(struct man_node *manp);
176 static void freev(char **);
177 static void fullpaths(struct man_node **);
178 static void get_all_sect(struct man_node *);
179 static int getdirs(char *, char ***, int);
180 static void getpath(struct man_node *, char **);
181 static void getsect(struct man_node *, char **);
182 static void init_bintoman(void);
183 static void lower(char *);
184 static void mandir(char **, char *, char *, int);
185 static int manual(struct man_node *, char *);
221 (void) setlocale(LC_ALL, "");
222 (void) strcpy(language, setlocale(LC_MESSAGES, (char *)NULL));
223 if (strcmp("C", language) != 0)
224 (void) strlcpy(localedir, language, MAXPATHLEN);
225
226 #if !defined(TEXT_DOMAIN)
227 #define TEXT_DOMAIN "SYS_TEST"
228 #endif
229 (void) textdomain(TEXT_DOMAIN);
230
231 if (strcmp(__progname, "apropos") == 0) {
232 apropos++;
233 opts = "M:ds:";
234 } else if (strcmp(__progname, "whatis") == 0) {
235 apropos++;
236 whatis++;
237 opts = "M:ds:";
238 } else if (strcmp(__progname, "catman") == 0) {
239 catman++;
240 makewhatis++;
241 opts = "M:w";
242 } else if (strcmp(__progname, "makewhatis") == 0) {
243 makewhatis++;
244 makewhatishere++;
245 manpath = ".";
246 opts = "";
247 } else {
248 opts = "M:adfklps:tw";
249 }
250
251 opterr = 0;
252 while ((c = getopt(argc, argv, opts)) != -1) {
253 switch (c) {
254 case 'M': /* Respecify path for man pages */
255 manpath = optarg;
256 break;
257 case 'a':
258 all++;
259 break;
260 case 'd':
261 debug++;
262 break;
263 case 'f':
264 whatis++;
265 /*FALLTHROUGH*/
266 case 'k':
267 apropos++;
268 break;
269 case 'l':
270 list++;
271 /*FALLTHROUGH*/
272 case 'p':
273 printmp++;
274 break;
275 case 's':
276 mansec = optarg;
277 sargs++;
278 break;
279 case 't':
280 psoutput++;
281 break;
282 case 'w':
283 makewhatis++;
284 break;
285 case '?':
286 default:
287 if (apropos)
288 usage_whatapro();
289 else if (catman)
290 usage_catman();
291 else if (makewhatishere)
292 usage_makewhatis();
293 else
294 usage_man();
295 }
296 }
297 argc -= optind;
298 argv += optind;
299
300 if (argc == 0) {
301 if (apropos) {
334 /* Collect environment information */
335 if (isatty(STDOUT_FILENO) && (mwstr = getenv("MANWIDTH")) != NULL &&
336 *mwstr != '\0') {
337 if (strcasecmp(mwstr, "tty") == 0) {
338 struct winsize ws;
339
340 if (ioctl(0, TIOCGWINSZ, &ws) != 0)
341 warn("TIOCGWINSZ");
342 else
343 manwidth = ws.ws_col;
344 } else {
345 manwidth = (int)strtol(mwstr, (char **)NULL, 10);
346 if (manwidth < 0)
347 manwidth = 0;
348 }
349 }
350 if (manwidth != 0) {
351 DPRINTF("-- Using non-standard page width: %d\n", manwidth);
352 }
353
354 if ((pager = getenv("PAGER")) == NULL || *pager == '\0')
355 pager = PAGER;
356 DPRINTF("-- Using pager: %s\n", pager);
357
358 for (i = 0; i < argc; i++) {
359 char *cmd;
360 static struct man_node *mp;
361 char *pv[2];
362
363 /*
364 * If full path to command specified, customize
365 * the manpath accordingly.
366 */
367 if ((cmd = strrchr(argv[i], '/')) != NULL) {
368 *cmd = '\0';
369 if ((pv[0] = strdup(argv[i])) == NULL)
370 err(1, "strdup");
371 pv[1] = NULL;
372 *cmd = '/';
373 mp = build_manpath(pv,
374 BMP_ISPATH | BMP_FALLBACK_DEFMANDIR);
375 } else {
1129 (void) format(path, dir, name, sd->d_name);
1130 (void) closedir(sdp);
1131 free(pname);
1132 return (1);
1133 }
1134 free(pname);
1135 }
1136 (void) closedir(sdp);
1137
1138 return (0);
1139 }
1140
1141 /*
1142 * Check the hash table of old directory names to see if there is a
1143 * new directory name.
1144 */
1145 static char *
1146 map_section(char *section, char *path)
1147 {
1148 int i;
1149 int len;
1150 char fullpath[MAXPATHLEN];
1151
1152 if (list) /* -l option fall through */
1153 return (NULL);
1154
1155 for (i = 0; i <= ((sizeof (map)/sizeof (map[0]) - 1)); i++) {
1156 if (strlen(section) > strlen(map[i].new_name)) {
1157 len = strlen(section);
1158 } else {
1159 len = strlen(map[i].new_name);
1160 }
1161 if (strncmp(section, map[i].old_name, len) == 0) {
1162 (void) snprintf(fullpath, sizeof (fullpath),
1163 "%s/sman%s", path, map[i].new_name);
1164 if (!access(fullpath, R_OK | X_OK)) {
1165 return (map[i].new_name);
1166 } else {
1167 return (NULL);
1168 }
1169 }
1170 }
1171
1172 return (NULL);
1173 }
1174
1175 /*
1176 * Format the manpage.
1177 */
1178 static int
1179 format(char *path, char *dir, char *name, char *pg)
1180 {
1181 char manpname[MAXPATHLEN], catpname[MAXPATHLEN];
1182 char cmdbuf[BUFSIZ], tmpbuf[BUFSIZ];
1183 char *cattool;
1184 int utf8 = 0;
1185 struct stat sbman, sbcat;
1186
1187 found++;
1188
1189 if (list) {
1190 (void) printf(gettext("%s(%s)\t-M %s\n"), name, dir + 3, path);
1191 return (-1);
1192 }
1193
1194 (void) snprintf(manpname, sizeof (manpname), "%s/man%s/%s", path,
1195 dir + 3, pg);
1196 (void) snprintf(catpname, sizeof (catpname), "%s/cat%s/%s", path,
1197 dir + 3, pg);
1198
1199 /* Can't do PS output if manpage doesn't exist */
1200 if (stat(manpname, &sbman) != 0 && psoutput)
1201 return (-1);
1202
1203 /*
1204 * If both manpage and catpage do not exist, manpname is
1205 * broken symlink, most likely.
1206 */
1207 if (stat(catpname, &sbcat) != 0 && stat(manpname, &sbman) != 0)
1208 err(1, "%s", manpname);
1209
1210 /* Setup cattool */
1211 if (fnmatch("*.gz", manpname, 0) == 0)
1212 cattool = "gzcat";
1213 else if (fnmatch("*.bz2", manpname, 0) == 0)
1214 cattool = "bzcat";
1215 else
1216 cattool = "gzcat -f";
1217
1218 /* Preprocess UTF-8 input with preconv (could be smarter) */
1219 if (strstr(path, "UTF-8") != NULL)
1220 utf8 = 1;
1221
1222 if (psoutput) {
1223 (void) snprintf(cmdbuf, BUFSIZ,
1224 "cd %s; %s %s%s | mandoc -Tps | lp -Tpostscript",
1225 path, cattool, manpname,
1226 utf8 ? " | " PRECONV " -e UTF-8" : "");
1227 DPRINTF("-- Using manpage: %s\n", manpname);
1228 goto cmd;
1229 }
1230
1231 /*
1232 * Output catpage if:
1233 * - manpage doesn't exist
1234 * - output width is standard and catpage is recent enough
1235 */
1236 if (stat(manpname, &sbman) != 0 || (manwidth == 0 &&
1237 stat(catpname, &sbcat) == 0 && sbcat.st_mtime >= sbman.st_mtime)) {
1238 DPRINTF("-- Using catpage: %s\n", catpname);
1239 (void) snprintf(cmdbuf, BUFSIZ, "%s %s", pager, catpname);
1240 goto cmd;
1241 }
1242
1243 DPRINTF("-- Using manpage: %s\n", manpname);
1244 if (manwidth > 0)
1245 (void) snprintf(tmpbuf, BUFSIZ, "-Owidth=%d ", manwidth);
1246 (void) snprintf(cmdbuf, BUFSIZ, "cd %s; %s %s%s | mandoc -T%s %s| %s",
1247 path, cattool, manpname,
1248 utf8 ? " | " PRECONV " -e UTF-8 " : "",
1551
1552 for (secp = manp->secv; *secp != NULL; secp++) {
1553 /*
1554 * Section deduplication may have eliminated some
1555 * sections from the vector. Avoid displaying this
1556 * detail which would appear as ",," in output
1557 */
1558 if ((*secp)[0] != '\0')
1559 (void) printf(",%s", *secp);
1560 }
1561 }
1562 (void) printf("\n");
1563 }
1564
1565 static void
1566 usage_man(void)
1567 {
1568
1569 (void) fprintf(stderr, gettext(
1570 "usage: man [-alptw] [-M path] [-s section] name ...\n"
1571 " man [-M path] [-s section] -k keyword -- emulate apropos\n"
1572 " man [-M path] [-s section] -f keyword -- emulate whatis\n"));
1573
1574 exit(1);
1575 }
1576
1577 static void
1578 usage_whatapro(void)
1579 {
1580
1581 (void) fprintf(stderr, gettext(
1582 "usage: %s [-M path] [-s section] keyword ...\n"),
1583 whatis ? "whatis" : "apropos");
1584
1585 exit(1);
1586 }
1587
1588 static void
1589 usage_catman(void)
1590 {
1591 (void) fprintf(stderr, gettext(
1592 "usage: catman [-M path] [-w]\n"));
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012, Josef 'Jeff' Sipek <jeffpc@31bits.net>. All rights reserved.
25 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
27 */
28
29 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T. */
30 /* All rights reserved. */
31
32 /*
33 * University Copyright- Copyright (c) 1982, 1986, 1988
34 * The Regents of the University of California
35 * All Rights Reserved
36 *
37 * University Acknowledgment- Portions of this document are derived from
38 * software developed by the University of California, Berkeley, and its
39 * contributors.
40 */
41
42 /*
43 * Find and display reference manual pages. This version includes makewhatis
44 * functionality as well.
45 */
46
66 #include <unistd.h>
67
68 #include "man.h"
69
70
71 /* Mapping of old directories to new directories */
72 static const struct map_entry {
73 char *old_name;
74 char *new_name;
75 } map[] = {
76 { "3b", "3ucb" },
77 { "3e", "3elf" },
78 { "3g", "3gen" },
79 { "3k", "3kstat" },
80 { "3n", "3socket" },
81 { "3r", "3rt" },
82 { "3s", "3c" },
83 { "3t", "3thr" },
84 { "3x", "3curses" },
85 { "3xc", "3xcurses" },
86 { "3xn", "3xnet" },
87 { NULL, NULL }
88 };
89
90 struct suffix {
91 char *ds;
92 char *fs;
93 };
94
95 /*
96 * Flags that control behavior of build_manpath()
97 *
98 * BMP_ISPATH pathv is a vector constructed from PATH.
99 * Perform appropriate path translations for
100 * manpath.
101 * BMP_APPEND_DEFMANDIR Add DEFMANDIR to the end if it hasn't
102 * already appeared earlier.
103 * BMP_FALLBACK_DEFMANDIR Append /usr/share/man only if no other
104 * manpath (including derived from PATH)
105 * elements are valid.
106 */
107 #define BMP_ISPATH 1
143 { NULL, NULL, 0, 0 }
144 };
145
146 struct man_node {
147 char *path; /* mandir path */
148 char **secv; /* submandir suffices */
149 int defsrch; /* hint for man -p */
150 int frompath; /* hint for man -d */
151 struct man_node *next;
152 };
153
154 static int all = 0;
155 static int apropos = 0;
156 static int debug = 0;
157 static int found = 0;
158 static int list = 0;
159 static int makewhatis = 0;
160 static int printmp = 0;
161 static int sargs = 0;
162 static int psoutput = 0;
163 static int lintout = 0;
164 static int whatis = 0;
165 static int makewhatishere = 0;
166
167 static char *mansec;
168 static char *pager = NULL;
169
170 static char *addlocale(char *);
171 static struct man_node *build_manpath(char **, int);
172 static void do_makewhatis(struct man_node *);
173 static char *check_config(char *);
174 static int cmp(const void *, const void *);
175 static int dupcheck(struct man_node *, struct dupnode **);
176 static int format(char *, char *, char *, char *);
177 static void free_dupnode(struct dupnode *);
178 static void free_manp(struct man_node *manp);
179 static void freev(char **);
180 static void fullpaths(struct man_node **);
181 static void get_all_sect(struct man_node *);
182 static int getdirs(char *, char ***, int);
183 static void getpath(struct man_node *, char **);
184 static void getsect(struct man_node *, char **);
185 static void init_bintoman(void);
186 static void lower(char *);
187 static void mandir(char **, char *, char *, int);
188 static int manual(struct man_node *, char *);
224 (void) setlocale(LC_ALL, "");
225 (void) strcpy(language, setlocale(LC_MESSAGES, (char *)NULL));
226 if (strcmp("C", language) != 0)
227 (void) strlcpy(localedir, language, MAXPATHLEN);
228
229 #if !defined(TEXT_DOMAIN)
230 #define TEXT_DOMAIN "SYS_TEST"
231 #endif
232 (void) textdomain(TEXT_DOMAIN);
233
234 if (strcmp(__progname, "apropos") == 0) {
235 apropos++;
236 opts = "M:ds:";
237 } else if (strcmp(__progname, "whatis") == 0) {
238 apropos++;
239 whatis++;
240 opts = "M:ds:";
241 } else if (strcmp(__progname, "catman") == 0) {
242 catman++;
243 makewhatis++;
244 opts = "P:M:w";
245 } else if (strcmp(__progname, "makewhatis") == 0) {
246 makewhatis++;
247 makewhatishere++;
248 manpath = ".";
249 opts = "";
250 } else {
251 opts = "FM:P:T:adfklprs:tw";
252 if (argc > 1 && strcmp(argv[1], "-") == 0) {
253 pager = "cat";
254 optind++;
255 }
256 }
257
258 opterr = 0;
259 while ((c = getopt(argc, argv, opts)) != -1) {
260 switch (c) {
261 case 'M': /* Respecify path for man pages */
262 manpath = optarg;
263 break;
264 case 'a':
265 all++;
266 break;
267 case 'd':
268 debug++;
269 break;
270 case 'f':
271 whatis++;
272 /*FALLTHROUGH*/
273 case 'k':
274 apropos++;
275 break;
276 case 'l':
277 list++;
278 all++;
279 break;
280 case 'p':
281 printmp++;
282 break;
283 case 's':
284 mansec = optarg;
285 sargs++;
286 break;
287 case 'r':
288 lintout++;
289 break;
290 case 't':
291 psoutput++;
292 break;
293 case 'T':
294 case 'P':
295 case 'F':
296 /* legacy options, compatibility only and ignored */
297 break;
298 case 'w':
299 makewhatis++;
300 break;
301 case '?':
302 default:
303 if (apropos)
304 usage_whatapro();
305 else if (catman)
306 usage_catman();
307 else if (makewhatishere)
308 usage_makewhatis();
309 else
310 usage_man();
311 }
312 }
313 argc -= optind;
314 argv += optind;
315
316 if (argc == 0) {
317 if (apropos) {
350 /* Collect environment information */
351 if (isatty(STDOUT_FILENO) && (mwstr = getenv("MANWIDTH")) != NULL &&
352 *mwstr != '\0') {
353 if (strcasecmp(mwstr, "tty") == 0) {
354 struct winsize ws;
355
356 if (ioctl(0, TIOCGWINSZ, &ws) != 0)
357 warn("TIOCGWINSZ");
358 else
359 manwidth = ws.ws_col;
360 } else {
361 manwidth = (int)strtol(mwstr, (char **)NULL, 10);
362 if (manwidth < 0)
363 manwidth = 0;
364 }
365 }
366 if (manwidth != 0) {
367 DPRINTF("-- Using non-standard page width: %d\n", manwidth);
368 }
369
370 if (pager == NULL) {
371 if ((pager = getenv("PAGER")) == NULL || *pager == '\0')
372 pager = PAGER;
373 }
374 DPRINTF("-- Using pager: %s\n", pager);
375
376 for (i = 0; i < argc; i++) {
377 char *cmd;
378 static struct man_node *mp;
379 char *pv[2];
380
381 /*
382 * If full path to command specified, customize
383 * the manpath accordingly.
384 */
385 if ((cmd = strrchr(argv[i], '/')) != NULL) {
386 *cmd = '\0';
387 if ((pv[0] = strdup(argv[i])) == NULL)
388 err(1, "strdup");
389 pv[1] = NULL;
390 *cmd = '/';
391 mp = build_manpath(pv,
392 BMP_ISPATH | BMP_FALLBACK_DEFMANDIR);
393 } else {
1147 (void) format(path, dir, name, sd->d_name);
1148 (void) closedir(sdp);
1149 free(pname);
1150 return (1);
1151 }
1152 free(pname);
1153 }
1154 (void) closedir(sdp);
1155
1156 return (0);
1157 }
1158
1159 /*
1160 * Check the hash table of old directory names to see if there is a
1161 * new directory name.
1162 */
1163 static char *
1164 map_section(char *section, char *path)
1165 {
1166 int i;
1167 char fullpath[MAXPATHLEN];
1168
1169 if (list) /* -l option fall through */
1170 return (NULL);
1171
1172 for (i = 0; map[i].new_name != NULL; i++) {
1173 if (strcmp(section, map[i].old_name) == 0) {
1174 (void) snprintf(fullpath, sizeof (fullpath),
1175 "%s/man%s", path, map[i].new_name);
1176 if (!access(fullpath, R_OK | X_OK)) {
1177 return (map[i].new_name);
1178 } else {
1179 return (NULL);
1180 }
1181 }
1182 }
1183
1184 return (NULL);
1185 }
1186
1187 /*
1188 * Format the manpage.
1189 */
1190 static int
1191 format(char *path, char *dir, char *name, char *pg)
1192 {
1193 char manpname[MAXPATHLEN], catpname[MAXPATHLEN];
1194 char cmdbuf[BUFSIZ], tmpbuf[BUFSIZ];
1195 char *cattool;
1196 int utf8 = 0;
1197 struct stat sbman, sbcat;
1198
1199 found++;
1200
1201 if (list) {
1202 (void) printf(gettext("%s(%s)\t-M %s\n"), name, dir + 3, path);
1203 return (-1);
1204 }
1205
1206 (void) snprintf(manpname, sizeof (manpname), "%s/man%s/%s", path,
1207 dir + 3, pg);
1208 (void) snprintf(catpname, sizeof (catpname), "%s/cat%s/%s", path,
1209 dir + 3, pg);
1210
1211 /* Can't do PS output if manpage doesn't exist */
1212 if (stat(manpname, &sbman) != 0 && (psoutput|lintout))
1213 return (-1);
1214
1215 /*
1216 * If both manpage and catpage do not exist, manpname is
1217 * broken symlink, most likely.
1218 */
1219 if (stat(catpname, &sbcat) != 0 && stat(manpname, &sbman) != 0)
1220 err(1, "%s", manpname);
1221
1222 /* Setup cattool */
1223 if (fnmatch("*.gz", manpname, 0) == 0)
1224 cattool = "gzcat";
1225 else if (fnmatch("*.bz2", manpname, 0) == 0)
1226 cattool = "bzcat";
1227 else
1228 cattool = "cat";
1229
1230 /* Preprocess UTF-8 input with preconv (could be smarter) */
1231 if (strstr(path, "UTF-8") != NULL)
1232 utf8 = 1;
1233
1234 if (psoutput) {
1235 (void) snprintf(cmdbuf, BUFSIZ,
1236 "cd %s; %s %s%s | mandoc -Tps | lp -Tpostscript",
1237 path, cattool, manpname,
1238 utf8 ? " | " PRECONV " -e UTF-8" : "");
1239 DPRINTF("-- Using manpage: %s\n", manpname);
1240 goto cmd;
1241 } else if (lintout) {
1242 (void) snprintf(cmdbuf, BUFSIZ,
1243 "cd %s; %s %s%s | mandoc -Tlint",
1244 path, cattool, manpname,
1245 utf8 ? " | " PRECONV " -e UTF-8" : "");
1246 DPRINTF("-- Linting manpage: %s\n", manpname);
1247 goto cmd;
1248 }
1249
1250 /*
1251 * Output catpage if:
1252 * - manpage doesn't exist
1253 * - output width is standard and catpage is recent enough
1254 */
1255 if (stat(manpname, &sbman) != 0 || (manwidth == 0 &&
1256 stat(catpname, &sbcat) == 0 && sbcat.st_mtime >= sbman.st_mtime)) {
1257 DPRINTF("-- Using catpage: %s\n", catpname);
1258 (void) snprintf(cmdbuf, BUFSIZ, "%s %s", pager, catpname);
1259 goto cmd;
1260 }
1261
1262 DPRINTF("-- Using manpage: %s\n", manpname);
1263 if (manwidth > 0)
1264 (void) snprintf(tmpbuf, BUFSIZ, "-Owidth=%d ", manwidth);
1265 (void) snprintf(cmdbuf, BUFSIZ, "cd %s; %s %s%s | mandoc -T%s %s| %s",
1266 path, cattool, manpname,
1267 utf8 ? " | " PRECONV " -e UTF-8 " : "",
1570
1571 for (secp = manp->secv; *secp != NULL; secp++) {
1572 /*
1573 * Section deduplication may have eliminated some
1574 * sections from the vector. Avoid displaying this
1575 * detail which would appear as ",," in output
1576 */
1577 if ((*secp)[0] != '\0')
1578 (void) printf(",%s", *secp);
1579 }
1580 }
1581 (void) printf("\n");
1582 }
1583
1584 static void
1585 usage_man(void)
1586 {
1587
1588 (void) fprintf(stderr, gettext(
1589 "usage: man [-alptw] [-M path] [-s section] name ...\n"
1590 " man [-M path] [-s section] -k keyword ...\n"
1591 " man [-M path] [-s section] -f keyword ...\n"));
1592
1593 exit(1);
1594 }
1595
1596 static void
1597 usage_whatapro(void)
1598 {
1599
1600 (void) fprintf(stderr, gettext(
1601 "usage: %s [-M path] [-s section] keyword ...\n"),
1602 whatis ? "whatis" : "apropos");
1603
1604 exit(1);
1605 }
1606
1607 static void
1608 usage_catman(void)
1609 {
1610 (void) fprintf(stderr, gettext(
1611 "usage: catman [-M path] [-w]\n"));
|