Annotation of mandoc/manpage.c, Revision 1.9
1.9 ! schwarze 1: /* $Id: manpage.c,v 1.8 2014/08/10 23:54:41 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: #include "config.h"
1.8 schwarze 19:
20: #include <sys/types.h>
1.1 kristaps 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.9 ! schwarze 90: search.outkey = "Nd";
! 91: search.argmode = ARG_EXPR;
1.2 kristaps 92:
1.1 kristaps 93: manpath_parse(&paths, conf_file, defpaths, auxpaths);
1.9 ! schwarze 94: ch = mansearch(&search, &paths, argc, argv, &res, &sz);
1.1 kristaps 95: manpath_free(&paths);
96:
97: if (0 == ch)
98: goto usage;
99:
100: if (0 == sz) {
101: free(res);
102: return(EXIT_FAILURE);
103: } else if (1 == sz && term) {
104: i = 1;
105: goto show;
106: } else if (NULL == res)
107: return(EXIT_FAILURE);
108:
109: for (i = 0; i < sz; i++) {
110: printf("%6zu %s: %s\n",
1.7 schwarze 111: i + 1, res[i].names, res[i].output);
1.5 schwarze 112: free(res[i].names);
1.6 schwarze 113: free(res[i].output);
1.1 kristaps 114: }
115:
116: if (0 == term) {
1.5 schwarze 117: for (i = 0; i < sz; i++)
118: free(res[i].file);
1.1 kristaps 119: free(res);
120: return(EXIT_SUCCESS);
121: }
122:
123: i = 1;
124: printf("Enter a choice [1]: ");
125: fflush(stdout);
126:
127: if (NULL != (cp = fgetln(stdin, &len)))
128: if ('\n' == cp[--len] && len > 0) {
129: cp[len] = '\0';
130: if ((i = atoi(cp)) < 1 || i > sz)
131: i = 0;
132: }
133:
134: if (0 == i) {
1.5 schwarze 135: for (i = 0; i < sz; i++)
136: free(res[i].file);
1.1 kristaps 137: free(res);
138: return(EXIT_SUCCESS);
139: }
140: show:
141: cmd = res[i - 1].form ? "mandoc" : "cat";
1.4 schwarze 142: strlcpy(buf, res[i - 1].file, PATH_MAX);
1.5 schwarze 143: for (i = 0; i < sz; i++)
144: free(res[i].file);
1.1 kristaps 145: free(res);
146:
147: show(cmd, buf);
148: /* NOTREACHED */
149: usage:
150: fprintf(stderr, "usage: %s [-C conf] "
151: "[-M paths] "
152: "[-m paths] "
153: "[-S arch] "
154: "[-s section] "
155: "expr ...\n",
156: progname);
157: return(EXIT_FAILURE);
158: }
159:
160: static void
161: show(const char *cmd, const char *file)
162: {
163: int fds[2];
164: pid_t pid;
165:
166: if (-1 == pipe(fds)) {
167: perror(NULL);
168: exit(EXIT_FAILURE);
169: }
170:
171: if (-1 == (pid = fork())) {
172: perror(NULL);
173: exit(EXIT_FAILURE);
174: } else if (pid > 0) {
175: dup2(fds[0], STDIN_FILENO);
176: close(fds[1]);
177: cmd = NULL != getenv("MANPAGER") ?
178: getenv("MANPAGER") :
179: (NULL != getenv("PAGER") ?
180: getenv("PAGER") : "more");
181: execlp(cmd, cmd, (char *)NULL);
182: perror(cmd);
183: exit(EXIT_FAILURE);
184: }
185:
186: dup2(fds[1], STDOUT_FILENO);
187: close(fds[0]);
188: execlp(cmd, cmd, file, (char *)NULL);
189: perror(cmd);
190: exit(EXIT_FAILURE);
191: }
CVSweb