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 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1987 Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)whatis.c 5.4 (Berkeley) 03/11/90"; 26 #endif /* not lint */ 27 28 #include <sys/param.h> 29 #include <stdio.h> 30 #include <ctype.h> 31 #include <string.h> 32 #include "../man/pathnames.h" 33 34 #define MAXLINELEN 256 /* max line handled */ 35 36 int *found, foundman; 37 char *progname; 38 39 main(argc, argv) 40 int argc; 41 char **argv; 42 { 43 extern char *optarg; 44 extern int optind; 45 register char *beg, **p; 46 int ch; 47 char *p_augment, *p_path, *config(), *getenv(), *malloc(); 48 49 progname = "whatis"; 50 while ((ch = getopt(argc, argv, "M:m:P:")) != EOF) 51 switch((char)ch) { 52 case 'M': 53 case 'P': /* backward compatible */ 54 p_path = optarg; 55 break; 56 case 'm': 57 p_augment = optarg; 58 break; 59 case '?': 60 default: 61 usage(); 62 } 63 argv += optind; 64 argc -= optind; 65 66 if (argc < 1) 67 usage(); 68 69 if (!p_path && !(p_path = getenv("MANPATH"))) 70 p_path = config(); 71 72 /*NOSTRICT*/ 73 if (!(found = (int *)malloc((u_int)argc))) 74 enomem(); 75 bzero((char *)found, argc * sizeof(int)); 76 77 for (p = argv; *p; ++p) /* trim full paths */ 78 if (beg = rindex(*p, '/')) 79 *p = beg + 1; 80 81 if (p_augment) 82 whatis(argv, p_augment); 83 if (p_path) 84 whatis(argv, p_path); 85 86 if (!foundman) { 87 fprintf(stderr, "whatis: no %s file found.\n", _PATH_WHATIS); 88 exit(1); 89 } 90 for (p = argv; *p; ++p) 91 if (!found[p - argv]) 92 printf("%s: not found\n", *p); 93 } 94 95 whatis(argv, path) 96 char **argv, *path; 97 { 98 register char *beg, *end, **p; 99 char fname[MAXPATHLEN + 1]; 100 char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1]; 101 102 for (beg = path; beg; beg = end) { /* through path list */ 103 end = index(beg, ':'); 104 if (!end) 105 (void)sprintf(fname, "%s/%s", beg, _PATH_WHATIS); 106 else { 107 (void)sprintf(fname, "%.*s/%s", end - beg, beg, 108 _PATH_WHATIS); 109 ++end; 110 } 111 if (!freopen(fname, "r", stdin)) 112 continue; 113 114 /* for each file found */ 115 for (foundman = 1; fgets(buf, sizeof(buf), stdin);) { 116 dashtrunc(buf, wbuf); 117 for (p = argv; *p; ++p) 118 if (match(wbuf, *p)) { 119 printf("%s", buf); 120 found[p - argv] = 1; 121 122 /* only print line once */ 123 while (*++p) 124 if (match(wbuf, *p)) 125 found[p - argv] = 1; 126 break; 127 } 128 } 129 } 130 } 131 132 /* 133 * match -- 134 * match a full word 135 */ 136 match(bp, str) 137 register char *bp, *str; 138 { 139 register int len; 140 register char *start; 141 142 if (!*str || !*bp) 143 return(0); 144 for (len = strlen(str);;) { 145 for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp); 146 if (!*bp) 147 break; 148 for (start = bp++; 149 *bp && (*bp == '_' || isdigit(*bp) || isalpha(*bp)); ++bp); 150 if (bp - start == len && !strncasecmp(start, str, len)) 151 return(1); 152 } 153 return(0); 154 } 155 156 /* 157 * dashtrunc -- 158 * truncate a string at " - " 159 */ 160 dashtrunc(from, to) 161 register char *from, *to; 162 { 163 register int ch; 164 165 for (; (ch = *from) && ch != '\n' && 166 (ch != ' ' || from[1] != '-' || from[2] != ' '); ++from) 167 *to++ = ch; 168 *to = '\0'; 169 } 170 171 /* 172 * usage -- 173 * print usage message and die 174 */ 175 usage() 176 { 177 (void)fprintf(stderr, 178 "usage: whatis [-M path] [-m path] command ...\n"); 179 exit(1); 180 } 181