Annotation of mandoc/manpage.c, Revision 1.5
1.5 ! schwarze 1: /* $Id: manpage.c,v 1.4 2013/06/05 02:00:26 schwarze Exp $ */
1.1 kristaps 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>
1.4 schwarze 23: #include <limits.h>
1.3 kristaps 24: #include <stdint.h>
1.1 kristaps 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;
1.2 kristaps 40: struct mansearch search;
1.1 kristaps 41: struct manpage *res;
1.2 kristaps 42: char *conf_file, *defpaths, *auxpaths, *cp;
1.4 schwarze 43: char buf[PATH_MAX];
1.1 kristaps 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:
1.2 kristaps 58: auxpaths = defpaths = conf_file = NULL;
1.1 kristaps 59: memset(&paths, 0, sizeof(struct manpaths));
1.2 kristaps 60: memset(&search, 0, sizeof(struct mansearch));
1.1 kristaps 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'):
1.2 kristaps 74: search.arch = optarg;
1.1 kristaps 75: break;
76: case ('s'):
1.2 kristaps 77: search.sec = optarg;
1.1 kristaps 78: break;
79: default:
80: goto usage;
81: }
82:
83: argc -= optind;
84: argv += optind;
85:
86: if (0 == argc)
87: goto usage;
88:
1.2 kristaps 89: search.deftype = TYPE_Nm | TYPE_Nd;
90:
1.1 kristaps 91: manpath_parse(&paths, conf_file, defpaths, auxpaths);
1.2 kristaps 92: ch = mansearch(&search, &paths, argc, argv, &res, &sz);
1.1 kristaps 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",
1.5 ! schwarze 109: i + 1, res[i].names, res[i].desc);
! 110: free(res[i].names);
1.1 kristaps 111: free(res[i].desc);
112: }
113:
114: if (0 == term) {
1.5 ! schwarze 115: for (i = 0; i < sz; i++)
! 116: free(res[i].file);
1.1 kristaps 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) {
1.5 ! schwarze 133: for (i = 0; i < sz; i++)
! 134: free(res[i].file);
1.1 kristaps 135: free(res);
136: return(EXIT_SUCCESS);
137: }
138: show:
139: cmd = res[i - 1].form ? "mandoc" : "cat";
1.4 schwarze 140: strlcpy(buf, res[i - 1].file, PATH_MAX);
1.5 ! schwarze 141: for (i = 0; i < sz; i++)
! 142: free(res[i].file);
1.1 kristaps 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: }
CVSweb