prettyness police
[unix-history] / usr / src / usr.bin / apropos / apropos.c
CommitLineData
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
9static 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 15static 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
31static int *found, foundman;
32
706c0358
JSP
33void apropos __P((char **, char *, int));
34void lowstr __P((char *, char *));
35int match __P((char *, char *));
36void usage __P((void));
37
1ce46e5c 38int
43f23b36 39main(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 103void
c0eca3d4 104apropos(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 153int
9273b7be 154match(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 175void
43f23b36 176lowstr(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 190void
43f23b36
KB
191usage()
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}