1 /* $Id: frame.c,v 1.34 2003/09/26 17:59:51 ukai Exp $ */
2 #include "fm.h"
3 #include "parsetagx.h"
4 #include "myctype.h"
5 #include <signal.h>
6 #include <setjmp.h>
7
8 static JMP_BUF AbortLoading;
9 struct frameset *renderFrameSet = NULL;
10
11 static MySignalHandler
KeyAbort(SIGNAL_ARG)12 KeyAbort(SIGNAL_ARG)
13 {
14 LONGJMP(AbortLoading, 1);
15 }
16
17 static int
parseFrameSetLength(char * s,char *** ret)18 parseFrameSetLength(char *s, char ***ret)
19 {
20 int i, len;
21 char *p, *q, **lv;
22
23 i = 1;
24
25 if (s)
26 for (p = s; (p = strchr(p, ',')); ++p)
27 ++i;
28 else
29 s = "*";
30
31 lv = New_N(char *, i);
32
33 for (i = 0, p = s;; ++p) {
34 SKIP_BLANKS(p);
35 len = strtol(p, &q, 10);
36
37 switch (*q) {
38 case '%':
39 lv[i++] = Sprintf("%d%%", len)->ptr;
40 break;
41 case '*':
42 lv[i++] = "*";
43 break;
44 default:
45 lv[i++] = Sprintf("%d", len)->ptr;
46 break;
47 }
48
49 if (!(p = strchr(q, ',')))
50 break;
51 }
52
53 *ret = lv;
54 return i;
55 }
56
57 struct frameset *
newFrameSet(struct parsed_tag * tag)58 newFrameSet(struct parsed_tag *tag)
59 {
60 struct frameset *f;
61 int i;
62 char *cols = NULL, *rows = NULL;
63
64 f = New(struct frameset);
65 f->attr = F_FRAMESET;
66 f->name = NULL;
67 f->currentURL = NULL;
68 parsedtag_get_value(tag, ATTR_COLS, &cols);
69 parsedtag_get_value(tag, ATTR_ROWS, &rows);
70 f->col = parseFrameSetLength(cols, &f->width);
71 f->row = parseFrameSetLength(rows, &f->height);
72 f->i = 0;
73 i = f->row * f->col;
74 f->frame = New_N(union frameset_element, i);
75 do {
76 f->frame[--i].element = NULL;
77 } while (i);
78 return f;
79 }
80
81 struct frame_body *
newFrame(struct parsed_tag * tag,Buffer * buf)82 newFrame(struct parsed_tag *tag, Buffer *buf)
83 {
84 struct frame_body *body;
85 char *p;
86
87 body = New(struct frame_body);
88 bzero((void *)body, sizeof(*body));
89 body->attr = F_UNLOADED;
90 body->flags = 0;
91 body->baseURL = baseURL(buf);
92 if (tag) {
93 if (parsedtag_get_value(tag, ATTR_SRC, &p))
94 body->url = url_encode(remove_space(p), body->baseURL,
95 buf->document_charset);
96 if (parsedtag_get_value(tag, ATTR_NAME, &p) && *p != '_')
97 body->name = url_quote_conv(p, buf->document_charset);
98 }
99 return body;
100 }
101
102 static void
unloadFrame(struct frame_body * b)103 unloadFrame(struct frame_body *b)
104 {
105 b->attr = F_UNLOADED;
106 }
107
108 void
deleteFrame(struct frame_body * b)109 deleteFrame(struct frame_body *b)
110 {
111 if (b == NULL)
112 return;
113 unloadFrame(b);
114 bzero((void *)b, sizeof(*b));
115 }
116
117 void
addFrameSetElement(struct frameset * f,union frameset_element element)118 addFrameSetElement(struct frameset *f, union frameset_element element)
119 {
120 int i;
121
122 if (f == NULL)
123 return;
124 i = f->i;
125 if (i >= f->col * f->row)
126 return;
127 f->frame[i] = element;
128 f->i++;
129 }
130
131 void
deleteFrameSet(struct frameset * f)132 deleteFrameSet(struct frameset *f)
133 {
134 int i;
135
136 if (f == NULL)
137 return;
138 for (i = 0; i < f->col * f->row; i++) {
139 deleteFrameSetElement(f->frame[i]);
140 }
141 f->name = NULL;
142 f->currentURL = NULL;
143 return;
144 }
145
146 void
deleteFrameSetElement(union frameset_element e)147 deleteFrameSetElement(union frameset_element e)
148 {
149 if (e.element == NULL)
150 return;
151 switch (e.element->attr) {
152 case F_UNLOADED:
153 break;
154 case F_BODY:
155 deleteFrame(e.body);
156 break;
157 case F_FRAMESET:
158 deleteFrameSet(e.set);
159 break;
160 default:
161 break;
162 }
163 return;
164 }
165
166 static struct frame_body *
copyFrame(struct frame_body * ob)167 copyFrame(struct frame_body *ob)
168 {
169 struct frame_body *rb;
170
171 rb = New(struct frame_body);
172 bcopy((const void *)ob, (void *)rb, sizeof(struct frame_body));
173 return rb;
174 }
175
176 struct frameset *
copyFrameSet(struct frameset * of)177 copyFrameSet(struct frameset *of)
178 {
179 struct frameset *rf;
180 int n;
181
182 rf = New(struct frameset);
183 n = of->col * of->row;
184 bcopy((const void *)of, (void *)rf, sizeof(struct frameset));
185 rf->width = New_N(char *, rf->col);
186 bcopy((const void *)of->width,
187 (void *)rf->width, sizeof(char *) * rf->col);
188 rf->height = New_N(char *, rf->row);
189 bcopy((const void *)of->height,
190 (void *)rf->height, sizeof(char *) * rf->row);
191 rf->frame = New_N(union frameset_element, n);
192 while (n) {
193 n--;
194 if (!of->frame[n].element)
195 goto attr_default;
196 switch (of->frame[n].element->attr) {
197 case F_UNLOADED:
198 case F_BODY:
199 rf->frame[n].body = copyFrame(of->frame[n].body);
200 break;
201 case F_FRAMESET:
202 rf->frame[n].set = copyFrameSet(of->frame[n].set);
203 break;
204 default:
205 attr_default:
206 rf->frame[n].element = NULL;
207 break;
208 }
209 }
210 return rf;
211 }
212
213 void
flushFrameSet(struct frameset * fs)214 flushFrameSet(struct frameset *fs)
215 {
216 int n = fs->i;
217
218 while (n) {
219 n--;
220 if (!fs->frame[n].element)
221 goto attr_default;
222 switch (fs->frame[n].element->attr) {
223 case F_UNLOADED:
224 case F_BODY:
225 fs->frame[n].body->nameList = NULL;
226 break;
227 case F_FRAMESET:
228 flushFrameSet(fs->frame[n].set);
229 break;
230 default:
231 attr_default:
232 /* nothing to do */
233 break;
234 }
235 }
236 }
237
238 void
pushFrameTree(struct frameset_queue ** fqpp,struct frameset * fs,Buffer * buf)239 pushFrameTree(struct frameset_queue **fqpp, struct frameset *fs, Buffer *buf)
240 {
241 struct frameset_queue *rfq, *cfq = *fqpp;
242
243 if (!fs)
244 return;
245
246 rfq = New(struct frameset_queue);
247 rfq->linenumber = (buf
248 && buf->currentLine) ? buf->currentLine->linenumber : 1;
249 rfq->top_linenumber = (buf && buf->topLine) ? buf->topLine->linenumber : 1;
250 rfq->pos = buf ? buf->pos : 0;
251 rfq->currentColumn = buf ? buf->currentColumn : 0;
252 rfq->formitem = buf ? buf->formitem : NULL;
253
254 rfq->back = cfq;
255 if (cfq) {
256 rfq->next = cfq->next;
257 if (cfq->next)
258 cfq->next->back = rfq;
259 cfq->next = rfq;
260 }
261 else
262 rfq->next = cfq;
263 rfq->frameset = fs;
264 *fqpp = rfq;
265 return;
266 }
267
268 struct frameset *
popFrameTree(struct frameset_queue ** fqpp)269 popFrameTree(struct frameset_queue **fqpp)
270 {
271 struct frameset_queue *rfq = NULL, *cfq = *fqpp;
272 struct frameset *rfs = NULL;
273
274 if (!cfq)
275 return rfs;
276
277 rfs = cfq->frameset;
278 if (cfq->next) {
279 (rfq = cfq->next)->back = cfq->back;
280 }
281 if (cfq->back) {
282 (rfq = cfq->back)->next = cfq->next;
283 }
284 *fqpp = rfq;
285 bzero((void *)cfq, sizeof(struct frameset_queue));
286 return rfs;
287 }
288
289 void
resetFrameElement(union frameset_element * f_element,Buffer * buf,char * referer,FormList * request)290 resetFrameElement(union frameset_element *f_element,
291 Buffer *buf, char *referer, FormList *request)
292 {
293 char *f_name;
294 struct frame_body *f_body;
295
296 f_name = f_element->element->name;
297 if (buf->frameset) {
298 /* frame cascade */
299 deleteFrameSetElement(*f_element);
300 f_element->set = buf->frameset;
301 f_element->set->currentURL = New(ParsedURL);
302 copyParsedURL(f_element->set->currentURL, &buf->currentURL);
303 buf->frameset = popFrameTree(&(buf->frameQ));
304 f_element->set->name = f_name;
305 }
306 else {
307 f_body = newFrame(NULL, buf);
308 f_body->attr = F_BODY;
309 f_body->name = f_name;
310 f_body->url = parsedURL2Str(&buf->currentURL)->ptr;
311 f_body->source = buf->sourcefile;
312 buf->sourcefile = NULL;
313 if (buf->mailcap_source) {
314 f_body->source = buf->mailcap_source;
315 buf->mailcap_source = NULL;
316 }
317 f_body->type = buf->type;
318 f_body->referer = referer;
319 f_body->request = request;
320 deleteFrameSetElement(*f_element);
321 f_element->body = f_body;
322 }
323 }
324
325 static struct frameset *
frame_download_source(struct frame_body * b,ParsedURL * currentURL,ParsedURL * baseURL,int flag)326 frame_download_source(struct frame_body *b, ParsedURL *currentURL,
327 ParsedURL *baseURL, int flag)
328 {
329 Buffer *buf;
330 struct frameset *ret_frameset = NULL;
331 ParsedURL url;
332
333 if (b == NULL || b->url == NULL || b->url[0] == '\0')
334 return NULL;
335 if (b->baseURL)
336 baseURL = b->baseURL;
337 parseURL2(b->url, &url, currentURL);
338 switch (url.scheme) {
339 case SCM_LOCAL:
340 #if 0
341 b->source = url.real_file;
342 #endif
343 b->flags = 0;
344 default:
345 is_redisplay = TRUE;
346 w3m_dump |= DUMP_FRAME;
347 buf = loadGeneralFile(b->url,
348 baseURL ? baseURL : currentURL,
349 b->referer, flag | RG_FRAME_SRC, b->request);
350 #ifdef USE_SSL
351 /* XXX certificate? */
352 if (buf && buf != NO_BUFFER)
353 b->ssl_certificate = buf->ssl_certificate;
354 #endif
355 w3m_dump &= ~DUMP_FRAME;
356 is_redisplay = FALSE;
357 break;
358 }
359
360 if (buf == NULL || buf == NO_BUFFER) {
361 b->source = NULL;
362 b->flags = (buf == NO_BUFFER) ? FB_NO_BUFFER : 0;
363 return NULL;
364 }
365 b->url = parsedURL2Str(&buf->currentURL)->ptr;
366 b->type = buf->type;
367 b->source = buf->sourcefile;
368 buf->sourcefile = NULL;
369 if (buf->mailcap_source) {
370 b->source = buf->mailcap_source;
371 buf->mailcap_source = NULL;
372 }
373 b->attr = F_BODY;
374 if (buf->frameset) {
375 ret_frameset = buf->frameset;
376 ret_frameset->name = b->name;
377 ret_frameset->currentURL = New(ParsedURL);
378 copyParsedURL(ret_frameset->currentURL, &buf->currentURL);
379 buf->frameset = popFrameTree(&(buf->frameQ));
380 }
381 discardBuffer(buf);
382 return ret_frameset;
383 }
384
385 #define CASE_TABLE_TAG \
386 case HTML_TR:\
387 case HTML_N_TR:\
388 case HTML_TD:\
389 case HTML_N_TD:\
390 case HTML_TH:\
391 case HTML_N_TH:\
392 case HTML_THEAD:\
393 case HTML_N_THEAD:\
394 case HTML_TBODY:\
395 case HTML_N_TBODY:\
396 case HTML_TFOOT:\
397 case HTML_N_TFOOT:\
398 case HTML_COLGROUP:\
399 case HTML_N_COLGROUP:\
400 case HTML_COL
401
402 static int
createFrameFile(struct frameset * f,FILE * f1,Buffer * current,int level,int force_reload)403 createFrameFile(struct frameset *f, FILE * f1, Buffer *current, int level,
404 int force_reload)
405 {
406 int r, c, t_stack;
407 URLFile f2;
408 #ifdef USE_M17N
409 wc_ces charset, doc_charset;
410 #endif
411 char *d_target, *p_target, *s_target, *t_target;
412 ParsedURL *currentURL, base;
413 MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
414 int flag;
415
416 if (f == NULL)
417 return -1;
418
419 if (level == 0) {
420 if (SETJMP(AbortLoading) != 0) {
421 TRAP_OFF;
422 return -1;
423 }
424 TRAP_ON;
425 f->name = "_top";
426 }
427
428 if (level > 7) {
429 fputs("Too many frameset tasked.\n", f1);
430 return -1;
431 }
432
433 if (level == 0) {
434 fprintf(f1, "<html><head><title>%s</title></head><body>\n",
435 html_quote(current->buffername));
436 fputs("<table hborder width=\"100%\">\n", f1);
437 }
438 else
439 fputs("<table hborder>\n", f1);
440
441 currentURL = f->currentURL ? f->currentURL : ¤t->currentURL;
442 for (r = 0; r < f->row; r++) {
443 fputs("<tr valign=top>\n", f1);
444 for (c = 0; c < f->col; c++) {
445 union frameset_element frame;
446 struct frameset *f_frameset;
447 int i = c + r * f->col;
448 char *p = "";
449 int status = R_ST_NORMAL;
450 Str tok = Strnew();
451 int pre_mode = 0;
452 int end_tag = 0;
453
454 frame = f->frame[i];
455
456 if (frame.element == NULL) {
457 fputs("<td>\n</td>\n", f1);
458 continue;
459 }
460
461 fputs("<td", f1);
462 if (frame.element->name)
463 fprintf(f1, " id=\"_%s\"", html_quote(frame.element->name));
464 if (!r)
465 fprintf(f1, " width=\"%s\"", f->width[c]);
466 fputs(">\n", f1);
467
468 flag = 0;
469 if (force_reload) {
470 flag |= RG_NOCACHE;
471 if (frame.element->attr == F_BODY)
472 unloadFrame(frame.body);
473 }
474 switch (frame.element->attr) {
475 default:
476 /* FIXME: gettextize? */
477 fprintf(f1, "Frameset \"%s\" frame %d: type unrecognized",
478 html_quote(f->name), i + 1);
479 break;
480 case F_UNLOADED:
481 if (!frame.body->name && f->name) {
482 frame.body->name = Sprintf("%s_%d", f->name, i)->ptr;
483 }
484 fflush(f1);
485 f_frameset = frame_download_source(frame.body,
486 currentURL,
487 current->baseURL, flag);
488 if (f_frameset) {
489 deleteFrame(frame.body);
490 f->frame[i].set = frame.set = f_frameset;
491 goto render_frameset;
492 }
493 /* fall through */
494 case F_BODY:
495 init_stream(&f2, SCM_LOCAL, NULL);
496 if (frame.body->source) {
497 fflush(f1);
498 examineFile(frame.body->source, &f2);
499 }
500 if (f2.stream == NULL) {
501 frame.body->attr = F_UNLOADED;
502 if (frame.body->flags & FB_NO_BUFFER)
503 /* FIXME: gettextize? */
504 fprintf(f1, "Open %s with other method",
505 html_quote(frame.body->url));
506 else if (frame.body->url)
507 /* FIXME: gettextize? */
508 fprintf(f1, "Can't open %s",
509 html_quote(frame.body->url));
510 else
511 /* FIXME: gettextize? */
512 fprintf(f1,
513 "This frame (%s) contains no src attribute",
514 frame.body->name ? html_quote(frame.body->name)
515 : "(no name)");
516 break;
517 }
518 parseURL2(frame.body->url, &base, currentURL);
519 p_target = f->name;
520 s_target = frame.body->name;
521 t_target = "_blank";
522 d_target = TargetSelf ? s_target : t_target;
523 #ifdef USE_M17N
524 charset = WC_CES_US_ASCII;
525 if (current->document_charset != WC_CES_US_ASCII)
526 doc_charset = current->document_charset;
527 else
528 doc_charset = DocumentCharset;
529 #endif
530 t_stack = 0;
531 if (frame.body->type &&
532 !strcasecmp(frame.body->type, "text/plain")) {
533 Str tmp;
534 fprintf(f1, "<pre>\n");
535 while ((tmp = StrmyUFgets(&f2))->length) {
536 tmp = convertLine(NULL, tmp, HTML_MODE, &charset,
537 doc_charset);
538 fprintf(f1, "%s", html_quote(tmp->ptr));
539 }
540 fprintf(f1, "</pre>\n");
541 UFclose(&f2);
542 break;
543 }
544 do {
545 int is_tag = FALSE;
546 char *q;
547 struct parsed_tag *tag;
548
549 do {
550 if (*p == '\0') {
551 Str tmp = StrmyUFgets(&f2);
552 if (tmp->length == 0)
553 break;
554 tmp = convertLine(NULL, tmp, HTML_MODE, &charset,
555 doc_charset);
556 p = tmp->ptr;
557 }
558 read_token(tok, &p, &status, 1, status != R_ST_NORMAL);
559 } while (status != R_ST_NORMAL);
560
561 if (tok->length == 0)
562 continue;
563
564 if (tok->ptr[0] == '<') {
565 if (tok->ptr[1] &&
566 REALLY_THE_BEGINNING_OF_A_TAG(tok->ptr))
567 is_tag = TRUE;
568 else if (!(pre_mode & (RB_PLAIN | RB_INTXTA |
569 RB_SCRIPT | RB_STYLE))) {
570 p = Strnew_m_charp(tok->ptr + 1, p, NULL)->ptr;
571 tok = Strnew_charp("<");
572 }
573 }
574 if (is_tag) {
575 if (pre_mode & (RB_PLAIN | RB_INTXTA | RB_SCRIPT |
576 RB_STYLE)) {
577 q = tok->ptr;
578 if ((tag = parse_tag(&q, FALSE)) &&
579 tag->tagid == end_tag) {
580 if (pre_mode & RB_PLAIN) {
581 fputs("</PRE_PLAIN>", f1);
582 pre_mode = 0;
583 end_tag = 0;
584 goto token_end;
585 }
586 pre_mode = 0;
587 end_tag = 0;
588 goto proc_normal;
589 }
590 if (strncmp(tok->ptr, "<!--", 4) &&
591 (q = strchr(tok->ptr + 1, '<'))) {
592 tok = Strnew_charp_n(tok->ptr, q - tok->ptr);
593 p = Strnew_m_charp(q, p, NULL)->ptr;
594 status = R_ST_NORMAL;
595 }
596 is_tag = FALSE;
597 }
598 else if (pre_mode & RB_INSELECT) {
599 q = tok->ptr;
600 if ((tag = parse_tag(&q, FALSE))) {
601 if ((tag->tagid == end_tag) ||
602 (tag->tagid == HTML_N_FORM)) {
603 if (tag->tagid == HTML_N_FORM)
604 fputs("</SELECT>", f1);
605 pre_mode = 0;
606 end_tag = 0;
607 goto proc_normal;
608 }
609 if (t_stack) {
610 switch (tag->tagid) {
611 case HTML_TABLE:
612 case HTML_N_TABLE:
613 CASE_TABLE_TAG:
614 fputs("</SELECT>", f1);
615 pre_mode = 0;
616 end_tag = 0;
617 goto proc_normal;
618 }
619 }
620 }
621 }
622 }
623
624 proc_normal:
625 if (is_tag) {
626 char *q = tok->ptr;
627 int j, a_target = 0;
628 ParsedURL url;
629
630 if (!(tag = parse_tag(&q, FALSE)))
631 goto token_end;
632
633 switch (tag->tagid) {
634 case HTML_TITLE:
635 fputs("<!-- title:", f1);
636 goto token_end;
637 case HTML_N_TITLE:
638 fputs("-->", f1);
639 goto token_end;
640 case HTML_BASE:
641 /* "BASE" is prohibit tag */
642 if (parsedtag_get_value(tag, ATTR_HREF, &q)) {
643 q = url_encode(remove_space(q), NULL, charset);
644 parseURL(q, &base, NULL);
645 }
646 if (parsedtag_get_value(tag, ATTR_TARGET, &q)) {
647 if (!strcasecmp(q, "_self"))
648 d_target = s_target;
649 else if (!strcasecmp(q, "_parent"))
650 d_target = p_target;
651 else
652 d_target = url_quote_conv(q, charset);
653 }
654 Strshrinkfirst(tok, 1);
655 Strshrink(tok, 1);
656 fprintf(f1, "<!-- %s -->", html_quote(tok->ptr));
657 goto token_end;
658 case HTML_META:
659 if (parsedtag_get_value(tag, ATTR_HTTP_EQUIV, &q)
660 && !strcasecmp(q, "refresh")) {
661 if (parsedtag_get_value(tag, ATTR_CONTENT, &q)
662 ) {
663 Str s_tmp = NULL;
664 int refresh_interval =
665 getMetaRefreshParam(q, &s_tmp);
666 if (s_tmp) {
667 q = html_quote(s_tmp->ptr);
668 fprintf(f1,
669 "Refresh (%d sec) <a href=\"%s\">%s</a>\n",
670 refresh_interval, q, q);
671 }
672 }
673 }
674 #ifdef USE_M17N
675 if (UseContentCharset &&
676 parsedtag_get_value(tag, ATTR_HTTP_EQUIV, &q)
677 && !strcasecmp(q, "Content-Type")
678 && parsedtag_get_value(tag, ATTR_CONTENT, &q)
679 && (q = strcasestr(q, "charset")) != NULL) {
680 q += 7;
681 SKIP_BLANKS(q);
682 if (*q == '=') {
683 wc_ces c;
684 q++;
685 SKIP_BLANKS(q);
686 if ((c = wc_guess_charset(q, 0)) != 0) {
687 doc_charset = c;
688 charset = WC_CES_US_ASCII;
689 }
690 }
691 }
692 #endif
693 /* fall thru, "META" is prohibit tag */
694 case HTML_HEAD:
695 case HTML_N_HEAD:
696 case HTML_BODY:
697 case HTML_N_BODY:
698 case HTML_DOCTYPE:
699 /* prohibit_tags */
700 Strshrinkfirst(tok, 1);
701 Strshrink(tok, 1);
702 fprintf(f1, "<!-- %s -->", html_quote(tok->ptr));
703 goto token_end;
704 case HTML_TABLE:
705 t_stack++;
706 break;
707 case HTML_N_TABLE:
708 t_stack--;
709 if (t_stack < 0) {
710 t_stack = 0;
711 Strshrinkfirst(tok, 1);
712 Strshrink(tok, 1);
713 fprintf(f1,
714 "<!-- table stack underflow: %s -->",
715 html_quote(tok->ptr));
716 goto token_end;
717 }
718 break;
719 CASE_TABLE_TAG:
720 /* table_tags MUST be in table stack */
721 if (!t_stack) {
722 Strshrinkfirst(tok, 1);
723 Strshrink(tok, 1);
724 fprintf(f1, "<!-- %s -->",
725 html_quote(tok->ptr));
726 goto token_end;
727
728 }
729 break;
730 case HTML_SELECT:
731 pre_mode = RB_INSELECT;
732 end_tag = HTML_N_SELECT;
733 break;
734 case HTML_TEXTAREA:
735 pre_mode = RB_INTXTA;
736 end_tag = HTML_N_TEXTAREA;
737 break;
738 case HTML_SCRIPT:
739 pre_mode = RB_SCRIPT;
740 end_tag = HTML_N_SCRIPT;
741 break;
742 case HTML_STYLE:
743 pre_mode = RB_STYLE;
744 end_tag = HTML_N_STYLE;
745 break;
746 case HTML_LISTING:
747 pre_mode = RB_PLAIN;
748 end_tag = HTML_N_LISTING;
749 fputs("<PRE_PLAIN>", f1);
750 goto token_end;
751 case HTML_XMP:
752 pre_mode = RB_PLAIN;
753 end_tag = HTML_N_XMP;
754 fputs("<PRE_PLAIN>", f1);
755 goto token_end;
756 case HTML_PLAINTEXT:
757 pre_mode = RB_PLAIN;
758 end_tag = MAX_HTMLTAG;
759 fputs("<PRE_PLAIN>", f1);
760 goto token_end;
761 default:
762 break;
763 }
764 for (j = 0; j < TagMAP[tag->tagid].max_attribute; j++) {
765 switch (tag->attrid[j]) {
766 case ATTR_SRC:
767 case ATTR_HREF:
768 case ATTR_ACTION:
769 if (!tag->value[j])
770 break;
771 tag->value[j] =
772 url_encode(remove_space(tag->value[j]),
773 &base, charset);
774 tag->need_reconstruct = TRUE;
775 parseURL2(tag->value[j], &url, &base);
776 if (url.scheme == SCM_UNKNOWN ||
777 #ifndef USE_W3MMAILER
778 url.scheme == SCM_MAILTO ||
779 #endif
780 url.scheme == SCM_MISSING)
781 break;
782 a_target |= 1;
783 tag->value[j] = parsedURL2Str(&url)->ptr;
784 parsedtag_set_value(tag,
785 ATTR_REFERER,
786 parsedURL2Str(&base)->ptr);
787 #ifdef USE_M17N
788 if (tag->attrid[j] == ATTR_ACTION &&
789 charset != WC_CES_US_ASCII)
790 parsedtag_set_value(tag,
791 ATTR_CHARSET,
792 wc_ces_to_charset
793 (charset));
794 #endif
795 break;
796 case ATTR_TARGET:
797 if (!tag->value[j])
798 break;
799 a_target |= 2;
800 if (!strcasecmp(tag->value[j], "_self")) {
801 parsedtag_set_value(tag,
802 ATTR_TARGET, s_target);
803 }
804 else if (!strcasecmp(tag->value[j], "_parent")) {
805 parsedtag_set_value(tag,
806 ATTR_TARGET, p_target);
807 }
808 break;
809 case ATTR_NAME:
810 case ATTR_ID:
811 if (!tag->value[j])
812 break;
813 parsedtag_set_value(tag,
814 ATTR_FRAMENAME, s_target);
815 break;
816 }
817 }
818 if (a_target == 1) {
819 /* there is HREF attribute and no TARGET
820 * attribute */
821 parsedtag_set_value(tag, ATTR_TARGET, d_target);
822 }
823 if (parsedtag_need_reconstruct(tag))
824 tok = parsedtag2str(tag);
825 Strfputs(tok, f1);
826 }
827 else {
828 if (pre_mode & RB_PLAIN)
829 fprintf(f1, "%s", html_quote(tok->ptr));
830 else if (pre_mode & RB_INTXTA)
831 fprintf(f1, "%s",
832 html_quote(html_unquote(tok->ptr)));
833 else
834 Strfputs(tok, f1);
835 }
836 token_end:
837 Strclear(tok);
838 } while (*p != '\0' || !iseos(f2.stream));
839 if (pre_mode & RB_PLAIN)
840 fputs("</PRE_PLAIN>\n", f1);
841 else if (pre_mode & RB_INTXTA)
842 fputs("</TEXTAREA></FORM>\n", f1);
843 else if (pre_mode & RB_INSELECT)
844 fputs("</SELECT></FORM>\n", f1);
845 else if (pre_mode & (RB_SCRIPT | RB_STYLE)) {
846 if (status != R_ST_NORMAL)
847 fputs(correct_irrtag(status)->ptr, f1);
848 if (pre_mode & RB_SCRIPT)
849 fputs("</SCRIPT>\n", f1);
850 else if (pre_mode & RB_STYLE)
851 fputs("</STYLE>\n", f1);
852 }
853 while (t_stack--)
854 fputs("</TABLE>\n", f1);
855 UFclose(&f2);
856 break;
857 case F_FRAMESET:
858 render_frameset:
859 if (!frame.set->name && f->name) {
860 frame.set->name = Sprintf("%s_%d", f->name, i)->ptr;
861 }
862 createFrameFile(frame.set, f1, current, level + 1,
863 force_reload);
864 break;
865 }
866 fputs("</td>\n", f1);
867 }
868 fputs("</tr>\n", f1);
869 }
870
871 fputs("</table>\n", f1);
872 if (level == 0) {
873 fputs("</body></html>\n", f1);
874 TRAP_OFF;
875 }
876 return 0;
877 }
878
879 Buffer *
renderFrame(Buffer * Cbuf,int force_reload)880 renderFrame(Buffer *Cbuf, int force_reload)
881 {
882 Str tmp;
883 FILE *f;
884 Buffer *buf;
885 int flag;
886 struct frameset *fset;
887 #ifdef USE_M17N
888 wc_ces doc_charset = DocumentCharset;
889 #endif
890
891 tmp = tmpfname(TMPF_FRAME, ".html");
892 f = fopen(tmp->ptr, "w");
893 if (f == NULL)
894 return NULL;
895 /*
896 * if (Cbuf->frameQ != NULL) fset = Cbuf->frameQ->frameset; else */
897 fset = Cbuf->frameset;
898 if (fset == NULL || createFrameFile(fset, f, Cbuf, 0, force_reload) < 0) {
899 fclose(f);
900 return NULL;
901 }
902 fclose(f);
903 flag = RG_FRAME;
904 if ((Cbuf->currentURL).is_nocache)
905 flag |= RG_NOCACHE;
906 renderFrameSet = Cbuf->frameset;
907 flushFrameSet(renderFrameSet);
908 #ifdef USE_M17N
909 DocumentCharset = InnerCharset;
910 #endif
911 buf = loadGeneralFile(tmp->ptr, NULL, NULL, flag, NULL);
912 #ifdef USE_M17N
913 DocumentCharset = doc_charset;
914 #endif
915 renderFrameSet = NULL;
916 if (buf == NULL || buf == NO_BUFFER)
917 return NULL;
918 buf->sourcefile = tmp->ptr;
919 #ifdef USE_M17N
920 buf->document_charset = Cbuf->document_charset;
921 #endif
922 copyParsedURL(&buf->currentURL, &Cbuf->currentURL);
923 preFormUpdateBuffer(buf);
924 return buf;
925 }
926
927 union frameset_element *
search_frame(struct frameset * fset,char * name)928 search_frame(struct frameset *fset, char *name)
929 {
930 int i;
931 union frameset_element *e = NULL;
932
933 for (i = 0; i < fset->col * fset->row; i++) {
934 e = &(fset->frame[i]);
935 if (e->element != NULL) {
936 if (e->element->name && !strcmp(e->element->name, name)) {
937 return e;
938 }
939 else if (e->element->attr == F_FRAMESET &&
940 (e = search_frame(e->set, name))) {
941 return e;
942 }
943 }
944 }
945 return NULL;
946 }
947