1 /*
2 *
3 * form.c -
4 *
5 * Copyright (C) 1997-1999 Satoru Takabayashi All rights reserved.
6 * This is free software with ABSOLUTELY NO WARRANTY.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * 02111-1307, USA
22 *
23 * This file must be encoded in EUC-JP encoding.
24 *
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <unistd.h>
32 #ifdef __EMX__
33 #include <sys/types.h>
34 #endif
35 #include <sys/stat.h>
36 #include "namazu.h"
37 #include "util.h"
38
39 /* load the whole of file */
load_headfoot(uchar * fname)40 uchar *load_headfoot(uchar *fname)
41 {
42 uchar *buf;
43 FILE *fp;
44 struct stat fstatus;
45
46 stat(fname, &fstatus);
47 fp = fopen(fname, "rb");
48 if (fp == NULL) {
49 fprintf(stderr, "warning: Can't open %s\n", fname);
50 return 0;
51 }
52 buf = (uchar *) malloc(fstatus.st_size + 1);
53 if (buf == NULL) {
54 error("cat_head_or_foot(malloc)");
55 }
56 if (fread(buf, sizeof(uchar), fstatus.st_size, fp) == 0
57 && fstatus.st_size != 0)
58 error("cat_head_or_foot(fread)");
59 *(buf + fstatus.st_size) = '\0';
60 fclose(fp);
61 return buf;
62 }
63
64 /* compare the element
65 * some measure of containing LF or redundant spaces are acceptable.
66 * igonore cases
67 */
cmp_element(uchar * s1,uchar * s2)68 int cmp_element(uchar *s1, uchar *s2)
69 {
70 for (; *s1 && *s2; s1++, s2++) {
71 if (*s2 == ' ') {
72 while (*s1 == ' ' || *s1 == '\t' || *s1 == '\n' || *s1 == '\r') {
73 s1++;
74 }
75 s2++;
76 }
77 if (toupper(*s1) != toupper(*s2)) {
78 break;
79 }
80 }
81 if (*s2 == '\0') {
82 return 0;
83 } else {
84 return 1;
85 }
86 }
87
88 #define iseuc(c) ((c) >= 0xa1 && (c) <= 0xfe)
89
90 /* replace <INPUT TYPE="TEXT" NAME="key" VALUE="hogehoge"> */
replace_key_value(uchar * p,uchar * orig_query)91 int replace_key_value(uchar *p, uchar *orig_query)
92 {
93 uchar query[BUFSIZE];
94
95 strcpy(query, orig_query);
96
97 if (!cmp_element(p, "INPUT TYPE=\"TEXT\" NAME=\"key\"")) {
98 for (; *p; p++)
99 fputc(*p, stdout);
100 printf(" VALUE=\"");
101 fputx(query, stdout);
102 fputs("\"", stdout);
103 return 0;
104 }
105 return 1;
106 }
107
108 /* replace <FORM METHOD="GET" ACTION="/somewhere/namazu.cgi"> */
replace_action(uchar * p)109 int replace_action(uchar *p)
110 {
111 if (!cmp_element(p, "FORM METHOD=\"GET\"")) {
112 char *script_name = getenv("SCRIPT_NAME");
113 if (script_name) {
114 printf("FORM METHOD=\"GET\" ACTION=\"%s\"", script_name);
115 return 0;
116 } else {
117 return 1;
118 }
119 }
120 return 1;
121 }
122
123 /* delete string */
delete_str(uchar * s,uchar * d)124 void delete_str(uchar *s, uchar *d)
125 {
126 int l;
127 uchar *tmp;
128
129 l = strlen(d);
130 for (tmp = s; *tmp; tmp++) {
131 if (!strncmp(tmp, d, l)) {
132 strcpy(tmp, tmp + l);
133 tmp--;
134 }
135 }
136 chop(s);
137 }
138
get_value(uchar * s,uchar * v)139 void get_value(uchar *s, uchar *v)
140 {
141 *v = '\0';
142 for (; *s; s++) {
143 if (!strncmp(s, "VALUE=\"", 7)) {
144 for (s += 7; *s && *s != '"'; s++, v++) {
145 *v = *s;
146 }
147 *v = '\0';
148 return;
149 }
150 }
151 }
152
get_select_name(uchar * s,uchar * v)153 void get_select_name(uchar *s, uchar *v)
154 {
155 *v = '\0';
156 for (; *s; s++) {
157 if (!cmp_element(s, "SELECT NAME=\"")) {
158 s = strchr(s, '"') + 1;
159 for (; *s && *s != '"'; s++, v++) {
160 *v = *s;
161 }
162 *v = '\0';
163 return;
164 }
165 }
166 }
167
str_backward_cmp(uchar * str1,uchar * str2)168 int str_backward_cmp(uchar *str1, uchar *str2)
169 {
170 uchar *p, *q;
171
172 p = str1 + strlen(str1) -1;
173 q = str2 + strlen(str2) -1;
174
175 for (; p >= str1 && q >= str2; p--, q--) {
176 if (*p != *q) {
177 return 1;
178 }
179 }
180 #if defined(WIN32) || defined(OS2)
181 if (*q != '\\' && *q != '/') {
182 #else
183 if (*q != '/') {
184 #endif
185 return 1;
186 }
187 return 0;
188 }
189
190
191 int select_option(uchar *s, uchar *name, uchar *subquery)
192 {
193 uchar value[BUFSIZE];
194
195 if (!cmp_element(s, "OPTION")) {
196 delete_str(s,"SELECTED ");
197 fputs(s, stdout);
198 get_value(s, value);
199 if (!strcmp(name, "format")) {
200 if (!strcmp(value, "short") && ShortFormat) {
201 fputs(" SELECTED", stdout);
202 } else if (!strcmp(value, "long") && (!ShortFormat)) {
203 fputs(" SELECTED", stdout);
204 }
205 } else if (!strcmp(name, "sort")) {
206 if (!strcmp(value, "later") && LaterOrder && !ScoreSort) {
207 fputs(" SELECTED", stdout);
208 } else if (!strcmp(value, "earlier") && !LaterOrder && !ScoreSort)
209 {
210 fputs(" SELECTED", stdout);
211 } else if (!strcmp(value, "score") && ScoreSort) {
212 fputs(" SELECTED", stdout);
213 }
214 } else if (!strcmp(name, "lang")) {
215 if (!strcmp(value, Lang)) {
216 fputs(" SELECTED", stdout);
217 }
218 } else if (!strcmp(name, "dbname")) {
219 if (*DbNames[0] && !str_backward_cmp(value, DbNames[0])) {
220 fputs(" SELECTED", stdout);
221 }
222 } else if (!strcmp(name, "subquery")) {
223 if (!strcmp(value, subquery)) {
224 fputs(" SELECTED", stdout);
225 }
226 } else if (!strcmp(name, "max")) {
227 if (atoi(value) == HListMax) {
228 fputs(" SELECTED", stdout);
229 }
230 }
231 return 0;
232 }
233 return 1;
234 }
235
236 /* mark CHECKBOX of dbname with CHECKED */
237 int check_checkbox(uchar *s)
238 {
239 uchar value[BUFSIZE];
240 int i;
241
242 if (!cmp_element(s, "INPUT TYPE=\"CHECKBOX\" NAME=\"dbname\"")) {
243 uchar *pp;
244 int db_count, searched;
245
246 delete_str(s,"CHECKED");
247 fputs(s, stdout);
248 get_value(s, value);
249 for (pp = value, db_count = searched = 0 ; *pp ;db_count++) {
250 uchar name[BUFSIZE], *x;
251 if ((x = strchr(pp, (int)','))) {
252 *x = '\0';
253 strcpy(name, pp);
254 pp = x + 1;
255 } else {
256 strcpy(name, pp);
257 pp += strlen(pp);
258 }
259 for (i = 0; i < DbNumber; i++) {
260 if (!str_backward_cmp(name, DbNames[i])) {
261 searched++;
262 break;
263 }
264 }
265 }
266 if (db_count == searched) {
267 printf(" CHECKED");
268 }
269 return 0;
270 }
271 return 1;
272 }
273
274 /* treat an HTML tag */
275 void treat_tag(uchar *p, uchar *q, uchar *query,
276 uchar *select_name, uchar *subquery)
277 {
278 uchar tmp[BUFSIZE];
279 int l;
280
281 l = q - p + 1;
282 if (l < BUFSIZE - 1) {
283 strncpy(tmp, p, l);
284 tmp[l] = '\0';
285 if (!replace_key_value(tmp, query))
286 return;
287 if (!replace_action(tmp))
288 return;
289 if (!select_option(tmp, select_name, subquery))
290 return;
291 if (!check_checkbox(tmp))
292 return;
293 get_select_name(tmp, select_name);
294 }
295 fputs(tmp, stdout);
296 }
297
298 /* display header or footer file.
299 * very foolish
300 */
301 void cat_head_or_foot(uchar * fname, uchar * query, uchar *subquery)
302 {
303 uchar *buf, *p, *q, name[BUFSIZE] = "";
304 int f, f2;
305 buf = load_headfoot(fname);
306 if (buf == NULL) {
307 return;
308 }
309
310 for (p = buf, f = f2 = 0; *p; p++) {
311 if (BASE_URL[0] && !strncmp(p, "\n</HEAD>", 8)) {
312 printf("\n<BASE HREF=\"%s\">", BASE_URL);
313 }
314
315 if (!f && *p == '<') {
316 if (!strncmp(p, "</TITLE>", 8)) {
317 if (*query != '\0') {
318 printf(": <");
319 fputx(query, stdout);
320 printf(">");
321 }
322 printf("</TITLE>\n");
323 p = strchr(p, '>');
324 continue;
325 }
326
327 if (!IsCGI && !ForcePrintForm && !strncmp(p, "<FORM ", 6)) f2 = 1;
328 if (!IsCGI && !ForcePrintForm && !strncmp(p, "</FORM>", 7))
329 {f2 = 0; p += 6; continue;}
330 if (f2) continue;
331 /* In case of file's encoding is ISO-2022-JP,
332 the problem occurs if JIS X 208 characters in element */
333 q = (uchar *)strchr(p, (int)'>');
334 fputs("<", stdout);
335 treat_tag(p + 1, q - 1, query, name, subquery);
336 fputs(">", stdout);
337 p = q;
338 } else {
339 if (!strncmp(p, "\x1b$", 2)
340 && (*(p + 2) == 'B' || *(p + 2) == '@'))
341 {
342 f = 1;
343 } else if (!strncmp(p, "\x1b(", 2) &&
344 (*(p + 2) == 'J' || *(p + 2) == 'B' || *(p + 2) == 'H'))
345 {
346 f = 0;
347 }
348 if (f2) continue;
349 fputc(*p, stdout);
350 }
351 }
352 free(buf);
353 }
354
355