BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.bin / man / apropos / apropos.c
CommitLineData
43f23b36
KB
1/*
2 * Copyright (c) 1987 Regents of the University of California.
ea9afd82
KB
3 * All rights reserved.
4 *
af359dea
C
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.
43f23b36
KB
32 */
33
34#ifndef lint
35char copyright[] =
36"@(#) Copyright (c) 1987 Regents of the University of California.\n\
37 All rights reserved.\n";
ea9afd82 38#endif /* not lint */
43f23b36
KB
39
40#ifndef lint
1c15e888 41static char sccsid[] = "@(#)apropos.c 5.12 (Berkeley) 6/1/90";
ea9afd82 42#endif /* not lint */
43f23b36
KB
43
44#include <sys/param.h>
45#include <stdio.h>
46#include <ctype.h>
38dde0cd 47#include <string.h>
c0eca3d4 48#include <stdlib.h>
2f28d62a 49#include "../man/pathnames.h"
43f23b36 50
2f28d62a
KB
51#define MAXLINELEN 256 /* max line handled */
52
2f28d62a 53char *progname;
43f23b36 54
c0eca3d4
KB
55static int *found, foundman;
56
43f23b36 57main(argc, argv)
76f1f97b
KB
58 int argc;
59 char **argv;
43f23b36 60{
76f1f97b
KB
61 extern char *optarg;
62 extern int optind;
2f28d62a
KB
63 register char **p;
64 int ch;
c0eca3d4 65 char *p_augment, *p_path, **getdb();
43f23b36 66
2f28d62a
KB
67 progname = "apropos";
68 p_augment = p_path = NULL;
69 while ((ch = getopt(argc, argv, "M:m:P:")) != EOF)
43f23b36 70 switch((char)ch) {
9273b7be
KB
71 case 'M':
72 case 'P': /* backward compatible */
2f28d62a
KB
73 p_path = optarg;
74 break;
75 case 'm':
76 p_augment = optarg;
9273b7be
KB
77 break;
78 case '?':
79 default:
80 usage();
43f23b36
KB
81 }
82 argv += optind;
83 argc -= optind;
2f28d62a 84
43f23b36
KB
85 if (argc < 1)
86 usage();
87
43f23b36 88 /*NOSTRICT*/
2f28d62a
KB
89 if (!(found = (int *)malloc((u_int)argc)))
90 enomem();
c0eca3d4 91 bzero((void *)found, argc * sizeof(int));
43f23b36 92
9273b7be
KB
93 for (p = argv; *p; ++p) /* convert to lower-case */
94 lowstr(*p, *p);
2f28d62a
KB
95
96 if (p_augment)
c0eca3d4
KB
97 apropos(argv, p_augment, 1);
98 if (p_path || (p_path = getenv("MANPATH")))
99 apropos(argv, p_path, 1);
100 else
101 for (p = getdb(); *p; ++p)
102 apropos(argv, *p, 0);
103
2f28d62a 104 if (!foundman) {
c0eca3d4
KB
105 (void)fprintf(stderr,
106 "apropos: : no %s file found.\n", _PATH_WHATIS);
2f28d62a
KB
107 exit(1);
108 }
109 for (p = argv; *p; ++p)
110 if (!found[p - argv])
111 (void)printf("%s: nothing appropriate\n", *p);
112}
113
c0eca3d4 114apropos(argv, path, buildpath)
2f28d62a 115 char **argv, *path;
c0eca3d4 116 int buildpath;
2f28d62a 117{
c0eca3d4 118 register char *end, *name, **p;
2f28d62a
KB
119 char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1];
120
c0eca3d4
KB
121 for (name = path; name; name = end) { /* through name list */
122 if (end = index(name, ':'))
123 *end++ = '\0';
124
125 if (buildpath) {
126 char hold[MAXPATHLEN + 1];
127
128 (void)sprintf(hold, "%s/%s", name, _PATH_WHATIS);
129 name = hold;
43f23b36 130 }
c0eca3d4
KB
131
132 if (!freopen(name, "r", stdin))
76f1f97b
KB
133 continue;
134
c0eca3d4
KB
135 foundman = 1;
136
9273b7be 137 /* for each file found */
c0eca3d4 138 while (fgets(buf, sizeof(buf), stdin)) {
2f28d62a
KB
139 if (!index(buf, '\n')) {
140 (void)fprintf(stderr,
c0eca3d4 141 "apropos: %s line too long.\n", name);
2f28d62a
KB
142 exit(1);
143 }
9273b7be
KB
144 lowstr(buf, wbuf);
145 for (p = argv; *p; ++p)
146 if (match(wbuf, *p)) {
2f28d62a 147 (void)printf("%s", buf);
9273b7be 148 found[p - argv] = 1;
76f1f97b
KB
149
150 /* only print line once */
9273b7be
KB
151 while (*++p)
152 if (match(wbuf, *p))
153 found[p - argv] = 1;
76f1f97b
KB
154 break;
155 }
43f23b36
KB
156 }
157 }
43f23b36
KB
158}
159
76f1f97b 160/*
9273b7be
KB
161 * match --
162 * match anywhere the string appears
76f1f97b 163 */
9273b7be 164match(bp, str)
76f1f97b 165 register char *bp, *str;
43f23b36 166{
76f1f97b
KB
167 register int len;
168 register char test;
43f23b36
KB
169
170 if (!*bp)
9273b7be 171 return(0);
76f1f97b 172 /* backward compatible: everything matches empty string */
43f23b36 173 if (!*str)
9273b7be 174 return(1);
76f1f97b
KB
175 for (test = *str++, len = strlen(str); *bp;)
176 if (test == *bp++ && !strncmp(bp, str, len))
9273b7be
KB
177 return(1);
178 return(0);
76f1f97b
KB
179}
180
181/*
182 * lowstr --
183 * convert a string to lower case
184 */
43f23b36 185lowstr(from, to)
76f1f97b 186 register char *from, *to;
43f23b36 187{
9273b7be
KB
188 register char ch;
189
190 while ((ch = *from++) && ch != '\n')
191 *to++ = isupper(ch) ? tolower(ch) : ch;
192 *to = '\0';
43f23b36
KB
193}
194
76f1f97b
KB
195/*
196 * usage --
197 * print usage message and die
198 */
43f23b36
KB
199usage()
200{
2f28d62a
KB
201 (void)fprintf(stderr,
202 "usage: apropos [-M path] [-m path] keyword ...\n");
43f23b36
KB
203 exit(1);
204}