Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | /* |
2 | * Copyright (c) 1987 Regents of the University of California. | |
3 | * 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 | * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE | |
34 | * -------------------- ----- ---------------------- | |
35 | * CURRENT PATCH LEVEL: 1 00005 | |
36 | * -------------------- ----- ---------------------- | |
37 | * | |
38 | * 20 Aug 92 Andrew Moore Fixed core dump from uninited pointers | |
39 | */ | |
40 | ||
41 | #ifndef lint | |
42 | char copyright[] = | |
43 | "@(#) Copyright (c) 1987 Regents of the University of California.\n\ | |
44 | All rights reserved.\n"; | |
45 | #endif /* not lint */ | |
46 | ||
47 | #ifndef lint | |
48 | static char sccsid[] = "@(#)whatis.c 5.6 (Berkeley) 6/1/90"; | |
49 | #endif /* not lint */ | |
50 | ||
51 | #include <sys/param.h> | |
52 | #include <stdio.h> | |
53 | #include <ctype.h> | |
54 | #include <string.h> | |
55 | #include <stdlib.h> | |
56 | #include "../man/pathnames.h" | |
57 | ||
58 | #define MAXLINELEN 256 /* max line handled */ | |
59 | ||
60 | char *progname; | |
61 | ||
62 | static int *found, foundman; | |
63 | ||
64 | main(argc, argv) | |
65 | int argc; | |
66 | char **argv; | |
67 | { | |
68 | extern char *optarg; | |
69 | extern int optind; | |
70 | register char *beg, **p; | |
71 | int ch; | |
72 | char *p_augment, *p_path, **getdb(); | |
73 | ||
74 | progname = "whatis"; | |
75 | p_augment = p_path = NULL; /* 20 Aug 92*/ | |
76 | while ((ch = getopt(argc, argv, "M:m:P:")) != EOF) | |
77 | switch((char)ch) { | |
78 | case 'M': | |
79 | case 'P': /* backward compatible */ | |
80 | p_path = optarg; | |
81 | break; | |
82 | case 'm': | |
83 | p_augment = optarg; | |
84 | break; | |
85 | case '?': | |
86 | default: | |
87 | usage(); | |
88 | } | |
89 | argv += optind; | |
90 | argc -= optind; | |
91 | ||
92 | if (argc < 1) | |
93 | usage(); | |
94 | ||
95 | /*NOSTRICT*/ | |
96 | if (!(found = (int *)malloc((u_int)argc))) | |
97 | enomem(); | |
98 | bzero((char *)found, argc * sizeof(int)); | |
99 | ||
100 | for (p = argv; *p; ++p) /* trim full paths */ | |
101 | if (beg = rindex(*p, '/')) | |
102 | *p = beg + 1; | |
103 | ||
104 | if (p_augment) | |
105 | whatis(argv, p_augment, 1); | |
106 | if (p_path || (p_path = getenv("MANPATH"))) | |
107 | whatis(argv, p_path, 1); | |
108 | else | |
109 | for (p = getdb(); *p; ++p) | |
110 | whatis(argv, *p, 0); | |
111 | ||
112 | if (!foundman) { | |
113 | fprintf(stderr, "whatis: no %s file found.\n", _PATH_WHATIS); | |
114 | exit(1); | |
115 | } | |
116 | for (p = argv; *p; ++p) | |
117 | if (!found[p - argv]) | |
118 | printf("%s: not found\n", *p); | |
119 | } | |
120 | ||
121 | whatis(argv, path, buildpath) | |
122 | char **argv, *path; | |
123 | int buildpath; | |
124 | { | |
125 | register char *end, *name, **p; | |
126 | char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1]; | |
127 | ||
128 | for (name = path; name; name = end) { /* through name list */ | |
129 | if (end = index(name, ':')) | |
130 | *end++ = '\0'; | |
131 | ||
132 | if (buildpath) { | |
133 | char hold[MAXPATHLEN + 1]; | |
134 | ||
135 | (void)sprintf(hold, "%s/%s", name, _PATH_WHATIS); | |
136 | name = hold; | |
137 | } | |
138 | ||
139 | if (!freopen(name, "r", stdin)) | |
140 | continue; | |
141 | ||
142 | foundman = 1; | |
143 | ||
144 | /* for each file found */ | |
145 | while (fgets(buf, sizeof(buf), stdin)) { | |
146 | dashtrunc(buf, wbuf); | |
147 | for (p = argv; *p; ++p) | |
148 | if (match(wbuf, *p)) { | |
149 | printf("%s", buf); | |
150 | found[p - argv] = 1; | |
151 | ||
152 | /* only print line once */ | |
153 | while (*++p) | |
154 | if (match(wbuf, *p)) | |
155 | found[p - argv] = 1; | |
156 | break; | |
157 | } | |
158 | } | |
159 | } | |
160 | } | |
161 | ||
162 | /* | |
163 | * match -- | |
164 | * match a full word | |
165 | */ | |
166 | match(bp, str) | |
167 | register char *bp, *str; | |
168 | { | |
169 | register int len; | |
170 | register char *start; | |
171 | ||
172 | if (!*str || !*bp) | |
173 | return(0); | |
174 | for (len = strlen(str);;) { | |
175 | for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp); | |
176 | if (!*bp) | |
177 | break; | |
178 | for (start = bp++; | |
179 | *bp && (*bp == '_' || isdigit(*bp) || isalpha(*bp)); ++bp); | |
180 | if (bp - start == len && !strncasecmp(start, str, len)) | |
181 | return(1); | |
182 | } | |
183 | return(0); | |
184 | } | |
185 | ||
186 | /* | |
187 | * dashtrunc -- | |
188 | * truncate a string at " - " | |
189 | */ | |
190 | dashtrunc(from, to) | |
191 | register char *from, *to; | |
192 | { | |
193 | register int ch; | |
194 | ||
195 | for (; (ch = *from) && ch != '\n' && | |
196 | (ch != ' ' || from[1] != '-' || from[2] != ' '); ++from) | |
197 | *to++ = ch; | |
198 | *to = '\0'; | |
199 | } | |
200 | ||
201 | /* | |
202 | * usage -- | |
203 | * print usage message and die | |
204 | */ | |
205 | usage() | |
206 | { | |
207 | (void)fprintf(stderr, | |
208 | "usage: whatis [-M path] [-m path] command ...\n"); | |
209 | exit(1); | |
210 | } |