1 /*- 2 * Copyright (c) 1987 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.proprietary.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1987 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)look.c 4.9 (Berkeley) 04/18/91"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/file.h> 20 #include <sys/stat.h> 21 #include <stdio.h> 22 #include <ctype.h> 23 #include "pathnames.h" 24 25 #define EOS '\0' 26 #define MAXLINELEN 250 27 #define YES 1 28 29 static int fold, dict, len; 30 31 main(argc, argv) 32 int argc; 33 char **argv; 34 { 35 extern char *optarg; 36 extern int optind; 37 static char *filename = _PATH_WORDS; 38 register off_t bot, mid, top; 39 register int c; 40 struct stat sb; 41 char entry[MAXLINELEN], copy[MAXLINELEN]; 42 43 while ((c = getopt(argc, argv, "df")) != EOF) 44 switch((char)c) { 45 case 'd': 46 dict = YES; 47 break; 48 case 'f': 49 fold = YES; 50 break; 51 case '?': 52 default: 53 usage(); 54 } 55 argv += optind; 56 argc -= optind; 57 58 switch(argc) { 59 case 1: /* if default file, set to dictionary order and folding */ 60 dict = fold = YES; 61 break; 62 case 2: 63 filename = argv[1]; 64 break; 65 default: 66 usage(); 67 } 68 69 if (!freopen(filename, "r", stdin)) { 70 fprintf(stderr,"look: can't read %s.\n", filename); 71 exit(2); 72 } 73 if (fstat(fileno(stdin), &sb)) { 74 perror("look: fstat"); 75 exit(2); 76 } 77 78 len = strlen(*argv); 79 canon(*argv, *argv); 80 len = strlen(*argv); /* may have changed */ 81 if (len > MAXLINELEN - 1) { 82 (void)fprintf(stderr, 83 "look: search string is too long.\n"); 84 exit(2); 85 } 86 87 for (bot = 0, top = sb.st_size;;) { 88 mid = (top + bot) / 2; 89 (void)fseek(stdin, mid, L_SET); 90 91 for (++mid; (c = getchar()) != EOF && c != '\n'; ++mid); 92 if (!getline(entry)) 93 break; 94 canon(entry, copy); 95 if (strncmp(*argv, copy, len) <= 0) { 96 if (top <= mid) 97 break; 98 top = mid; 99 } 100 else 101 bot = mid; 102 } 103 (void)fseek(stdin, bot, L_SET); 104 while (ftell(stdin) < top) { 105 register int val; 106 107 if (!getline(entry)) 108 exit(0); 109 canon(entry, copy); 110 if (!(val = strncmp(*argv, copy, len))) { 111 puts(entry); 112 break; 113 } 114 if (val < 0) 115 exit(0); 116 } 117 while (getline(entry)) { 118 canon(entry, copy); 119 if (strncmp(*argv, copy, len)) 120 break; 121 puts(entry); 122 } 123 exit(0); 124 } 125 126 /* 127 * getline -- 128 * get a line 129 */ 130 getline(buf) 131 register char *buf; 132 { 133 register int c; 134 135 for (;;) { 136 if ((c = getchar()) == EOF) 137 return(0); 138 if (c == '\n') 139 break; 140 *buf++ = c; 141 } 142 *buf = EOS; 143 return(1); 144 } 145 146 /* 147 * canon -- 148 * create canonical version of word 149 */ 150 canon(src, copy) 151 register char *src, *copy; 152 { 153 register int cnt; 154 register char c; 155 156 for (cnt = len + 1; (c = *src++) && cnt; --cnt) 157 if (!dict || isalnum(c)) 158 *copy++ = fold && isupper(c) ? tolower(c) : c; 159 *copy = EOS; 160 } 161 162 /* 163 * usage -- 164 * print a usage message and die 165 */ 166 usage() 167 { 168 (void)fprintf(stderr, "usage: look [-df] string [file]\n"); 169 exit(1); 170 } 171