Annotation of src/usr.bin/whatis/whatis.c, Revision 1.1.1.1
1.1 deraadt 1: /*
2: * Copyright (c) 1987, 1993
3: * The Regents of the University of California. All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #ifndef lint
35: static char copyright[] =
36: "@(#) Copyright (c) 1987, 1993\n\
37: The Regents of the University of California. All rights reserved.\n";
38: #endif /* not lint */
39:
40: #ifndef lint
41: static char sccsid[] = "@(#)whatis.c 8.5 (Berkeley) 11/26/93";
42: #endif /* not lint */
43:
44: #include <sys/param.h>
45: #include <sys/queue.h>
46:
47: #include <ctype.h>
48: #include <err.h>
49: #include <stdio.h>
50: #include <stdlib.h>
51: #include <string.h>
52:
53: #include "../man/config.h"
54: #include "../man/pathnames.h"
55:
56: #define MAXLINELEN 256 /* max line handled */
57:
58: static int *found, foundman;
59:
60: void dashtrunc __P((char *, char *));
61: int match __P((char *, char *));
62: void usage __P((void));
63: void whatis __P((char **, char *, int));
64:
65: int
66: main(argc, argv)
67: int argc;
68: char *argv[];
69: {
70: ENTRY *ep;
71: TAG *tp;
72: int ch, rv;
73: char *beg, *conffile, **p, *p_augment, *p_path;
74:
75: conffile = NULL;
76: p_augment = p_path = NULL;
77: while ((ch = getopt(argc, argv, "C:M:m:P:")) != EOF)
78: switch (ch) {
79: case 'C':
80: conffile = optarg;
81: break;
82: case 'M':
83: case 'P': /* backward compatible */
84: p_path = optarg;
85: break;
86: case 'm':
87: p_augment = optarg;
88: break;
89: case '?':
90: default:
91: usage();
92: }
93: argv += optind;
94: argc -= optind;
95:
96: if (argc < 1)
97: usage();
98:
99: if ((found = malloc((u_int)argc * sizeof(int))) == NULL)
100: err(1, NULL);
101: memset(found, 0, argc * sizeof(int));
102:
103: for (p = argv; *p; ++p) /* trim full paths */
104: if (beg = strrchr(*p, '/'))
105: *p = beg + 1;
106:
107: if (p_augment)
108: whatis(argv, p_augment, 1);
109: if (p_path || (p_path = getenv("MANPATH")))
110: whatis(argv, p_path, 1);
111: else {
112: config(conffile);
113: ep = (tp = getlist("_whatdb")) == NULL ?
114: NULL : tp->list.tqh_first;
115: for (; ep != NULL; ep = ep->q.tqe_next)
116: whatis(argv, ep->s, 0);
117: }
118:
119: if (!foundman) {
120: fprintf(stderr, "whatis: no %s file found.\n", _PATH_WHATIS);
121: exit(1);
122: }
123: rv = 1;
124: for (p = argv; *p; ++p)
125: if (found[p - argv])
126: rv = 0;
127: else
128: printf("%s: not found\n", *p);
129: exit(rv);
130: }
131:
132: void
133: whatis(argv, path, buildpath)
134: char **argv, *path;
135: int buildpath;
136: {
137: register char *end, *name, **p;
138: char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1];
139:
140: for (name = path; name; name = end) { /* through name list */
141: if (end = strchr(name, ':'))
142: *end++ = '\0';
143:
144: if (buildpath) {
145: char hold[MAXPATHLEN + 1];
146:
147: (void)sprintf(hold, "%s/%s", name, _PATH_WHATIS);
148: name = hold;
149: }
150:
151: if (!freopen(name, "r", stdin))
152: continue;
153:
154: foundman = 1;
155:
156: /* for each file found */
157: while (fgets(buf, sizeof(buf), stdin)) {
158: dashtrunc(buf, wbuf);
159: for (p = argv; *p; ++p)
160: if (match(wbuf, *p)) {
161: printf("%s", buf);
162: found[p - argv] = 1;
163:
164: /* only print line once */
165: while (*++p)
166: if (match(wbuf, *p))
167: found[p - argv] = 1;
168: break;
169: }
170: }
171: }
172: }
173:
174: /*
175: * match --
176: * match a full word
177: */
178: int
179: match(bp, str)
180: register char *bp, *str;
181: {
182: register int len;
183: register char *start;
184:
185: if (!*str || !*bp)
186: return(0);
187: for (len = strlen(str);;) {
188: for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp);
189: if (!*bp)
190: break;
191: for (start = bp++;
192: *bp && (*bp == '_' || isdigit(*bp) || isalpha(*bp)); ++bp);
193: if (bp - start == len && !strncasecmp(start, str, len))
194: return(1);
195: }
196: return(0);
197: }
198:
199: /*
200: * dashtrunc --
201: * truncate a string at " - "
202: */
203: void
204: dashtrunc(from, to)
205: register char *from, *to;
206: {
207: register int ch;
208:
209: for (; (ch = *from) && ch != '\n' &&
210: (ch != ' ' || from[1] != '-' || from[2] != ' '); ++from)
211: *to++ = ch;
212: *to = '\0';
213: }
214:
215: /*
216: * usage --
217: * print usage message and die
218: */
219: void
220: usage()
221: {
222: (void)fprintf(stderr,
223: "usage: whatis [-C file] [-M path] [-m path] command ...\n");
224: exit(1);
225: }