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