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.5 (Berkeley) 05/27/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 <stdlib.h> 33 #include "../man/pathnames.h" 34 35 #define MAXLINELEN 256 /* max line handled */ 36 37 char *progname; 38 39 static int *found, foundman; 40 41 main(argc, argv) 42 int argc; 43 char **argv; 44 { 45 extern char *optarg; 46 extern int optind; 47 register char *beg, **p; 48 int ch; 49 char *p_augment, *p_path, **getdb(); 50 51 progname = "whatis"; 52 while ((ch = getopt(argc, argv, "M:m:P:")) != EOF) 53 switch((char)ch) { 54 case 'M': 55 case 'P': /* backward compatible */ 56 p_path = optarg; 57 break; 58 case 'm': 59 p_augment = optarg; 60 break; 61 case '?': 62 default: 63 usage(); 64 } 65 argv += optind; 66 argc -= optind; 67 68 if (argc < 1) 69 usage(); 70 71 /*NOSTRICT*/ 72 if (!(found = (int *)malloc((u_int)argc))) 73 enomem(); 74 bzero((char *)found, argc * sizeof(int)); 75 76 for (p = argv; *p; ++p) /* trim full paths */ 77 if (beg = rindex(*p, '/')) 78 *p = beg + 1; 79 80 if (p_augment) 81 whatis(argv, p_augment, 1); 82 if (p_path || (p_path = getenv("MANPATH"))) 83 whatis(argv, p_path, 1); 84 else 85 for (p = getdb(); *p; ++p) 86 whatis(argv, *p, 0); 87 88 if (!foundman) { 89 fprintf(stderr, "whatis: no %s file found.\n", _PATH_WHATIS); 90 exit(1); 91 } 92 for (p = argv; *p; ++p) 93 if (!found[p - argv]) 94 printf("%s: not found\n", *p); 95 } 96 97 whatis(argv, path, buildpath) 98 char **argv, *path; 99 int buildpath; 100 { 101 register char *end, *name, **p; 102 char buf[MAXLINELEN + 1], wbuf[MAXLINELEN + 1]; 103 104 for (name = path; name; name = end) { /* through name list */ 105 if (end = index(name, ':')) 106 *end++ = '\0'; 107 108 if (buildpath) { 109 char hold[MAXPATHLEN + 1]; 110 111 (void)sprintf(hold, "%s/%s", name, _PATH_WHATIS); 112 name = hold; 113 } 114 115 if (!freopen(name, "r", stdin)) 116 continue; 117 118 foundman = 1; 119 120 /* for each file found */ 121 while (fgets(buf, sizeof(buf), stdin)) { 122 dashtrunc(buf, wbuf); 123 for (p = argv; *p; ++p) 124 if (match(wbuf, *p)) { 125 printf("%s", buf); 126 found[p - argv] = 1; 127 128 /* only print line once */ 129 while (*++p) 130 if (match(wbuf, *p)) 131 found[p - argv] = 1; 132 break; 133 } 134 } 135 } 136 } 137 138 /* 139 * match -- 140 * match a full word 141 */ 142 match(bp, str) 143 register char *bp, *str; 144 { 145 register int len; 146 register char *start; 147 148 if (!*str || !*bp) 149 return(0); 150 for (len = strlen(str);;) { 151 for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp); 152 if (!*bp) 153 break; 154 for (start = bp++; 155 *bp && (*bp == '_' || isdigit(*bp) || isalpha(*bp)); ++bp); 156 if (bp - start == len && !strncasecmp(start, str, len)) 157 return(1); 158 } 159 return(0); 160 } 161 162 /* 163 * dashtrunc -- 164 * truncate a string at " - " 165 */ 166 dashtrunc(from, to) 167 register char *from, *to; 168 { 169 register int ch; 170 171 for (; (ch = *from) && ch != '\n' && 172 (ch != ' ' || from[1] != '-' || from[2] != ' '); ++from) 173 *to++ = ch; 174 *to = '\0'; 175 } 176 177 /* 178 * usage -- 179 * print usage message and die 180 */ 181 usage() 182 { 183 (void)fprintf(stderr, 184 "usage: whatis [-M path] [-m path] command ...\n"); 185 exit(1); 186 } 187