Annotation of mandoc/manpage.c, Revision 1.4
1.4 ! schwarze 1: /* $Id: manpage.c,v 1.3 2012/06/09 17:49:13 kristaps 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",
109: i + 1, res[i].file, res[i].desc);
110: free(res[i].desc);
111: }
112:
113: if (0 == term) {
114: free(res);
115: return(EXIT_SUCCESS);
116: }
117:
118: i = 1;
119: printf("Enter a choice [1]: ");
120: fflush(stdout);
121:
122: if (NULL != (cp = fgetln(stdin, &len)))
123: if ('\n' == cp[--len] && len > 0) {
124: cp[len] = '\0';
125: if ((i = atoi(cp)) < 1 || i > sz)
126: i = 0;
127: }
128:
129: if (0 == i) {
130: free(res);
131: return(EXIT_SUCCESS);
132: }
133: show:
134: cmd = res[i - 1].form ? "mandoc" : "cat";
1.4 ! schwarze 135: strlcpy(buf, res[i - 1].file, PATH_MAX);
1.1 kristaps 136: free(res);
137:
138: show(cmd, buf);
139: /* NOTREACHED */
140: usage:
141: fprintf(stderr, "usage: %s [-C conf] "
142: "[-M paths] "
143: "[-m paths] "
144: "[-S arch] "
145: "[-s section] "
146: "expr ...\n",
147: progname);
148: return(EXIT_FAILURE);
149: }
150:
151: static void
152: show(const char *cmd, const char *file)
153: {
154: int fds[2];
155: pid_t pid;
156:
157: if (-1 == pipe(fds)) {
158: perror(NULL);
159: exit(EXIT_FAILURE);
160: }
161:
162: if (-1 == (pid = fork())) {
163: perror(NULL);
164: exit(EXIT_FAILURE);
165: } else if (pid > 0) {
166: dup2(fds[0], STDIN_FILENO);
167: close(fds[1]);
168: cmd = NULL != getenv("MANPAGER") ?
169: getenv("MANPAGER") :
170: (NULL != getenv("PAGER") ?
171: getenv("PAGER") : "more");
172: execlp(cmd, cmd, (char *)NULL);
173: perror(cmd);
174: exit(EXIT_FAILURE);
175: }
176:
177: dup2(fds[1], STDOUT_FILENO);
178: close(fds[0]);
179: execlp(cmd, cmd, file, (char *)NULL);
180: perror(cmd);
181: exit(EXIT_FAILURE);
182: }
CVSweb