Commit | Line | Data |
---|---|---|
43f23b36 | 1 | /* |
ad43d1e0 KB |
2 | * Copyright (c) 1987, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
ea9afd82 | 4 | * |
f15db449 | 5 | * %sccs.include.redist.c% |
43f23b36 KB |
6 | */ |
7 | ||
8 | #ifndef lint | |
ad43d1e0 KB |
9 | static char copyright[] = |
10 | "@(#) Copyright (c) 1987, 1993\n\ | |
11 | The Regents of the University of California. All rights reserved.\n"; | |
ea9afd82 | 12 | #endif /* not lint */ |
43f23b36 KB |
13 | |
14 | #ifndef lint | |
706c0358 | 15 | static char sccsid[] = "@(#)apropos.c 8.6 (Berkeley) %G%"; |
ea9afd82 | 16 | #endif /* not lint */ |
43f23b36 KB |
17 | |
18 | #include <sys/param.h> | |
1ce46e5c KB |
19 | #include <sys/queue.h> |
20 | ||
43f23b36 | 21 | #include <ctype.h> |
1ce46e5c | 22 | #include <err.h> |
706c0358 | 23 | #include <limits.h> |
1ce46e5c | 24 | #include <stdio.h> |
c0eca3d4 | 25 | #include <stdlib.h> |
1ce46e5c KB |
26 | #include <string.h> |
27 | ||
28 | #include "../man/config.h" | |
2f28d62a | 29 | #include "../man/pathnames.h" |
43f23b36 | 30 | |
c0eca3d4 KB |
31 | static int *found, foundman; |
32 | ||
706c0358 JSP |
33 | void apropos __P((char **, char *, int)); |
34 | void lowstr __P((char *, char *)); | |
35 | int match __P((char *, char *)); | |
36 | void usage __P((void)); | |
37 | ||
1ce46e5c | 38 | int |
43f23b36 | 39 | main(argc, argv) |
76f1f97b | 40 | int argc; |
1ce46e5c | 41 | char *argv[]; |
43f23b36 | 42 | { |
1ce46e5c | 43 | ENTRY *ep; |
c8718fc0 | 44 | TAG *tp; |
c73b790e | 45 | int ch, rv; |
756e0dcc | 46 | char *conffile, **p, *p_augment, *p_path; |
43f23b36 | 47 | |
756e0dcc | 48 | conffile = NULL; |
2f28d62a | 49 | p_augment = p_path = NULL; |
756e0dcc | 50 | while ((ch = getopt(argc, argv, "C:M:m:P:")) != EOF) |
1ce46e5c | 51 | switch (ch) { |
756e0dcc KB |
52 | case 'C': |
53 | conffile = optarg; | |
54 | break; | |
9273b7be KB |
55 | case 'M': |
56 | case 'P': /* backward compatible */ | |
2f28d62a KB |
57 | p_path = optarg; |
58 | break; | |
59 | case 'm': | |
60 | p_augment = optarg; | |
9273b7be KB |
61 | break; |
62 | case '?': | |
63 | default: | |
64 | usage(); | |
43f23b36 KB |
65 | } |
66 | argv += optind; | |
67 | argc -= optind; | |
2f28d62a | 68 | |
43f23b36 KB |
69 | if (argc < 1) |
70 | usage(); | |
71 | ||
c73b790e | 72 | if ((found = malloc((u_int)argc * sizeof(int))) == NULL) |
1ce46e5c KB |
73 | err(1, NULL); |
74 | memset(found, 0, argc * sizeof(int)); | |
43f23b36 | 75 | |
9273b7be KB |
76 | for (p = argv; *p; ++p) /* convert to lower-case */ |
77 | lowstr(*p, *p); | |
2f28d62a KB |
78 | |
79 | if (p_augment) | |
c0eca3d4 KB |
80 | apropos(argv, p_augment, 1); |
81 | if (p_path || (p_path = getenv("MANPATH"))) | |
82 | apropos(argv, p_path, 1); | |
1ce46e5c | 83 | else { |
756e0dcc | 84 | config(conffile); |
c8718fc0 KB |
85 | ep = (tp = getlist("_whatdb")) == NULL ? |
86 | NULL : tp->list.tqh_first; | |
87 | for (; ep != NULL; ep = ep->q.tqe_next) | |
1ce46e5c KB |
88 | apropos(argv, ep->s, 0); |
89 | } | |
c0eca3d4 | 90 | |
706c0358 JSP |
91 | if (!foundman) |
92 | errx(1, "no %s file found", _PATH_WHATIS); | |
93 | ||
c73b790e | 94 | rv = 1; |
2f28d62a | 95 | for (p = argv; *p; ++p) |
c73b790e KB |
96 | if (found[p - argv]) |
97 | rv = 0; | |
98 | else | |
2f28d62a | 99 | (void)printf("%s: nothing appropriate\n", *p); |
c73b790e | 100 | exit(rv); |
2f28d62a KB |
101 | } |
102 | ||
706c0358 | 103 | void |
c0eca3d4 | 104 | apropos(argv, path, buildpath) |
2f28d62a | 105 | char **argv, *path; |
c0eca3d4 | 106 | int buildpath; |
2f28d62a | 107 | { |
706c0358 JSP |
108 | char *end, *name, **p; |
109 | char buf[LINE_MAX + 1], wbuf[LINE_MAX + 1]; | |
2f28d62a | 110 | |
c0eca3d4 | 111 | for (name = path; name; name = end) { /* through name list */ |
706c0358 | 112 | if (end = strchr(name, ':')) |
c0eca3d4 KB |
113 | *end++ = '\0'; |
114 | ||
115 | if (buildpath) { | |
116 | char hold[MAXPATHLEN + 1]; | |
117 | ||
118 | (void)sprintf(hold, "%s/%s", name, _PATH_WHATIS); | |
119 | name = hold; | |
43f23b36 | 120 | } |
c0eca3d4 KB |
121 | |
122 | if (!freopen(name, "r", stdin)) | |
76f1f97b KB |
123 | continue; |
124 | ||
c0eca3d4 KB |
125 | foundman = 1; |
126 | ||
9273b7be | 127 | /* for each file found */ |
c0eca3d4 | 128 | while (fgets(buf, sizeof(buf), stdin)) { |
706c0358 JSP |
129 | if (!strchr(buf, '\n')) { |
130 | warnx("%s: line too long", name); | |
14b743d6 | 131 | continue; |
2f28d62a | 132 | } |
9273b7be KB |
133 | lowstr(buf, wbuf); |
134 | for (p = argv; *p; ++p) | |
135 | if (match(wbuf, *p)) { | |
2f28d62a | 136 | (void)printf("%s", buf); |
9273b7be | 137 | found[p - argv] = 1; |
76f1f97b KB |
138 | |
139 | /* only print line once */ | |
9273b7be KB |
140 | while (*++p) |
141 | if (match(wbuf, *p)) | |
142 | found[p - argv] = 1; | |
76f1f97b KB |
143 | break; |
144 | } | |
43f23b36 KB |
145 | } |
146 | } | |
43f23b36 KB |
147 | } |
148 | ||
76f1f97b | 149 | /* |
9273b7be KB |
150 | * match -- |
151 | * match anywhere the string appears | |
76f1f97b | 152 | */ |
706c0358 | 153 | int |
9273b7be | 154 | match(bp, str) |
706c0358 | 155 | char *bp, *str; |
43f23b36 | 156 | { |
706c0358 JSP |
157 | int len; |
158 | char test; | |
43f23b36 KB |
159 | |
160 | if (!*bp) | |
706c0358 | 161 | return (0); |
76f1f97b | 162 | /* backward compatible: everything matches empty string */ |
43f23b36 | 163 | if (!*str) |
706c0358 | 164 | return (1); |
76f1f97b KB |
165 | for (test = *str++, len = strlen(str); *bp;) |
166 | if (test == *bp++ && !strncmp(bp, str, len)) | |
706c0358 JSP |
167 | return (1); |
168 | return (0); | |
76f1f97b KB |
169 | } |
170 | ||
171 | /* | |
172 | * lowstr -- | |
173 | * convert a string to lower case | |
174 | */ | |
706c0358 | 175 | void |
43f23b36 | 176 | lowstr(from, to) |
706c0358 | 177 | char *from, *to; |
43f23b36 | 178 | { |
706c0358 | 179 | char ch; |
9273b7be KB |
180 | |
181 | while ((ch = *from++) && ch != '\n') | |
182 | *to++ = isupper(ch) ? tolower(ch) : ch; | |
183 | *to = '\0'; | |
43f23b36 KB |
184 | } |
185 | ||
76f1f97b KB |
186 | /* |
187 | * usage -- | |
188 | * print usage message and die | |
189 | */ | |
706c0358 | 190 | void |
43f23b36 KB |
191 | usage() |
192 | { | |
706c0358 | 193 | |
2f28d62a | 194 | (void)fprintf(stderr, |
756e0dcc | 195 | "usage: apropos [-C file] [-M path] [-m path] keyword ...\n"); |
43f23b36 KB |
196 | exit(1); |
197 | } |