|
|
1.1 root 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 are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)apropos.c 5.12 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: #include <sys/param.h>
31: #include <stdio.h>
32: #include <ctype.h>
33: #include <string.h>
34: #include <stdlib.h>
35: #include "../man/pathnames.h"
36:
37: #define MAXLINELEN 256 /* max line handled */
38:
39: char *progname;
40:
41: static int *found, foundman;
42:
43: main(argc, argv)
44: int argc;
45: char **argv;
46: {
47: extern char *optarg;
48: extern int optind;
49: register char **p;
50: int ch;
51: char *p_augment, *p_path, **getdb();
52:
53: progname = "apropos";
54: p_augment = p_path = NULL;
55: while ((ch = getopt(argc, argv, "M:m:P:")) != EOF)
56: switch((char)ch) {
57: case 'M':
58: case 'P': /* backward compatible */
59: p_path = optarg;
60: break;
61: case 'm':
62: p_augment = optarg;
63: break;
64: case '?':
65: default:
66: usage();
67: }
68: argv += optind;
69: argc -= optind;
70:
71: if (argc < 1)
72: usage();
73:
74: /*NOSTRICT*/
75: if (!(found = (int *)malloc((u_int)argc)))
76: enomem();
77: bzero((void *)found, argc * sizeof(int));
78:
79: for (p = argv; *p; ++p) /* convert to lower-case */
80: lowstr(*p, *p);
81:
82: if (p_augment)
83: apropos(argv, p_augment, 1);
84: if (p_path || (p_path = getenv("MANPATH")))
85: apropos(argv, p_path, 1);
86: else
87: for (p = getdb(); *p; ++p)
88: apropos(argv, *p, 0);
89:
90: if (!foundman) {
91: (void)fprintf(stderr,
92: "apropos: : no %s file found.\n", _PATH_WHATIS);
93: exit(1);
94: }
95: for (p = argv; *p; ++p)
96: if (!found[p - argv])
97: (void)printf("%s: nothing appropriate\n", *p);
98: }
99:
100: apropos(argv, path, buildpath)
101: char **argv, *path;
102: int buildpath;
103: {
104: register char *end, *name, **p;
105: char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1];
106:
107: for (name = path; name; name = end) { /* through name list */
108: if (end = index(name, ':'))
109: *end++ = '\0';
110:
111: if (buildpath) {
112: char hold[MAXPATHLEN + 1];
113:
114: (void)sprintf(hold, "%s/%s", name, _PATH_WHATIS);
115: name = hold;
116: }
117:
118: if (!freopen(name, "r", stdin))
119: continue;
120:
121: foundman = 1;
122:
123: /* for each file found */
124: while (fgets(buf, sizeof(buf), stdin)) {
125: if (!index(buf, '\n')) {
126: (void)fprintf(stderr,
127: "apropos: %s line too long.\n", name);
128: exit(1);
129: }
130: lowstr(buf, wbuf);
131: for (p = argv; *p; ++p)
132: if (match(wbuf, *p)) {
133: (void)printf("%s", buf);
134: found[p - argv] = 1;
135:
136: /* only print line once */
137: while (*++p)
138: if (match(wbuf, *p))
139: found[p - argv] = 1;
140: break;
141: }
142: }
143: }
144: }
145:
146: /*
147: * match --
148: * match anywhere the string appears
149: */
150: match(bp, str)
151: register char *bp, *str;
152: {
153: register int len;
154: register char test;
155:
156: if (!*bp)
157: return(0);
158: /* backward compatible: everything matches empty string */
159: if (!*str)
160: return(1);
161: for (test = *str++, len = strlen(str); *bp;)
162: if (test == *bp++ && !strncmp(bp, str, len))
163: return(1);
164: return(0);
165: }
166:
167: /*
168: * lowstr --
169: * convert a string to lower case
170: */
171: lowstr(from, to)
172: register char *from, *to;
173: {
174: register char ch;
175:
176: while ((ch = *from++) && ch != '\n')
177: *to++ = isupper(ch) ? tolower(ch) : ch;
178: *to = '\0';
179: }
180:
181: /*
182: * usage --
183: * print usage message and die
184: */
185: usage()
186: {
187: (void)fprintf(stderr,
188: "usage: apropos [-M path] [-m path] keyword ...\n");
189: exit(1);
190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.