adding GNU dc ("desk calculator")
[unix-history] / usr.bin / man / whatis / whatis.c
CommitLineData
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
42char 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
48static 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
60char *progname;
61
62static int *found, foundman;
63
64main(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
121whatis(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 */
166match(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 */
190dashtrunc(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 */
205usage()
206{
207 (void)fprintf(stderr,
208 "usage: whatis [-M path] [-m path] command ...\n");
209 exit(1);
210}