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