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