Annotation of mandoc/manpage.c, Revision 1.2
1.2 ! kristaps 1: /* $Id: manpage.c,v 1.1 2012/06/08 10:44:52 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: #include <sys/param.h>
21:
22: #include <assert.h>
23: #include <getopt.h>
24: #include <stdio.h>
25: #include <stdlib.h>
26: #include <string.h>
27: #include <unistd.h>
28:
29: #include "manpath.h"
30: #include "mansearch.h"
31:
32: static void show(const char *, const char *);
33:
34: int
35: main(int argc, char *argv[])
36: {
37: int ch, term;
38: size_t i, sz, len;
1.2 ! kristaps 39: struct mansearch search;
1.1 kristaps 40: struct manpage *res;
1.2 ! kristaps 41: char *conf_file, *defpaths, *auxpaths, *cp;
1.1 kristaps 42: char buf[MAXPATHLEN];
43: const char *cmd;
44: struct manpaths paths;
45: char *progname;
46: extern char *optarg;
47: extern int optind;
48:
49: term = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO);
50:
51: progname = strrchr(argv[0], '/');
52: if (progname == NULL)
53: progname = argv[0];
54: else
55: ++progname;
56:
1.2 ! kristaps 57: auxpaths = defpaths = conf_file = NULL;
1.1 kristaps 58: memset(&paths, 0, sizeof(struct manpaths));
1.2 ! kristaps 59: memset(&search, 0, sizeof(struct mansearch));
1.1 kristaps 60:
61: while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
62: switch (ch) {
63: case ('C'):
64: conf_file = optarg;
65: break;
66: case ('M'):
67: defpaths = optarg;
68: break;
69: case ('m'):
70: auxpaths = optarg;
71: break;
72: case ('S'):
1.2 ! kristaps 73: search.arch = optarg;
1.1 kristaps 74: break;
75: case ('s'):
1.2 ! kristaps 76: search.sec = optarg;
1.1 kristaps 77: break;
78: default:
79: goto usage;
80: }
81:
82: argc -= optind;
83: argv += optind;
84:
85: if (0 == argc)
86: goto usage;
87:
1.2 ! kristaps 88: search.deftype = TYPE_Nm | TYPE_Nd;
! 89:
1.1 kristaps 90: manpath_parse(&paths, conf_file, defpaths, auxpaths);
1.2 ! kristaps 91: ch = mansearch(&search, &paths, argc, argv, &res, &sz);
1.1 kristaps 92: manpath_free(&paths);
93:
94: if (0 == ch)
95: goto usage;
96:
97: if (0 == sz) {
98: free(res);
99: return(EXIT_FAILURE);
100: } else if (1 == sz && term) {
101: i = 1;
102: goto show;
103: } else if (NULL == res)
104: return(EXIT_FAILURE);
105:
106: for (i = 0; i < sz; i++) {
107: printf("%6zu %s: %s\n",
108: i + 1, res[i].file, res[i].desc);
109: free(res[i].desc);
110: }
111:
112: if (0 == term) {
113: free(res);
114: return(EXIT_SUCCESS);
115: }
116:
117: i = 1;
118: printf("Enter a choice [1]: ");
119: fflush(stdout);
120:
121: if (NULL != (cp = fgetln(stdin, &len)))
122: if ('\n' == cp[--len] && len > 0) {
123: cp[len] = '\0';
124: if ((i = atoi(cp)) < 1 || i > sz)
125: i = 0;
126: }
127:
128: if (0 == i) {
129: free(res);
130: return(EXIT_SUCCESS);
131: }
132: show:
133: cmd = res[i - 1].form ? "mandoc" : "cat";
134: strlcpy(buf, res[i - 1].file, MAXPATHLEN);
135: free(res);
136:
137: show(cmd, buf);
138: /* NOTREACHED */
139: usage:
140: fprintf(stderr, "usage: %s [-C conf] "
141: "[-M paths] "
142: "[-m paths] "
143: "[-S arch] "
144: "[-s section] "
145: "expr ...\n",
146: progname);
147: return(EXIT_FAILURE);
148: }
149:
150: static void
151: show(const char *cmd, const char *file)
152: {
153: int fds[2];
154: pid_t pid;
155:
156: if (-1 == pipe(fds)) {
157: perror(NULL);
158: exit(EXIT_FAILURE);
159: }
160:
161: if (-1 == (pid = fork())) {
162: perror(NULL);
163: exit(EXIT_FAILURE);
164: } else if (pid > 0) {
165: dup2(fds[0], STDIN_FILENO);
166: close(fds[1]);
167: cmd = NULL != getenv("MANPAGER") ?
168: getenv("MANPAGER") :
169: (NULL != getenv("PAGER") ?
170: getenv("PAGER") : "more");
171: execlp(cmd, cmd, (char *)NULL);
172: perror(cmd);
173: exit(EXIT_FAILURE);
174: }
175:
176: dup2(fds[1], STDOUT_FILENO);
177: close(fds[0]);
178: execlp(cmd, cmd, file, (char *)NULL);
179: perror(cmd);
180: exit(EXIT_FAILURE);
181: }
CVSweb