1 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
2 /* All Rights Reserved */
3
4
5 /*
6 * Copyright (c) 1980 Regents of the University of California.
7 * All rights reserved. The Berkeley software License Agreement
8 * specifies the terms and conditions for redistribution.
9 */
10
11 /*
12 * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc.
13 * All Rights Reserved.
14 */
15
16 /* from OpenSolaris "refer2.c 1.4 05/06/02 SMI" */
17
18 /*
19 * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany
20 *
21 * Sccsid @(#)refer2.c 1.4 (gritter) 9/7/08
22 */
23
24 #include "refer..c"
25 #include <locale.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <limits.h>
29 #define NFLD 30
30 #define TLEN PATH_MAX
31
32 extern FILE *in;
33 char one[ANSLEN];
34 int onelen = ANSLEN;
35 static char dr [100] = "";
36
37 void
doref(char * line1)38 doref(char *line1)
39 {
40 char buff[QLEN], dbuff[3*QLEN];
41 char answer[ANSLEN], temp[TLEN], line[BUFSIZ];
42 char *p, **sr, *flds[NFLD], *r;
43 int nf, nr, query = 0, alph, digs;
44
45 again:
46 buff[0] = dbuff[0] = 0;
47 if (biblio && Iline == 1 && line1[0] == '%')
48 n_strcat(dbuff, line1, sizeof(dbuff));
49 while (input(line, sizeof(line))) { /* get query */
50 Iline++;
51 if (prefix(".]", line))
52 break;
53 if (biblio && line[0] == '\n')
54 break;
55 if (biblio && line[0] == '%' && line[1] == *convert)
56 break;
57 if (control(line[0]))
58 query = 1;
59 n_strcat(query ? dbuff : buff, line, query ?
60 sizeof(dbuff) : sizeof(buff));
61 if (strlen(buff) > QLEN)
62 err("query too long (%d)", strlen(buff));
63 if (strlen(dbuff) > 3 * QLEN)
64 err("record at line %d too long", Iline-1);
65 }
66 if (biblio && line[0] == '\n' && feof(in))
67 return;
68 if (strcmp(buff, "$LIST$\n")==0) {
69 assert (dbuff[0] == 0);
70 dumpold();
71 return;
72 }
73 answer[0] = 0;
74 for (p = buff; *p; p++) {
75 if (isupper((int)*p))
76 *p |= 040;
77 }
78 alph = digs = 0;
79 for (p = buff; *p; p++) {
80 if (isalpha((int)*p))
81 alph++;
82 else
83 if (isdigit((int)*p))
84 digs++;
85 else {
86 *p = 0;
87 if ((alph+digs < 3) || common(p-alph)) {
88 r = p-alph;
89 while (r < p)
90 *r++ = ' ';
91 }
92 if (alph == 0 && digs > 0) {
93 r = p-digs;
94 if (digs != 4 || atoi(r)/100 != 19) {
95 while (r < p)
96 *r++ = ' ';
97 }
98 }
99 *p = ' ';
100 alph = digs = 0;
101 }
102 }
103 one[0] = 0;
104 if (buff[0]) { /* do not search if no query */
105 for (sr = rdata; sr < search; sr++) {
106 temp[0] = 0;
107 corout(buff, temp, "hunt", *sr, TLEN);
108 assert(strlen(temp) < TLEN);
109 if (strlen(temp)+strlen(answer) > BUFSIZ)
110 err("Accumulated answers too large",0);
111 n_strcat(answer, temp, sizeof(answer));
112 if (strlen(answer)>BUFSIZ)
113 err("answer too long (%d)", strlen(answer));
114 if (newline(answer) > 0)
115 break;
116 }
117 }
118 assert(strlen(one) < ANSLEN);
119 assert(strlen(answer) < ANSLEN);
120 if (buff[0])
121 switch (newline(answer)) {
122 case 0:
123 fprintf(stderr, "No such paper: %s\n", buff);
124 return;
125 default:
126 fprintf(stderr, "Too many hits: %s\n", trimnl(buff));
127 choices(answer);
128 p = buff;
129 while (*p != '\n')
130 p++;
131 *++p = 0;
132 case 1:
133 if (endpush)
134 if ((nr = chkdup(answer))) {
135 if (bare < 2) {
136 nf = tabs(flds, one);
137 nf += tabs(flds+nf, dbuff);
138 assert(nf < NFLD);
139 putsig(nf,flds,nr,line1,line,0);
140 }
141 return;
142 }
143 if (one[0] == 0)
144 corout(answer, one, "deliv", dr, QLEN);
145 break;
146 }
147 assert(strlen(buff) < QLEN);
148 assert(strlen(one) < ANSLEN);
149 nf = tabs(flds, one);
150 nf += tabs(flds+nf, dbuff);
151 assert(nf < NFLD);
152 refnum++;
153 if (sort)
154 putkey(nf, flds, refnum, keystr);
155 if (bare < 2)
156 putsig(nf, flds, refnum, line1, line, 1);
157 else
158 flout();
159 putref(nf, flds);
160 if (biblio && line[0] == '\n')
161 goto again;
162 if (biblio && line[0] == '%' && line[1] == *convert)
163 fprintf(fo, "%s%c%s", convert+1, sep, line+3);
164 }
165
166 int
newline(const char * s)167 newline(const char *s)
168 {
169 int k = 0, c;
170
171 while ((c = *s++))
172 if (c == '\n')
173 k++;
174 return(k);
175 }
176
177 void
choices(char * buff)178 choices(char *buff)
179 {
180 char ob[BUFSIZ], *p, *r, *q, *t;
181 int nl;
182
183 for (r = p = buff; *p; p++) {
184 if (*p == '\n') {
185 *p++ = 0;
186 corout(r, ob, "deliv", dr, BUFSIZ);
187 nl = 1;
188 for (q = ob; *q; q++) {
189 if (nl && (q[0]=='.'||q[0]=='%') && q[1]=='T') {
190 q += 3;
191 for (t = q; *t && *t != '\n'; t++)
192 ;
193 *t = 0;
194 fprintf(stderr, "%.70s\n", q);
195 q = 0;
196 break;
197 }
198 nl = *q == '\n';
199 }
200 if (q)
201 fprintf(stderr, "??? at %s\n",r);
202 r=p;
203 }
204 }
205 }
206
207 int
control(int c)208 control(int c)
209 {
210 if (c == '.')
211 return(1);
212 if (c == '%')
213 return(1);
214 return(0);
215 }
216