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