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