]> git.cameronkatri.com Git - mandoc.git/blob - manpage.c
Remove duplicate const specifiers from the declaration of mandoc_escape().
[mandoc.git] / manpage.c
1 /* $Id: manpage.c,v 1.5 2013/12/27 18:51:25 schwarze Exp $ */
2 /*
3 * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <assert.h>
22 #include <getopt.h>
23 #include <limits.h>
24 #include <stdint.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29
30 #include "manpath.h"
31 #include "mansearch.h"
32
33 static void show(const char *, const char *);
34
35 int
36 main(int argc, char *argv[])
37 {
38 int ch, term;
39 size_t i, sz, len;
40 struct mansearch search;
41 struct manpage *res;
42 char *conf_file, *defpaths, *auxpaths, *cp;
43 char buf[PATH_MAX];
44 const char *cmd;
45 struct manpaths paths;
46 char *progname;
47 extern char *optarg;
48 extern int optind;
49
50 term = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO);
51
52 progname = strrchr(argv[0], '/');
53 if (progname == NULL)
54 progname = argv[0];
55 else
56 ++progname;
57
58 auxpaths = defpaths = conf_file = NULL;
59 memset(&paths, 0, sizeof(struct manpaths));
60 memset(&search, 0, sizeof(struct mansearch));
61
62 while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
63 switch (ch) {
64 case ('C'):
65 conf_file = optarg;
66 break;
67 case ('M'):
68 defpaths = optarg;
69 break;
70 case ('m'):
71 auxpaths = optarg;
72 break;
73 case ('S'):
74 search.arch = optarg;
75 break;
76 case ('s'):
77 search.sec = optarg;
78 break;
79 default:
80 goto usage;
81 }
82
83 argc -= optind;
84 argv += optind;
85
86 if (0 == argc)
87 goto usage;
88
89 search.deftype = TYPE_Nm | TYPE_Nd;
90
91 manpath_parse(&paths, conf_file, defpaths, auxpaths);
92 ch = mansearch(&search, &paths, argc, argv, &res, &sz);
93 manpath_free(&paths);
94
95 if (0 == ch)
96 goto usage;
97
98 if (0 == sz) {
99 free(res);
100 return(EXIT_FAILURE);
101 } else if (1 == sz && term) {
102 i = 1;
103 goto show;
104 } else if (NULL == res)
105 return(EXIT_FAILURE);
106
107 for (i = 0; i < sz; i++) {
108 printf("%6zu %s: %s\n",
109 i + 1, res[i].names, res[i].desc);
110 free(res[i].names);
111 free(res[i].desc);
112 }
113
114 if (0 == term) {
115 for (i = 0; i < sz; i++)
116 free(res[i].file);
117 free(res);
118 return(EXIT_SUCCESS);
119 }
120
121 i = 1;
122 printf("Enter a choice [1]: ");
123 fflush(stdout);
124
125 if (NULL != (cp = fgetln(stdin, &len)))
126 if ('\n' == cp[--len] && len > 0) {
127 cp[len] = '\0';
128 if ((i = atoi(cp)) < 1 || i > sz)
129 i = 0;
130 }
131
132 if (0 == i) {
133 for (i = 0; i < sz; i++)
134 free(res[i].file);
135 free(res);
136 return(EXIT_SUCCESS);
137 }
138 show:
139 cmd = res[i - 1].form ? "mandoc" : "cat";
140 strlcpy(buf, res[i - 1].file, PATH_MAX);
141 for (i = 0; i < sz; i++)
142 free(res[i].file);
143 free(res);
144
145 show(cmd, buf);
146 /* NOTREACHED */
147 usage:
148 fprintf(stderr, "usage: %s [-C conf] "
149 "[-M paths] "
150 "[-m paths] "
151 "[-S arch] "
152 "[-s section] "
153 "expr ...\n",
154 progname);
155 return(EXIT_FAILURE);
156 }
157
158 static void
159 show(const char *cmd, const char *file)
160 {
161 int fds[2];
162 pid_t pid;
163
164 if (-1 == pipe(fds)) {
165 perror(NULL);
166 exit(EXIT_FAILURE);
167 }
168
169 if (-1 == (pid = fork())) {
170 perror(NULL);
171 exit(EXIT_FAILURE);
172 } else if (pid > 0) {
173 dup2(fds[0], STDIN_FILENO);
174 close(fds[1]);
175 cmd = NULL != getenv("MANPAGER") ?
176 getenv("MANPAGER") :
177 (NULL != getenv("PAGER") ?
178 getenv("PAGER") : "more");
179 execlp(cmd, cmd, (char *)NULL);
180 perror(cmd);
181 exit(EXIT_FAILURE);
182 }
183
184 dup2(fds[1], STDOUT_FILENO);
185 close(fds[0]);
186 execlp(cmd, cmd, file, (char *)NULL);
187 perror(cmd);
188 exit(EXIT_FAILURE);
189 }