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