struct parsed_tagarg * cgistr2tagarg(char *cgistr) { Str tag; Str value; struct parsed_tagarg *t0, *t; t = t0 = NULL; do { t = New(struct parsed_tagarg); t->next = t0; t0 = t; tag = Strnew(); while (*cgistr && *cgistr != '=' && *cgistr != '&') Strcat_char(tag, *cgistr++); t->arg = Str_form_unquote(tag)->ptr; t->value = NULL; if (*cgistr == '\0') return t; else if (*cgistr == '=') { cgistr++; value = Strnew(); while (*cgistr && *cgistr != '&') Strcat_char(value, *cgistr++); t->value = Str_form_unquote(value)->ptr; } else if (*cgistr == '&') cgistr++; } while (*cgistr); return t; }
int getCharSize() { FILE *f; Str tmp; int w = 0, h = 0; set_environ("W3M_TTY", ttyname_tty()); tmp = Strnew(); if (!strchr(Imgdisplay, '/')) Strcat_m_charp(tmp, w3m_auxbin_dir(), "/", NULL); Strcat_m_charp(tmp, Imgdisplay, " -test 2>/dev/null", NULL); f = popen(tmp->ptr, "r"); if (!f) return FALSE; while (fscanf(f, "%d %d", &w, &h) < 0) { if (feof(f)) break; } pclose(f); if (!(w > 0 && h > 0)) return FALSE; if (!set_pixel_per_char) pixel_per_char = (int)(1.0 * w / COLS + 0.5); if (!set_pixel_per_line) pixel_per_line = (int)(1.0 * h / LINES + 0.5); return TRUE; }
static void interpret_rc(FILE * f) { Str line; Str tmp; char *p; for (;;) { line = Strfgets(f); Strchop(line); if (line->length == 0) break; Strremovefirstspaces(line); if (line->ptr[0] == '#') /* comment */ continue; tmp = Strnew(); p = line->ptr; while (*p && !IS_SPACE(*p)) Strcat_char(tmp, *p++); while (*p && IS_SPACE(*p)) p++; Strlower(tmp); set_param(tmp->ptr, p); } }
int set_param_option(char *option) { Str tmp = Strnew(); char *p = option, *q; while (*p && !IS_SPACE(*p) && *p != '=') Strcat_char(tmp, *p++); while (*p && IS_SPACE(*p)) p++; if (*p == '=') { p++; while (*p && IS_SPACE(*p)) p++; } Strlower(tmp); if (set_param(tmp->ptr, p)) goto option_assigned; q = tmp->ptr; if (!strncmp(q, "no", 2)) { /* -o noxxx, -o no-xxx, -o no_xxx */ q += 2; if (*q == '-' || *q == '_') q++; } else if (tmp->ptr[0] == '-') /* -o -xxx */ q++; else return 0; if (set_param(q, "0")) goto option_assigned; return 0; option_assigned: return 1; }
TextLine * newTextLine(Str line, int pos) { TextLine *lbuf = New(TextLine); if (line) lbuf->line = line; else lbuf->line = Strnew(); lbuf->pos = pos; return lbuf; }
Str find_cookie(ParsedURL *pu) { Str tmp; struct cookie *p, *p1, *fco = NULL; int version = 0; char *fq_domainname, *domainname; dump(Strnew_charp("GET")); load_cookies_sync(); fq_domainname = FQDN(pu->host); check_expired_cookies(); for (p = First_cookie; p; p = p->next) { domainname = (p->version == 0) ? fq_domainname : pu->host; if (p->flag & COO_USE && match_cookie(pu, p, domainname)) { for (p1 = fco; p1 && Strcasecmp(p1->name, p->name); p1 = p1->next) ; if (p1) continue; p1 = New(struct cookie); bcopy(p, p1, sizeof(struct cookie)); p1->next = fco; fco = p1; if (p1->version > version) version = p1->version; } } if (!fco) return NULL; tmp = Strnew(); if (version > 0) Strcat(tmp, Sprintf("$Version=\"%d\"; ", version)); Strcat(tmp, make_cookie(fco)); for (p1 = fco->next; p1; p1 = p1->next) { Strcat_charp(tmp, "; "); Strcat(tmp, make_cookie(p1)); if (version > 0) { if (p1->flag & COO_PATH) Strcat(tmp, Sprintf("; $Path=\"%s\"", p1->path->ptr)); if (p1->flag & COO_DOMAIN) Strcat(tmp, Sprintf("; $Domain=\"%s\"", p1->domain->ptr)); if (p1->portl) Strcat(tmp, Sprintf("; $Port=\"%s\"", portlist2str(p1->portl))); } } return tmp; }
Str Strnew_m_charp(char *p, ...) { va_list ap; Str r = Strnew(); va_start(ap, p); while (p != NULL) { Strcat_charp(r, p); p = va_arg(ap, char *); } return r; }
Str Strsubstr(Str s, int beg, int len) { Str new_s; int i; STR_LENGTH_CHECK(s); new_s = Strnew(); if (beg >= s->length) return new_s; for (i = 0; i < len && beg + i < s->length; i++) Strcat_char(new_s, s->ptr[beg + i]); return new_s; }
Str StrmyISgets(InputStream stream) { BaseStream base; StreamBuffer sb; Str s = NULL; int i, len; if (stream == NULL) return '\0'; base = &stream->base; sb = &base->stream; while (!base->iseos) { if (MUST_BE_UPDATED(base)) { do_update(base); } else { if (s && Strlastchar(s) == '\r') { if (sb->buf[sb->cur] == '\n') Strcat_char(s, (char)sb->buf[sb->cur++]); return s; } for (i = sb->cur; i < sb->next && sb->buf[i] != '\n' && sb->buf[i] != '\r'; i++) ; if (i < sb->next) { len = i - sb->cur + 1; if (s == NULL) s = Strnew_size(len + MARGIN_STR_SIZE); Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len); sb->cur = i + 1; if (sb->buf[i] == '\n') return s; } else { if (s == NULL) s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE); Strcat_charp_n(s, (char *)&sb->buf[sb->cur], sb->next - sb->cur); sb->cur = sb->next; } } } if (s == NULL) return Strnew(); return s; }
Str loadLocalDir(char *dname) { Str tmp; DIR *d; Directory *dir; struct stat st; char **flist; char *p, *qdir; Str fbuf = Strnew(); #ifdef HAVE_LSTAT struct stat lst; #ifdef HAVE_READLINK char lbuf[1024]; #endif /* HAVE_READLINK */ #endif /* HAVE_LSTAT */ int i, l, nrow = 0, n = 0, maxlen = 0; int nfile, nfile_max = 100; Str dirname; d = opendir(dname); if (d == NULL) return NULL; dirname = Strnew_charp(dname); if (Strlastchar(dirname) != '/') Strcat_char(dirname, '/'); qdir = html_quote(Str_conv_from_system(dirname)->ptr); /* FIXME: gettextize? */ tmp = Strnew_m_charp("<HTML>\n<HEAD>\n<BASE HREF=\"file://", html_quote(file_quote(dirname->ptr)), "\">\n<TITLE>Directory list of ", qdir, "</TITLE>\n</HEAD>\n<BODY>\n<H1>Directory list of ", qdir, "</H1>\n", NULL); flist = New_N(char *, nfile_max); nfile = 0; while ((dir = readdir(d)) != NULL) { flist[nfile++] = allocStr(dir->d_name, -1); if (nfile == nfile_max) { nfile_max *= 2; flist = New_Reuse(char *, flist, nfile_max); } if (multicolList) { l = strlen(dir->d_name); if (l > maxlen) maxlen = l; n++; } }
Str Strnew_charp(char *p) { Str x; int n; if (p == NULL) return Strnew(); x = GC_MALLOC(sizeof(struct _Str)); n = strlen(p) + 1; x->ptr = GC_MALLOC_ATOMIC(n); x->area_size = n; x->length = n - 1; bcopy((void *)p, (void *)x->ptr, n); return x; }
char * form2str(FormItemList *fi) { Str tmp = Strnew(); if (fi->type != FORM_SELECT && fi->type != FORM_TEXTAREA) Strcat_charp(tmp, "input type="); Strcat_charp(tmp, _formtypetbl[fi->type]); if (fi->name && fi->name->length) Strcat_m_charp(tmp, " name=\"", fi->name->ptr, "\"", NULL); if ((fi->type == FORM_INPUT_RADIO || fi->type == FORM_INPUT_CHECKBOX || fi->type == FORM_SELECT) && fi->value) Strcat_m_charp(tmp, " value=\"", fi->value->ptr, "\"", NULL); Strcat_m_charp(tmp, " (", _formmethodtbl[fi->parent->method], " ", fi->parent->action->ptr, ")", NULL); return tmp->ptr; }
char * acceptableMimeTypes() { static Str types = NULL; TextList *l; Hash_si *mhash; char *p; int i; if (types != NULL) return types->ptr; /* generate acceptable media types */ l = newTextList(); mhash = newHash_si(16); /* XXX */ /* pushText(l, "text"); */ putHash_si(mhash, "text", 1); pushText(l, "image"); putHash_si(mhash, "image", 1); for (i = 0; i < mailcap_list->nitem; i++) { struct mailcap *mp = UserMailcap[i]; char *mt; if (mp == NULL) continue; for (; mp->type; mp++) { p = strchr(mp->type, '/'); if (p == NULL) continue; mt = allocStr(mp->type, p - mp->type); if (getHash_si(mhash, mt, 0) == 0) { pushText(l, mt); putHash_si(mhash, mt, 1); } } } types = Strnew(); Strcat_charp(types, "text/html, text/*;q=0.5"); while ((p = popText(l)) != NULL) { Strcat_charp(types, ", "); Strcat_charp(types, p); Strcat_charp(types, "/*"); } return types->ptr; }
Str StrISgets(InputStream stream) { BaseStream base; StreamBuffer sb; Str s = NULL; uchar *p; int len; if (stream == NULL) return '\0'; base = &stream->base; sb = &base->stream; while (!base->iseos) { if (MUST_BE_UPDATED(base)) { do_update(base); } else { if ((p = memchr(&sb->buf[sb->cur], '\n', sb->next - sb->cur))) { len = p - &sb->buf[sb->cur] + 1; if (s == NULL) s = Strnew_size(len); Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len); sb->cur += len; return s; } else { if (s == NULL) s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE); Strcat_charp_n(s, (char *)&sb->buf[sb->cur], sb->next - sb->cur); sb->cur = sb->next; } } } if (s == NULL) return Strnew(); return s; }
Str quote_mailcap(char *s, int flag) { Str d; d = Strnew(); for (;; ++s) switch (*s) { case '\0': goto end; case '$': case '`': case '"': case '\\': if (!(flag & MCF_SQUOTED)) Strcat_char(d, '\\'); Strcat_char(d, *s); break; case '\'': if (flag & MCF_SQUOTED) { Strcat_charp(d, "'\\''"); break; } default: if (!flag && !IS_ALNUM(*s)) Strcat_char(d, '\\'); case '_': case '.': case ':': case '/': Strcat_char(d, *s); break; } end: return d; }
static struct portlist * make_portlist(Str port) { struct portlist *first = NULL, *pl; char *p; Str tmp = Strnew(); p = port->ptr; while (*p) { while (*p && !IS_DIGIT(*p)) p++; Strclear(tmp); while (*p && IS_DIGIT(*p)) Strcat_char(tmp, *(p++)); if (tmp->length == 0) break; pl = New(struct portlist); pl->port = atoi(tmp->ptr); pl->next = first; first = pl; } return first; }
static bool matchMailcapAttr(char *p, char *attr, size_t len, Str *value) { bool quoted = false; char *q = NULL; if (strncasecmp(p, attr, len) == 0) { p += len; SKIP_BLANKS(p); if (value) { *value = Strnew(); if (*p == '=') { p++; SKIP_BLANKS(p); while (*p && (quoted || *p != ';')) { if (quoted || !IS_SPACE(*p)) q = p; if (quoted) quoted = false; else if (*p == '\\') quoted = true; Strcat_char(*value, *p); p++; } if (q) Strshrink(*value, p - q - 1); } return true; } else { if (*p == '\0' || *p == ';') { return true; } } } return false; }
static Str unquote_mailcap_loop(char *qstr, char *type, char *name, char *attr, int *mc_stat, int flag0) { Str str, tmp, test, then; char *p; int status = MC_NORMAL, prev_status = MC_NORMAL, sp = 0, flag; if (mc_stat) *mc_stat = 0; if (qstr == NULL) return NULL; str = Strnew(); tmp = test = then = NULL; for (flag = flag0, p = qstr; *p; p++) { if (status == MC_QUOTED) { if (prev_status == MC_PREC2) Strcat_char(tmp, *p); else Strcat_char(str, *p); status = prev_status; continue; } else if (*p == '\\') { prev_status = status; status = MC_QUOTED; continue; } switch (status) { case MC_NORMAL: if (*p == '%') { status = MC_PREC; } else { if (*p == '\'') { if (!flag0 && flag & MCF_SQUOTED) flag &= ~MCF_SQUOTED; else if (!flag) flag |= MCF_SQUOTED; } else if (*p == '"') { if (!flag0 && flag & MCF_DQUOTED) flag &= ~MCF_DQUOTED; else if (!flag) flag |= MCF_DQUOTED; } Strcat_char(str, *p); } break; case MC_PREC: if (IS_ALPHA(*p)) { switch (*p) { case 's': if (name) { Strcat_charp(str, quote_mailcap(name, flag)->ptr); if (mc_stat) *mc_stat |= MCSTAT_REPNAME; } break; case 't': if (type) { Strcat_charp(str, quote_mailcap(type, flag)->ptr); if (mc_stat) *mc_stat |= MCSTAT_REPTYPE; } break; } status = MC_NORMAL; } else if (*p == '{') { status = MC_PREC2; test = then = NULL; tmp = Strnew(); } else if (*p == '%') { Strcat_char(str, *p); } break; case MC_PREC2: if (sp > 0 || *p == '{') { Strcat_char(tmp, *p); switch (*p) { case '{': ++sp; break; case '}': --sp; break; default: break; } } else if (*p == '}') { char *q; if (attr && (q = strcasestr(attr, tmp->ptr)) != NULL && (q == attr || IS_SPACE(*(q - 1)) || *(q - 1) == ';') && matchattr(q, tmp->ptr, tmp->length, &tmp)) { Strcat_charp(str, quote_mailcap(tmp->ptr, flag)->ptr); if (mc_stat) *mc_stat |= MCSTAT_REPPARAM; } status = MC_NORMAL; } else { Strcat_char(tmp, *p); } break; } } return str; }
char * inputLineHistSearch(char *prompt, char *def_str, int flag, Hist *hist, int (*incrfunc) (int ch, Str str, Lineprop *prop)) { int opos, x, y, lpos, rpos, epos; unsigned char c; char *p; #ifdef USE_M17N Str tmp; #endif is_passwd = FALSE; move_word = TRUE; CurrentHist = hist; if (hist != NULL) { use_hist = TRUE; strCurrentBuf = NULL; } else { use_hist = FALSE; } if (flag & IN_URL) { cm_mode = CPL_ALWAYS | CPL_URL; } else if (flag & IN_FILENAME) { cm_mode = CPL_ALWAYS; } else if (flag & IN_PASSWORD) { cm_mode = CPL_NEVER; is_passwd = TRUE; move_word = FALSE; } else if (flag & IN_COMMAND) cm_mode = CPL_ON; else cm_mode = CPL_OFF; opos = get_strwidth(prompt); epos = CLEN - opos; if (epos < 0) epos = 0; lpos = epos / 3; rpos = epos * 2 / 3; offset = 0; if (def_str) { strBuf = Strnew_charp(def_str); CLen = CPos = setStrType(strBuf, strProp); } else { strBuf = Strnew(); CLen = CPos = 0; } #ifdef SUPPORT_WIN9X_CONSOLE_MBCS enable_win9x_console_input(); #endif i_cont = TRUE; i_broken = FALSE; i_quote = FALSE; cm_next = FALSE; cm_disp_next = -1; need_redraw = FALSE; #ifdef USE_M17N wc_char_conv_init(wc_guess_8bit_charset(DisplayCharset), InnerCharset); #endif do { x = calcPosition(strBuf->ptr, strProp, CLen, CPos, 0, CP_FORCE); if (x - rpos > offset) { y = calcPosition(strBuf->ptr, strProp, CLen, CLen, 0, CP_AUTO); if (y - epos > x - rpos) offset = x - rpos; else if (y - epos > 0) offset = y - epos; } else if (x - lpos < offset) { if (x - lpos > 0) offset = x - lpos; else offset = 0; } move(LASTLINE, 0); addstr(prompt); if (is_passwd) addPasswd(strBuf->ptr, strProp, CLen, offset, COLS - opos); else addStr(strBuf->ptr, strProp, CLen, offset, COLS - opos); clrtoeolx(); move(LASTLINE, opos + x - offset); refresh(); next_char: c = getch(); #ifdef __EMX__ if (c == 0) { if (!(c = getcntrl())) goto next_char; } #endif cm_clear = TRUE; cm_disp_clear = TRUE; if (!i_quote && (((cm_mode & CPL_ALWAYS) && (c == CTRL_I || c == ' ')) || ((cm_mode & CPL_ON) && (c == CTRL_I)))) { if (emacs_like_lineedit && cm_next) { _dcompl(); need_redraw = TRUE; } else { _compl(); cm_disp_next = -1; } } else if (!i_quote && CLen == CPos && (cm_mode & CPL_ALWAYS || cm_mode & CPL_ON) && c == CTRL_D) { if (!emacs_like_lineedit) { _dcompl(); need_redraw = TRUE; } } else if (!i_quote && c == DEL_CODE) { _bs(); cm_next = FALSE; cm_disp_next = -1; } else if (!i_quote && c < 0x20) { /* Control code */ if (incrfunc == NULL || (c = incrfunc((int)c, strBuf, strProp)) < 0x20) (*InputKeymap[(int)c]) (c); if (incrfunc && c != (unsigned char)-1 && c != CTRL_J) incrfunc(-1, strBuf, strProp); if (cm_clear) cm_next = FALSE; if (cm_disp_clear) cm_disp_next = -1; } #ifdef USE_M17N else { tmp = wc_char_conv(c); if (tmp == NULL) { i_quote = TRUE; goto next_char; } i_quote = FALSE; cm_next = FALSE; cm_disp_next = -1; if (CLen + tmp->length > STR_LEN || !tmp->length) goto next_char; ins_char(tmp); if (incrfunc) incrfunc(-1, strBuf, strProp); } #else else { i_quote = FALSE; cm_next = FALSE; cm_disp_next = -1; if (CLen >= STR_LEN) goto next_char; insC(); strBuf->ptr[CPos] = c; if (!is_passwd && get_mctype(&c) == PC_CTRL) strProp[CPos] = PC_CTRL; else strProp[CPos] = PC_ASCII; CPos++; if (incrfunc) incrfunc(-1, strBuf, strProp); } #endif if (CLen && (flag & IN_CHAR)) break; } while (i_cont);
static Str ssl_check_cert_ident(X509 * x, char *hostname) { int i; Str ret = NULL; int match_ident = FALSE; /* * All we need to do here is check that the CN matches. * * From RFC2818 3.1 Server Identity: * If a subjectAltName extension of type dNSName is present, that MUST * be used as the identity. Otherwise, the (most specific) Common Name * field in the Subject field of the certificate MUST be used. Although * the use of the Common Name is existing practice, it is deprecated and * Certification Authorities are encouraged to use the dNSName instead. */ i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); if (i >= 0) { X509_EXTENSION *ex; STACK_OF(GENERAL_NAME) * alt; ex = X509_get_ext(x, i); alt = X509V3_EXT_d2i(ex); if (alt) { int n; GENERAL_NAME *gn; X509V3_EXT_METHOD *method; Str seen_dnsname = NULL; n = sk_GENERAL_NAME_num(alt); for (i = 0; i < n; i++) { gn = sk_GENERAL_NAME_value(alt, i); if (gn->type == GEN_DNS) { char *sn = ASN1_STRING_data(gn->d.ia5); int sl = ASN1_STRING_length(gn->d.ia5); if (!seen_dnsname) seen_dnsname = Strnew(); /* replace \0 to make full string visible to user */ if (sl != strlen(sn)) { int i; for (i = 0; i < sl; ++i) { if (!sn[i]) sn[i] = '!'; } } Strcat_m_charp(seen_dnsname, sn, " ", NULL); if (sl == strlen(sn) /* catch \0 in SAN */ && ssl_match_cert_ident(sn, sl, hostname)) break; } } method = X509V3_EXT_get(ex); sk_GENERAL_NAME_free(alt); if (i < n) /* Found a match */ match_ident = TRUE; else if (seen_dnsname) /* FIXME: gettextize? */ ret = Sprintf("Bad cert ident from %s: dNSName=%s", hostname, seen_dnsname->ptr); } } if (match_ident == FALSE && ret == NULL) { X509_NAME *xn; char buf[2048]; int slen; xn = X509_get_subject_name(x); slen = X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)); if ( slen == -1) /* FIXME: gettextize? */ ret = Strnew_charp("Unable to get common name from peer cert"); else if (slen != strlen(buf) || !ssl_match_cert_ident(buf, strlen(buf), hostname)) { /* replace \0 to make full string visible to user */ if (slen != strlen(buf)) { int i; for (i = 0; i < slen; ++i) { if (!buf[i]) buf[i] = '!'; } } /* FIXME: gettextize? */ ret = Sprintf("Bad cert ident %s from %s", buf, hostname); } else match_ident = TRUE; } return ret; }
static int createFrameFile(struct frameset *f, FILE * f1, Buffer *current, int level, int force_reload) { int r, c, t_stack; URLFile f2; #ifdef USE_M17N wc_ces charset, doc_charset; #endif char *d_target, *p_target, *s_target, *t_target; ParsedURL *currentURL, base; MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; int flag; if (f == NULL) return -1; if (level == 0) { if (SETJMP(AbortLoading) != 0) { TRAP_OFF; return -1; } TRAP_ON; f->name = "_top"; } if (level > 7) { fputs("Too many frameset tasked.\n", f1); return -1; } if (level == 0) { fprintf(f1, "<html><head><title>%s</title></head><body>\n", html_quote(current->buffername)); fputs("<table hborder width=\"100%\">\n", f1); } else fputs("<table hborder>\n", f1); currentURL = f->currentURL ? f->currentURL : ¤t->currentURL; for (r = 0; r < f->row; r++) { fputs("<tr valign=top>\n", f1); for (c = 0; c < f->col; c++) { union frameset_element frame; struct frameset *f_frameset; int i = c + r * f->col; char *p = ""; int status = R_ST_NORMAL; Str tok = Strnew(); int pre_mode = 0; int end_tag = 0; frame = f->frame[i]; if (frame.element == NULL) { fputs("<td>\n</td>\n", f1); continue; } fputs("<td", f1); if (frame.element->name) fprintf(f1, " id=\"_%s\"", html_quote(frame.element->name)); if (!r) fprintf(f1, " width=\"%s\"", f->width[c]); fputs(">\n", f1); flag = 0; if (force_reload) { flag |= RG_NOCACHE; if (frame.element->attr == F_BODY) unloadFrame(frame.body); } switch (frame.element->attr) { default: /* FIXME: gettextize? */ fprintf(f1, "Frameset \"%s\" frame %d: type unrecognized", html_quote(f->name), i + 1); break; case F_UNLOADED: if (!frame.body->name && f->name) { frame.body->name = Sprintf("%s_%d", f->name, i)->ptr; } fflush(f1); f_frameset = frame_download_source(frame.body, currentURL, current->baseURL, flag); if (f_frameset) { deleteFrame(frame.body); f->frame[i].set = frame.set = f_frameset; goto render_frameset; } /* fall through */ case F_BODY: init_stream(&f2, SCM_LOCAL, NULL); if (frame.body->source) { fflush(f1); examineFile(frame.body->source, &f2); } if (f2.stream == NULL) { frame.body->attr = F_UNLOADED; if (frame.body->flags & FB_NO_BUFFER) /* FIXME: gettextize? */ fprintf(f1, "Open %s with other method", html_quote(frame.body->url)); else if (frame.body->url) /* FIXME: gettextize? */ fprintf(f1, "Can't open %s", html_quote(frame.body->url)); else /* FIXME: gettextize? */ fprintf(f1, "This frame (%s) contains no src attribute", frame.body->name ? html_quote(frame.body->name) : "(no name)"); break; } parseURL2(frame.body->url, &base, currentURL); p_target = f->name; s_target = frame.body->name; t_target = "_blank"; d_target = TargetSelf ? s_target : t_target; #ifdef USE_M17N charset = WC_CES_US_ASCII; if (current->document_charset != WC_CES_US_ASCII) doc_charset = current->document_charset; else doc_charset = DocumentCharset; #endif t_stack = 0; if (frame.body->type && !strcasecmp(frame.body->type, "text/plain")) { Str tmp; fprintf(f1, "<pre>\n"); while ((tmp = StrmyUFgets(&f2))->length) { tmp = convertLine(NULL, tmp, HTML_MODE, &charset, doc_charset); fprintf(f1, "%s", html_quote(tmp->ptr)); } fprintf(f1, "</pre>\n"); UFclose(&f2); break; } do { int is_tag = FALSE; char *q; struct parsed_tag *tag; do { if (*p == '\0') { Str tmp = StrmyUFgets(&f2); if (tmp->length == 0) break; tmp = convertLine(NULL, tmp, HTML_MODE, &charset, doc_charset); p = tmp->ptr; } read_token(tok, &p, &status, 1, status != R_ST_NORMAL); } while (status != R_ST_NORMAL); if (tok->length == 0) continue; if (tok->ptr[0] == '<') { if (tok->ptr[1] && REALLY_THE_BEGINNING_OF_A_TAG(tok->ptr)) is_tag = TRUE; else if (!(pre_mode & (RB_PLAIN | RB_INTXTA | RB_SCRIPT | RB_STYLE))) { p = Strnew_m_charp(tok->ptr + 1, p, NULL)->ptr; tok = Strnew_charp("<"); } } if (is_tag) { if (pre_mode & (RB_PLAIN | RB_INTXTA | RB_SCRIPT | RB_STYLE)) { q = tok->ptr; if ((tag = parse_tag(&q, FALSE)) && tag->tagid == end_tag) { if (pre_mode & RB_PLAIN) { fputs("</PRE_PLAIN>", f1); pre_mode = 0; end_tag = 0; goto token_end; } pre_mode = 0; end_tag = 0; goto proc_normal; } if (strncmp(tok->ptr, "<!--", 4) && (q = strchr(tok->ptr + 1, '<'))) { tok = Strnew_charp_n(tok->ptr, q - tok->ptr); p = Strnew_m_charp(q, p, NULL)->ptr; status = R_ST_NORMAL; } is_tag = FALSE; } else if (pre_mode & RB_INSELECT) { q = tok->ptr; if ((tag = parse_tag(&q, FALSE))) { if ((tag->tagid == end_tag) || (tag->tagid == HTML_N_FORM)) { if (tag->tagid == HTML_N_FORM) fputs("</SELECT>", f1); pre_mode = 0; end_tag = 0; goto proc_normal; } if (t_stack) { switch (tag->tagid) { case HTML_TABLE: case HTML_N_TABLE: CASE_TABLE_TAG: fputs("</SELECT>", f1); pre_mode = 0; end_tag = 0; goto proc_normal; } } } } } proc_normal: if (is_tag) { char *q = tok->ptr; int j, a_target = 0; ParsedURL url; if (!(tag = parse_tag(&q, FALSE))) goto token_end; switch (tag->tagid) { case HTML_TITLE: fputs("<!-- title:", f1); goto token_end; case HTML_N_TITLE: fputs("-->", f1); goto token_end; case HTML_BASE: /* "BASE" is prohibit tag */ if (parsedtag_get_value(tag, ATTR_HREF, &q)) { q = url_encode(remove_space(q), NULL, charset); parseURL(q, &base, NULL); } if (parsedtag_get_value(tag, ATTR_TARGET, &q)) { if (!strcasecmp(q, "_self")) d_target = s_target; else if (!strcasecmp(q, "_parent")) d_target = p_target; else d_target = url_quote_conv(q, charset); } Strshrinkfirst(tok, 1); Strshrink(tok, 1); fprintf(f1, "<!-- %s -->", html_quote(tok->ptr)); goto token_end; case HTML_META: if (parsedtag_get_value(tag, ATTR_HTTP_EQUIV, &q) && !strcasecmp(q, "refresh")) { if (parsedtag_get_value(tag, ATTR_CONTENT, &q) ) { Str s_tmp = NULL; int refresh_interval = getMetaRefreshParam(q, &s_tmp); if (s_tmp) { q = html_quote(s_tmp->ptr); fprintf(f1, "Refresh (%d sec) <a href=\"%s\">%s</a>\n", refresh_interval, q, q); } } } #ifdef USE_M17N if (UseContentCharset && parsedtag_get_value(tag, ATTR_HTTP_EQUIV, &q) && !strcasecmp(q, "Content-Type") && parsedtag_get_value(tag, ATTR_CONTENT, &q) && (q = strcasestr(q, "charset")) != NULL) { q += 7; SKIP_BLANKS(q); if (*q == '=') { wc_ces c; q++; SKIP_BLANKS(q); if ((c = wc_guess_charset(q, 0)) != 0) { doc_charset = c; charset = WC_CES_US_ASCII; } } } #endif /* fall thru, "META" is prohibit tag */ case HTML_HEAD: case HTML_N_HEAD: case HTML_BODY: case HTML_N_BODY: case HTML_DOCTYPE: /* prohibit_tags */ Strshrinkfirst(tok, 1); Strshrink(tok, 1); fprintf(f1, "<!-- %s -->", html_quote(tok->ptr)); goto token_end; case HTML_TABLE: t_stack++; break; case HTML_N_TABLE: t_stack--; if (t_stack < 0) { t_stack = 0; Strshrinkfirst(tok, 1); Strshrink(tok, 1); fprintf(f1, "<!-- table stack underflow: %s -->", html_quote(tok->ptr)); goto token_end; } break; CASE_TABLE_TAG: /* table_tags MUST be in table stack */ if (!t_stack) { Strshrinkfirst(tok, 1); Strshrink(tok, 1); fprintf(f1, "<!-- %s -->", html_quote(tok->ptr)); goto token_end; } break; case HTML_SELECT: pre_mode = RB_INSELECT; end_tag = HTML_N_SELECT; break; case HTML_TEXTAREA: pre_mode = RB_INTXTA; end_tag = HTML_N_TEXTAREA; break; case HTML_SCRIPT: pre_mode = RB_SCRIPT; end_tag = HTML_N_SCRIPT; break; case HTML_STYLE: pre_mode = RB_STYLE; end_tag = HTML_N_STYLE; break; case HTML_LISTING: pre_mode = RB_PLAIN; end_tag = HTML_N_LISTING; fputs("<PRE_PLAIN>", f1); goto token_end; case HTML_XMP: pre_mode = RB_PLAIN; end_tag = HTML_N_XMP; fputs("<PRE_PLAIN>", f1); goto token_end; case HTML_PLAINTEXT: pre_mode = RB_PLAIN; end_tag = MAX_HTMLTAG; fputs("<PRE_PLAIN>", f1); goto token_end; default: break; } for (j = 0; j < TagMAP[tag->tagid].max_attribute; j++) { switch (tag->attrid[j]) { case ATTR_SRC: case ATTR_HREF: case ATTR_ACTION: if (!tag->value[j]) break; tag->value[j] = url_encode(remove_space(tag->value[j]), &base, charset); tag->need_reconstruct = TRUE; parseURL2(tag->value[j], &url, &base); if (url.scheme == SCM_UNKNOWN || #ifndef USE_W3MMAILER url.scheme == SCM_MAILTO || #endif url.scheme == SCM_MISSING) break; a_target |= 1; tag->value[j] = parsedURL2Str(&url)->ptr; parsedtag_set_value(tag, ATTR_REFERER, parsedURL2Str(&base)->ptr); #ifdef USE_M17N if (tag->attrid[j] == ATTR_ACTION && charset != WC_CES_US_ASCII) parsedtag_set_value(tag, ATTR_CHARSET, wc_ces_to_charset (charset)); #endif break; case ATTR_TARGET: if (!tag->value[j]) break; a_target |= 2; if (!strcasecmp(tag->value[j], "_self")) { parsedtag_set_value(tag, ATTR_TARGET, s_target); } else if (!strcasecmp(tag->value[j], "_parent")) { parsedtag_set_value(tag, ATTR_TARGET, p_target); } break; case ATTR_NAME: case ATTR_ID: if (!tag->value[j]) break; parsedtag_set_value(tag, ATTR_FRAMENAME, s_target); break; } } if (a_target == 1) { /* there is HREF attribute and no TARGET * attribute */ parsedtag_set_value(tag, ATTR_TARGET, d_target); } if (parsedtag_need_reconstruct(tag)) tok = parsedtag2str(tag); Strfputs(tok, f1); } else { if (pre_mode & RB_PLAIN) fprintf(f1, "%s", html_quote(tok->ptr)); else if (pre_mode & RB_INTXTA) fprintf(f1, "%s", html_quote(html_unquote(tok->ptr))); else Strfputs(tok, f1); } token_end: Strclear(tok); } while (*p != '\0' || !iseos(f2.stream)); if (pre_mode & RB_PLAIN) fputs("</PRE_PLAIN>\n", f1); else if (pre_mode & RB_INTXTA) fputs("</TEXTAREA></FORM>\n", f1); else if (pre_mode & RB_INSELECT) fputs("</SELECT></FORM>\n", f1); else if (pre_mode & (RB_SCRIPT | RB_STYLE)) { if (status != R_ST_NORMAL) fputs(correct_irrtag(status)->ptr, f1); if (pre_mode & RB_SCRIPT) fputs("</SCRIPT>\n", f1); else if (pre_mode & RB_STYLE) fputs("</STYLE>\n", f1); } while (t_stack--) fputs("</TABLE>\n", f1); UFclose(&f2); break; case F_FRAMESET: render_frameset: if (!frame.set->name && f->name) { frame.set->name = Sprintf("%s_%d", f->name, i)->ptr; } createFrameFile(frame.set, f1, current, level + 1, force_reload); break; } fputs("</td>\n", f1); } fputs("</tr>\n", f1); } fputs("</table>\n", f1); if (level == 0) { fputs("</body></html>\n", f1); TRAP_OFF; } return 0; }