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