diff options
Diffstat (limited to '')
-rw-r--r-- | file.c | 606 |
1 files changed, 499 insertions, 107 deletions
@@ -1,4 +1,4 @@ -/* $Id: file.c,v 1.235 2004/04/16 18:47:19 ukai Exp $ */ +/* $Id: file.c,v 1.254 2007/05/23 15:06:05 inu Exp $ */ #include "fm.h" #include <sys/types.h> #include "myctype.h" @@ -614,14 +614,12 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu) if (uf->scheme == SCM_NEWS && tmp->ptr[0] == '.') Strshrinkfirst(tmp, 1); #endif -#ifdef HTTP_DEBUG - { + if(w3m_reqlog){ FILE *ff; - ff = fopen("zzrequest", "a"); + ff = fopen(w3m_reqlog, "a"); Strfputs(tmp, ff); fclose(ff); } -#endif /* HTTP_DEBUG */ if (src) Strfputs(tmp, src); cleanup_line(tmp, HEADER_MODE); @@ -748,6 +746,7 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu) if (uf->compression != CMP_NOCOMPRESS) break; } + uf->content_encoding = uf->compression; } #ifdef USE_COOKIE else if (use_cookie && accept_cookie && @@ -836,13 +835,15 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu) } if (pu && name->length > 0) { int err; - if (flag & COO_SECURE) - disp_message_nsec("Received a secured cookie", FALSE, 1, + if (show_cookie) { + if (flag & COO_SECURE) + disp_message_nsec("Received a secured cookie", FALSE, 1, TRUE, FALSE); - else - disp_message_nsec(Sprintf("Received cookie: %s=%s", + else + disp_message_nsec(Sprintf("Received cookie: %s=%s", name->ptr, value->ptr)->ptr, FALSE, 1, TRUE, FALSE); + } err = add_cookie(pu, name, value, expires, domain, path, flag, comment, version, port, commentURL); @@ -874,10 +875,12 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu) emsg = "This cookie was rejected to prevent security violation."; record_err_message(emsg); - disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE); + if (show_cookie) + disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE); } else - disp_message_nsec(Sprintf + if (show_cookie) + disp_message_nsec(Sprintf ("Accepting invalid cookie: %s=%s", name->ptr, value->ptr)->ptr, FALSE, 1, TRUE, FALSE); @@ -972,7 +975,59 @@ struct http_auth { HRequest *hr, FormList *request); }; -#define TOKEN_PAT "[^][()<>@,;:\\\"/?={} \t\001-\037\177]*" +enum { + AUTHCHR_NUL, + AUTHCHR_SEP, + AUTHCHR_TOKEN, +}; + +static int +skip_auth_token(char **pp) +{ + char *p; + int first = AUTHCHR_NUL, typ; + + for (p = *pp ;; ++p) { + switch (*p) { + case '\0': + goto endoftoken; + default: + if ((unsigned char)*p > 037) { + typ = AUTHCHR_TOKEN; + break; + } + /* thru */ + case '\177': + case '[': + case ']': + case '(': + case ')': + case '<': + case '>': + case '@': + case ';': + case ':': + case '\\': + case '"': + case '/': + case '?': + case '=': + case ' ': + case '\t': + case ',': + typ = AUTHCHR_SEP; + break; + } + + if (!first) + first = typ; + else if (first != typ) + break; + } +endoftoken: + *pp = p; + return first; +} static Str extract_auth_val(char **q) @@ -993,12 +1048,13 @@ extract_auth_val(char **q) } if (!quoted) { switch (*qq) { + case '[': + case ']': case '(': case ')': case '<': case '>': case '@': - case ',': case ';': case ':': case '\\': @@ -1009,6 +1065,7 @@ extract_auth_val(char **q) case ' ': case '\t': qq++; + case ',': goto end_token; default: if (*qq <= 037 || *qq == 0177) { @@ -1022,11 +1079,6 @@ extract_auth_val(char **q) Strcat_char(val, *qq++); } end_token: - if (*qq != '\0') { - SKIP_BLANKS(qq); - if (*qq == ',') - qq++; - } *q = (char *)qq; return val; } @@ -1058,10 +1110,7 @@ static char * extract_auth_param(char *q, struct auth_param *auth) { struct auth_param *ap; - char *q0; - Regex re_token; - - newRegex(TOKEN_PAT, FALSE, &re_token, NULL); + char *p; for (ap = auth; ap->name != NULL; ap++) { ap->val = NULL; @@ -1070,26 +1119,41 @@ extract_auth_param(char *q, struct auth_param *auth) while (*q != '\0') { SKIP_BLANKS(q); for (ap = auth; ap->name != NULL; ap++) { - if (strncasecmp(q, ap->name, strlen(ap->name)) == 0) { - q += strlen(ap->name); - SKIP_BLANKS(q); - if (*q != '=') + size_t len; + + len = strlen(ap->name); + if (strncasecmp(q, ap->name, len) == 0 && + (IS_SPACE(q[len]) || q[len] == '=')) { + p = q + len; + SKIP_BLANKS(p); + if (*p != '=') return q; - q++; + q = p + 1; ap->val = extract_auth_val(&q); break; } } if (ap->name == NULL) { /* skip unknown param */ - if (RegexMatch(&re_token, q, -1, TRUE) == 0) - return q; - MatchedPosition(&re_token, &q0, &q); + int token_type; + p = q; + if ((token_type = skip_auth_token(&q)) == AUTHCHR_TOKEN && + (IS_SPACE(*q) || *q == '=')) { + SKIP_BLANKS(q); + if (*q != '=') + return p; + q++; + extract_auth_val(&q); + } + else + return p; + } + if (*q != '\0') { SKIP_BLANKS(q); - if (*q != '=') - return q; - q++; - extract_auth_val(&q); + if (*q == ',') + q++; + else + break; } } return q; @@ -1157,6 +1221,12 @@ digest_hex(char *p) return tmp; } +enum { + QOP_NONE, + QOP_AUTH, + QOP_AUTH_INT, +}; + static Str AuthDigestCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, HRequest *hr, FormList *request) @@ -1168,11 +1238,50 @@ AuthDigestCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, Str algorithm = qstr_unquote(get_auth_param(ha->param, "algorithm")); Str nonce = qstr_unquote(get_auth_param(ha->param, "nonce")); - Str cnonce = qstr_unquote(get_auth_param(ha->param, "cnonce")); + Str cnonce /* = qstr_unquote(get_auth_param(ha->param, "cnonce")) */; + /* cnonce is what client should generate. */ Str qop = qstr_unquote(get_auth_param(ha->param, "qop")); - if (cnonce == NULL) - cnonce = Strnew_charp("cnonce"); /* XXX */ + static union { + int r[4]; + char s[sizeof(int) * 4]; + } cnonce_seed; + int qop_i = QOP_NONE; + + cnonce_seed.r[0] = rand(); + cnonce_seed.r[1] = rand(); + cnonce_seed.r[2] = rand(); + MD5(cnonce_seed.s, sizeof(cnonce_seed.s), md5); + cnonce = digest_hex(md5); + cnonce_seed.r[3]++; + + if (qop) { + char *p; + size_t i; + + p = qop->ptr; + SKIP_BLANKS(p); + + for (;;) { + if ((i = strcspn(p, " \t,")) > 0) { + if (i == sizeof("auth-int") - sizeof("") && !strncasecmp(p, "auth-int", i)) { + if (qop_i < QOP_AUTH_INT) + qop_i = QOP_AUTH_INT; + } + else if (i == sizeof("auth") - sizeof("") && !strncasecmp(p, "auth", i)) { + if (qop_i < QOP_AUTH) + qop_i = QOP_AUTH; + } + } + + if (p[i]) { + p += i + 1; + SKIP_BLANKS(p); + } + else + break; + } + } /* A1 = unq(username-value) ":" unq(realm-value) ":" passwd */ tmp = Strnew_m_charp(uname->ptr, ":", @@ -1204,28 +1313,34 @@ AuthDigestCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, /* A2 = Method ":" digest-uri-value */ tmp = Strnew_m_charp(HTTPrequestMethod(hr)->ptr, ":", uri->ptr, NULL); - if (qop && (strcasecmp(qop->ptr, "auth-int") == 0)) { + if (qop_i == QOP_AUTH_INT) { /* A2 = Method ":" digest-uri-value ":" H(entity-body) */ - Str ebody = Strnew(); if (request && request->body) { - FILE *fp = fopen(request->body, "r"); - if (fp != NULL) { - int c; - while ((c = fgetc(fp)) != EOF) - Strcat_char(ebody, c); - fclose(fp); + if (request->method == FORM_METHOD_POST && request->enctype == FORM_ENCTYPE_MULTIPART) { + FILE *fp = fopen(request->body, "r"); + if (fp != NULL) { + Str ebody; + ebody = Strfgetall(fp); + MD5(ebody->ptr, strlen(ebody->ptr), md5); + } + else { + MD5("", 0, md5); + } + } + else { + MD5(request->body, request->length, md5); } } - MD5(ebody->ptr, strlen(ebody->ptr), md5); - ebody = digest_hex(md5); - Strcat_m_charp(tmp, ":", ebody->ptr, NULL); + else { + MD5("", 0, md5); + } + Strcat_char(tmp, ':'); + Strcat(tmp, digest_hex(md5)); } MD5(tmp->ptr, strlen(tmp->ptr), md5); a2buf = digest_hex(md5); - if (qop && - (strcasecmp(qop->ptr, "auth") == 0 - || strcasecmp(qop->ptr, "auth-int") == 0)) { + if (qop_i >= QOP_AUTH) { /* request-digest = <"> < KD ( H(A1), unq(nonce-value) * ":" nc-value * ":" unq(cnonce-value) @@ -1238,7 +1353,7 @@ AuthDigestCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, tmp = Strnew_m_charp(a1buf->ptr, ":", qstr_unquote(nonce)->ptr, ":", nc, ":", qstr_unquote(cnonce)->ptr, - ":", qstr_unquote(qop)->ptr, + ":", qop_i == QOP_AUTH ? "auth" : "auth-int", ":", a2buf->ptr, NULL); MD5(tmp->ptr, strlen(tmp->ptr), md5); rd = digest_hex(md5); @@ -1279,10 +1394,13 @@ AuthDigestCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu, if ((s = get_auth_param(ha->param, "opaque")) != NULL) Strcat_m_charp(tmp, ", opaque=", s->ptr, NULL); - if (qop) { + if (qop_i >= QOP_AUTH) { Strcat_m_charp(tmp, ", qop=", - get_auth_param(ha->param, "qop")->ptr, NULL); + qop_i == QOP_AUTH ? "auth" : "auth-int", + NULL); /* XXX how to count? */ + /* Since nonce is unique up to each *-Authenticate and w3m does not re-use *-Authenticate: headers, + nonce-count should be always "00000001". */ Strcat_m_charp(tmp, ", nc=", nc, NULL); } @@ -1344,12 +1462,9 @@ static struct http_auth * findAuthentication(struct http_auth *hauth, Buffer *buf, char *auth_field) { struct http_auth *ha; - int len = strlen(auth_field); + int len = strlen(auth_field), slen; TextListItem *i; char *p0, *p; - Regex re_token; - - newRegex(TOKEN_PAT, FALSE, &re_token, NULL); bzero(hauth, sizeof(struct http_auth)); for (i = buf->document_header->first; i != NULL; i = i->next) { @@ -1358,29 +1473,30 @@ findAuthentication(struct http_auth *hauth, Buffer *buf, char *auth_field) SKIP_BLANKS(p); p0 = p; for (ha = &www_auth[0]; ha->scheme != NULL; ha++) { - if (strncasecmp(p, ha->scheme, strlen(ha->scheme)) == 0) { + slen = strlen(ha->scheme); + if (strncasecmp(p, ha->scheme, slen) == 0) { + p += slen; + SKIP_BLANKS(p); if (hauth->pri < ha->pri) { *hauth = *ha; - p += strlen(ha->scheme); - SKIP_BLANKS(p); p = extract_auth_param(p, hauth->param); break; } else { /* weak auth */ - p += strlen(ha->scheme); - SKIP_BLANKS(p); p = extract_auth_param(p, none_auth_param); } } } if (p0 == p) { /* all unknown auth failed */ - if (RegexMatch(&re_token, p0, -1, TRUE) == 0) - return NULL; - MatchedPosition(&re_token, &p0, &p); - SKIP_BLANKS(p); - p = extract_auth_param(p, none_auth_param); + int token_type; + if ((token_type = skip_auth_token(&p)) == AUTHCHR_TOKEN && IS_SPACE(*p)) { + SKIP_BLANKS(p); + p = extract_auth_param(p, none_auth_param); + } + else + break; } } } @@ -1486,9 +1602,17 @@ getAuthCookie(struct http_auth *hauth, char *auth_header, getpassphrase(proxy ? "Proxy Password: " : "Password: ")); #else +#ifndef __MINGW32_VERSION *pwd = Strnew_charp((char *) getpass(proxy ? "Proxy Password: " : "Password: ")); +#else + term_raw(); + *pwd = Strnew_charp((char *) + inputLine(proxy ? "Proxy Password: " : + "Password: ", NULL, IN_PASSWORD)); + term_cbreak(); +#endif /* __MINGW32_VERSION */ #endif } } @@ -1893,6 +2017,27 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, status = HTST_NORMAL; goto load_doc; } +#ifdef AUTH_DEBUG + if ((p = checkHeader(t_buf, "WWW-Authenticate:")) != NULL) { + /* Authentication needed */ + struct http_auth hauth; + if (findAuthentication(&hauth, t_buf, "WWW-Authenticate:") != NULL + && (realm = get_auth_param(hauth.param, "realm")) != NULL) { + auth_pu = &pu; + getAuthCookie(&hauth, "Authorization:", extra_header, + auth_pu, &hr, request, &uname, &pwd); + if (uname == NULL) { + /* abort */ + TRAP_OFF; + goto page_loaded; + } + UFclose(&f); + add_auth_cookie_flag = 1; + status = HTST_NORMAL; + goto load_doc; + } + } +#endif /* defined(AUTH_DEBUG) */ t = checkContentType(t_buf); if (t == NULL) t = "text/plain"; @@ -1987,7 +2132,11 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, return NO_BUFFER; } - if (f.compression != CMP_NOCOMPRESS) { + if ((f.content_encoding != CMP_NOCOMPRESS) && AutoUncompress + && !(w3m_dump & DUMP_EXTRA)) { + uncompress_stream(&f, &pu.real_file); + } + else if (f.compression != CMP_NOCOMPRESS) { if (!(w3m_dump & DUMP_SOURCE) && (w3m_dump & ~DUMP_FRAME || is_text_type(t) || searchExtViewer(t))) { @@ -2109,7 +2258,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer, } else { /* plain text */ int l = atoi(pu.label); - gotoLine(b, l); + gotoRealLine(b, l); b->pos = 0; arrangeCursor(b); } @@ -2301,7 +2450,10 @@ set_breakpoint(struct readbuffer *obuf, int tag_length) sizeof(obuf->anchor)); obuf->bp.img_alt = obuf->img_alt; obuf->bp.in_bold = obuf->in_bold; + obuf->bp.in_italic = obuf->in_italic; obuf->bp.in_under = obuf->in_under; + obuf->bp.in_strike = obuf->in_strike; + obuf->bp.in_ins = obuf->in_ins; obuf->bp.nobr_level = obuf->nobr_level; obuf->bp.prev_ctype = obuf->prev_ctype; obuf->bp.init_flag = 0; @@ -2315,7 +2467,10 @@ back_to_breakpoint(struct readbuffer *obuf) sizeof(obuf->anchor)); obuf->img_alt = obuf->bp.img_alt; obuf->in_bold = obuf->bp.in_bold; + obuf->in_italic = obuf->bp.in_italic; obuf->in_under = obuf->bp.in_under; + obuf->in_strike = obuf->bp.in_strike; + obuf->in_ins = obuf->bp.in_ins; obuf->prev_ctype = obuf->bp.prev_ctype; obuf->pos = obuf->bp.pos; obuf->top_margin = obuf->bp.top_margin; @@ -2337,6 +2492,8 @@ append_tags(struct readbuffer *obuf) case HTML_IMG_ALT: case HTML_B: case HTML_U: + case HTML_I: + case HTML_S: push_link(obuf->tag_stack[i]->cmd, obuf->line->length, obuf->pos); break; } @@ -2551,7 +2708,8 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, FILE *f = h_env->f; Str line = obuf->line, pass = NULL; char *hidden_anchor = NULL, *hidden_img = NULL, *hidden_bold = NULL, - *hidden_under = NULL, *hidden = NULL; + *hidden_under = NULL, *hidden_italic = NULL, *hidden_strike = NULL, + *hidden_ins = NULL, *hidden = NULL; #ifdef DEBUG if (w3m_debug) { @@ -2589,12 +2747,30 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, hidden = hidden_bold; } } + if (obuf->in_italic) { + if ((hidden_italic = has_hidden_link(obuf, HTML_I)) != NULL) { + if (!hidden || hidden_italic < hidden) + hidden = hidden_italic; + } + } if (obuf->in_under) { if ((hidden_under = has_hidden_link(obuf, HTML_U)) != NULL) { if (!hidden || hidden_under < hidden) hidden = hidden_under; } } + if (obuf->in_strike) { + if ((hidden_strike = has_hidden_link(obuf, HTML_S)) != NULL) { + if (!hidden || hidden_strike < hidden) + hidden = hidden_strike; + } + } + if (obuf->in_ins) { + if ((hidden_ins = has_hidden_link(obuf, HTML_INS)) != NULL) { + if (!hidden || hidden_ins < hidden) + hidden = hidden_ins; + } + } if (hidden) { pass = Strnew_charp(hidden); Strshrink(line, line->ptr + line->length - hidden); @@ -2618,8 +2794,14 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, Strcat_charp(line, "</img_alt>"); if (obuf->in_bold && !hidden_bold) Strcat_charp(line, "</b>"); + if (obuf->in_italic && !hidden_italic) + Strcat_charp(line, "</i>"); if (obuf->in_under && !hidden_under) Strcat_charp(line, "</u>"); + if (obuf->in_strike && !hidden_strike) + Strcat_charp(line, "</s>"); + if (obuf->in_ins && !hidden_ins) + Strcat_charp(line, "</ins>"); if (obuf->top_margin > 0) { int i; @@ -2822,8 +3004,14 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, } if (!hidden_bold && obuf->in_bold) push_tag(obuf, "<B>", HTML_B); + if (!hidden_italic && obuf->in_italic) + push_tag(obuf, "<I>", HTML_I); if (!hidden_under && obuf->in_under) push_tag(obuf, "<U>", HTML_U); + if (!hidden_strike && obuf->in_strike) + push_tag(obuf, "<S>", HTML_S); + if (!hidden_ins && obuf->in_ins) + push_tag(obuf, "<INS>", HTML_INS); } void @@ -2934,8 +3122,14 @@ save_fonteffect(struct html_feed_environ *h_env, struct readbuffer *obuf) obuf->fontstat_sp++; if (obuf->in_bold) push_tag(obuf, "</b>", HTML_N_B); + if (obuf->in_italic) + push_tag(obuf, "</i>", HTML_N_I); if (obuf->in_under) push_tag(obuf, "</u>", HTML_N_U); + if (obuf->in_strike) + push_tag(obuf, "</s>", HTML_N_S); + if (obuf->in_ins) + push_tag(obuf, "</ins>", HTML_N_INS); bzero(obuf->fontstat, FONTSTAT_SIZE); } @@ -2949,8 +3143,14 @@ restore_fonteffect(struct html_feed_environ *h_env, struct readbuffer *obuf) FONTSTAT_SIZE); if (obuf->in_bold) push_tag(obuf, "<b>", HTML_B); + if (obuf->in_italic) + push_tag(obuf, "<i>", HTML_I); if (obuf->in_under) push_tag(obuf, "<u>", HTML_U); + if (obuf->in_strike) + push_tag(obuf, "<s>", HTML_S); + if (obuf->in_ins) + push_tag(obuf, "<ins>", HTML_INS); } static Str @@ -3003,7 +3203,7 @@ process_img(struct parsed_tag *tag, int width) #else int w, i, nw, n; #endif - int pre_int = FALSE; + int pre_int = FALSE, ext_pre_int = FALSE; Str tmp = Strnew(); if (!parsedtag_get_value(tag, ATTR_SRC, &p)) @@ -3059,6 +3259,8 @@ process_img(struct parsed_tag *tag, int width) parsedtag_get_value(tag, ATTR_HEIGHT, &i); r = NULL; parsedtag_get_value(tag, ATTR_USEMAP, &r); + if (parsedtag_exists(tag, ATTR_PRE_INT)) + ext_pre_int = TRUE; tmp = Strnew_size(128); #ifdef USE_IMAGE @@ -3287,7 +3489,7 @@ process_img(struct parsed_tag *tag, int width) } #endif Strcat_charp(tmp, "</img_alt>"); - if (pre_int) + if (pre_int && !ext_pre_int) Strcat_charp(tmp, "</pre_int>"); if (r) { Strcat_charp(tmp, "</input_alt>"); @@ -3426,7 +3628,7 @@ process_input(struct parsed_tag *tag) Strcat(tmp, Sprintf(" width=\"%d\"", iw)); if (parsedtag_get_value(tag, ATTR_HEIGHT, &ih)) Strcat(tmp, Sprintf(" height=\"%d\"", ih)); - Strcat_charp(tmp, ">"); + Strcat_charp(tmp, " pre_int>"); Strcat_charp(tmp, "</input_alt></pre_int>"); return tmp; } @@ -4104,6 +4306,20 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) return 0; } return 1; + case HTML_I: + obuf->in_italic++; + if (obuf->in_italic > 1) + return 1; + return 0; + case HTML_N_I: + if (obuf->in_italic == 1 && close_effect0(obuf, HTML_I)) + obuf->in_italic = 0; + if (obuf->in_italic > 0) { + obuf->in_italic--; + if (obuf->in_italic == 0) + return 0; + } + return 1; case HTML_U: obuf->in_under++; if (obuf->in_under > 1) @@ -4119,9 +4335,15 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) } return 1; case HTML_EM: - HTMLlineproc1("<b>", h_env); + HTMLlineproc1("<i>", h_env); return 1; case HTML_N_EM: + HTMLlineproc1("</i>", h_env); + return 1; + case HTML_STRONG: + HTMLlineproc1("<b>", h_env); + return 1; + case HTML_N_STRONG: HTMLlineproc1("</b>", h_env); return 1; case HTML_Q: @@ -4180,7 +4402,7 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) } PUSH_ENV(cmd); if (cmd == HTML_UL || cmd == HTML_OL) { - if (parsedtag_get_value(tag, ATTR_START, &count) && count > 0) { + if (parsedtag_get_value(tag, ATTR_START, &count)) { envs[h_env->envc].count = count - 1; } } @@ -4239,6 +4461,8 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) count = atoi(p); if (count > 0) envs[h_env->envc].count = count; + else + envs[h_env->envc].count = 0; } switch (envs[h_env->envc].env) { case HTML_UL: @@ -4272,7 +4496,7 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) case HTML_OL: if (parsedtag_get_value(tag, ATTR_TYPE, &p)) envs[h_env->envc].type = (int)*p; - switch (envs[h_env->envc].type) { + switch ((envs[h_env->envc].count > 0)? envs[h_env->envc].type: '1') { case 'i': num = romanNumeral(envs[h_env->envc].count); break; @@ -4424,6 +4648,7 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) do_blankline(h_env, obuf, envs[h_env->envc].indent, 0, h_env->limit); obuf->flag |= RB_IGNORE_P; + h_env->blank_lines++; } obuf->flag &= ~RB_PRE; close_anchor(h_env, obuf); @@ -4802,36 +5027,114 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) case HTML_AREA: return 0; case HTML_DEL: - if (displayInsDel) - HTMLlineproc1("<U>[DEL:</U>", h_env); - else + switch (displayInsDel) { + case DISPLAY_INS_DEL_SIMPLE: obuf->flag |= RB_DEL; + break; + case DISPLAY_INS_DEL_NORMAL: + HTMLlineproc1("<U>[DEL:</U>", h_env); + break; + case DISPLAY_INS_DEL_FONTIFY: + obuf->in_strike++; + if (obuf->in_strike == 1) { + push_tag(obuf, "<s>", HTML_S); + } + break; + } return 1; case HTML_N_DEL: - if (displayInsDel) - HTMLlineproc1("<U>:DEL]</U>", h_env); - else + switch (displayInsDel) { + case DISPLAY_INS_DEL_SIMPLE: obuf->flag &= ~RB_DEL; + break; + case DISPLAY_INS_DEL_NORMAL: + HTMLlineproc1("<U>:DEL]</U>", h_env); + case DISPLAY_INS_DEL_FONTIFY: + if (obuf->in_strike == 0) + return 1; + if (obuf->in_strike == 1 && close_effect0(obuf, HTML_S)) + obuf->in_strike = 0; + if (obuf->in_strike > 0) { + obuf->in_strike--; + if (obuf->in_strike == 0) { + push_tag(obuf, "</s>", HTML_N_S); + } + } + break; + } return 1; case HTML_S: - if (displayInsDel) - HTMLlineproc1("<U>[S:</U>", h_env); - else + switch (displayInsDel) { + case DISPLAY_INS_DEL_SIMPLE: obuf->flag |= RB_S; + break; + case DISPLAY_INS_DEL_NORMAL: + HTMLlineproc1("<U>[S:</U>", h_env); + break; + case DISPLAY_INS_DEL_FONTIFY: + obuf->in_strike++; + if (obuf->in_strike == 1) { + push_tag(obuf, "<s>", HTML_S); + } + break; + } return 1; case HTML_N_S: - if (displayInsDel) - HTMLlineproc1("<U>:S]</U>", h_env); - else + switch (displayInsDel) { + case DISPLAY_INS_DEL_SIMPLE: obuf->flag &= ~RB_S; + break; + case DISPLAY_INS_DEL_NORMAL: + HTMLlineproc1("<U>:S]</U>", h_env); + break; + case DISPLAY_INS_DEL_FONTIFY: + if (obuf->in_strike == 0) + return 1; + if (obuf->in_strike == 1 && close_effect0(obuf, HTML_S)) + obuf->in_strike = 0; + if (obuf->in_strike > 0) { + obuf->in_strike--; + if (obuf->in_strike == 0) { + push_tag(obuf, "</s>", HTML_N_S); + } + } + } return 1; case HTML_INS: - if (displayInsDel) + switch (displayInsDel) { + case DISPLAY_INS_DEL_SIMPLE: + break; + case DISPLAY_INS_DEL_NORMAL: HTMLlineproc1("<U>[INS:</U>", h_env); + break; + case DISPLAY_INS_DEL_FONTIFY: + obuf->in_ins++; + if (obuf->in_ins == 1) { + push_tag(obuf, "<ins>", HTML_INS); + } + break; + } return 1; case HTML_N_INS: - if (displayInsDel) + switch (displayInsDel) { + case DISPLAY_INS_DEL_SIMPLE: + break; + case DISPLAY_INS_DEL_NORMAL: HTMLlineproc1("<U>:INS]</U>", h_env); + break; + case DISPLAY_INS_DEL_FONTIFY: + if (obuf->in_ins == 0) + return 1; + if (obuf->in_ins == 1 && close_effect0(obuf, HTML_INS)) + obuf->in_ins = 0; + if (obuf->in_ins > 0) { + obuf->in_ins--; + if (obuf->in_ins == 0) { + push_tag(obuf, "</ins>", HTML_N_INS); + } + } + break; + } return 1; case HTML_SUP: if (!(obuf->flag & (RB_DEL | RB_S))) @@ -4926,6 +5229,25 @@ textlist_feed() return NULL; } +ex_efct(int ex) +{ + int effect = 0; + + if (! ex) + return 0; + + if (ex & PE_EX_ITALIC) + effect |= PE_EX_ITALIC_E; + + if (ex & PE_EX_INSERT) + effect |= PE_EX_INSERT_E; + + if (ex & PE_EX_STRIKE) + effect |= PE_EX_STRIKE_E; + + return effect; +} + static void HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) { @@ -4934,7 +5256,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) static int out_size = 0; Anchor *a_href = NULL, *a_img = NULL, *a_form = NULL; char *p, *q, *r, *s, *t, *str; - Lineprop mode, effect; + Lineprop mode, effect, ex_effect; int pos; int nlines; #ifdef DEBUG @@ -4981,6 +5303,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #endif effect = 0; + ex_effect = 0; nlines = 0; while ((line = feed()) != NULL) { #ifdef DEBUG @@ -5005,7 +5328,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) while (str < endp) { PSIZE; mode = get_mctype(str); - if (effect & PC_SYMBOL && *str != '<') { + if ((effect | ex_efct(ex_effect)) & PC_SYMBOL && *str != '<') { #ifdef USE_M17N char **buf = set_symbol(symbol_width0); int len; @@ -5013,16 +5336,16 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) p = buf[(int)symbol]; len = get_mclen(p); mode = get_mctype(p); - PPUSH(mode | effect, *(p++)); + PPUSH(mode | effect | ex_efct(ex_effect), *(p++)); if (--len) { mode = (mode & ~PC_WCHAR1) | PC_WCHAR2; while (len--) { PSIZE; - PPUSH(mode | effect, *(p++)); + PPUSH(mode | effect | ex_efct(ex_effect), *(p++)); } } #else - PPUSH(PC_ASCII | effect, SYMBOL_BASE + symbol); + PPUSH(PC_ASCII | effect | ex_efct(ex_effect), SYMBOL_BASE + symbol); #endif str += symbol_width; } @@ -5031,12 +5354,12 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #else else if (mode == PC_CTRL || IS_INTSPACE(*str)) { #endif - PPUSH(PC_ASCII | effect, ' '); + PPUSH(PC_ASCII | effect | ex_efct(ex_effect), ' '); str++; } #ifdef USE_M17N else if (mode & PC_UNKNOWN) { - PPUSH(PC_ASCII | effect, ' '); + PPUSH(PC_ASCII | effect | ex_efct(ex_effect), ' '); str += get_mclen(str); } #endif @@ -5044,13 +5367,13 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #ifdef USE_M17N int len = get_mclen(str); #endif - PPUSH(mode | effect, *(str++)); + PPUSH(mode | effect | ex_efct(ex_effect), *(str++)); #ifdef USE_M17N if (--len) { mode = (mode & ~PC_WCHAR1) | PC_WCHAR2; while (len--) { PSIZE; - PPUSH(mode | effect, *(str++)); + PPUSH(mode | effect | ex_efct(ex_effect), *(str++)); } } #endif @@ -5068,12 +5391,12 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #else if (mode == PC_CTRL || IS_INTSPACE(*str)) { #endif - PPUSH(PC_ASCII | effect, ' '); + PPUSH(PC_ASCII | effect | ex_efct(ex_effect), ' '); p++; } #ifdef USE_M17N else if (mode & PC_UNKNOWN) { - PPUSH(PC_ASCII | effect, ' '); + PPUSH(PC_ASCII | effect | ex_efct(ex_effect), ' '); p += get_mclen(p); } #endif @@ -5081,13 +5404,13 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #ifdef USE_M17N int len = get_mclen(p); #endif - PPUSH(mode | effect, *(p++)); + PPUSH(mode | effect | ex_efct(ex_effect), *(p++)); #ifdef USE_M17N if (--len) { mode = (mode & ~PC_WCHAR1) | PC_WCHAR2; while (len--) { PSIZE; - PPUSH(mode | effect, *(p++)); + PPUSH(mode | effect | ex_efct(ex_effect), *(p++)); } } #endif @@ -5106,12 +5429,30 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) case HTML_N_B: effect &= ~PE_BOLD; break; + case HTML_I: + ex_effect |= PE_EX_ITALIC; + break; + case HTML_N_I: + ex_effect &= ~PE_EX_ITALIC; + break; + case HTML_INS: + ex_effect |= PE_EX_INSERT; + break; + case HTML_N_INS: + ex_effect &= ~PE_EX_INSERT; + break; case HTML_U: effect |= PE_UNDER; break; case HTML_N_U: effect &= ~PE_UNDER; break; + case HTML_S: + ex_effect |= PE_EX_STRIKE; + break; + case HTML_N_S: + ex_effect &= ~PE_EX_STRIKE; + break; case HTML_A: if (renderFrameSet && parsedtag_get_value(tag, ATTR_FRAMENAME, &p)) { @@ -5145,6 +5486,17 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) buf->hmarklist = putHmarker(buf->hmarklist, currentLn(buf), pos, hseq - 1); + else if (hseq < 0) { + int h = -hseq - 1; + if (buf->hmarklist && + h < buf->hmarklist->nmark && + buf->hmarklist->marks[h].invalid) { + buf->hmarklist->marks[h].pos = pos; + buf->hmarklist->marks[h].line = currentLn(buf); + buf->hmarklist->marks[h].invalid = 0; + hseq = -hseq; + } + } if (id && idFrame) idFrame->body->nameList = putAnchor(idFrame->body->nameList, id, NULL, @@ -5164,8 +5516,12 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) a_href->end.line = currentLn(buf); a_href->end.pos = pos; if (a_href->start.line == a_href->end.line && - a_href->start.pos == a_href->end.pos) + a_href->start.pos == a_href->end.pos) { + if (buf->hmarklist && + a_href->hseq < buf->hmarklist->nmark) + buf->hmarklist->marks[a_href->hseq].invalid = 1; a_href->hseq = -1; + } a_href = NULL; } break; @@ -6347,7 +6703,10 @@ init_henv(struct html_feed_environ *h_env, struct readbuffer *obuf, bzero((void *)&obuf->anchor, sizeof(obuf->anchor)); obuf->img_alt = 0; obuf->in_bold = 0; + obuf->in_italic = 0; obuf->in_under = 0; + obuf->in_strike = 0; + obuf->in_ins = 0; obuf->prev_ctype = PC_ASCII; obuf->tag_sp = 0; obuf->fontstat_sp = 0; @@ -6382,10 +6741,22 @@ completeHTMLstream(struct html_feed_environ *h_env, struct readbuffer *obuf) push_tag(obuf, "</b>", HTML_N_B); obuf->in_bold = 0; } + if (obuf->in_italic) { + push_tag(obuf, "</i>", HTML_N_I); + obuf->in_italic = 0; + } if (obuf->in_under) { push_tag(obuf, "</u>", HTML_N_U); obuf->in_under = 0; } + if (obuf->in_strike) { + push_tag(obuf, "</s>", HTML_N_S); + obuf->in_strike = 0; + } + if (obuf->in_ins) { + push_tag(obuf, "</ins>", HTML_N_INS); + obuf->in_ins = 0; + } if (obuf->flag & RB_INTXTA) HTMLlineproc1("</textarea>", h_env); /* for unbalanced select tag */ @@ -6602,6 +6973,8 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) if (src) Strfputs(lineBuf2, src); linelen += lineBuf2->length; + if (w3m_dump & DUMP_EXTRA) + printf("W3m-in-progress: %s\n", convert_size2(linelen, current_content_length, TRUE)); if (w3m_dump & DUMP_SOURCE) continue; showProgress(&linelen, &trbyte); @@ -6854,6 +7227,8 @@ loadBuffer(URLFile *uf, Buffer *volatile newBuf) if (src) Strfputs(lineBuf2, src); linelen += lineBuf2->length; + if (w3m_dump & DUMP_EXTRA) + printf("W3m-in-progress: %s\n", convert_size2(linelen, current_content_length, TRUE)); if (w3m_dump & DUMP_SOURCE) continue; showProgress(&linelen, &trbyte); @@ -7534,6 +7909,7 @@ _MoveFile(char *path1, char *path2) int _doFileCopy(char *tmpf, char *defstr, int download) { +#ifndef __MINGW32_VERSION Str msg; Str filen; char *p, *q = NULL; @@ -7640,6 +8016,7 @@ _doFileCopy(char *tmpf, char *defstr, int download) if (PreserveTimestamp && !is_pipe && !stat(tmpf, &st)) setModtime(p, st.st_mtime); } +#endif /* __MINGW32_VERSION */ return 0; } @@ -7654,11 +8031,13 @@ doFileMove(char *tmpf, char *defstr) int doFileSave(URLFile uf, char *defstr) { +#ifndef __MINGW32_VERSION Str msg; Str filen; char *p, *q; pid_t pid; char *lock; + char *tmpf = NULL; #if !(defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)) FILE *f; #endif @@ -7699,6 +8078,11 @@ doFileSave(URLFile uf, char *defstr) flush_tty(); pid = fork(); if (!pid) { + if ((uf.content_encoding != CMP_NOCOMPRESS) && AutoUncompress) { + uncompress_stream(&uf, &tmpf); + if (tmpf) + unlink(tmpf); + } setup_child(FALSE, 0, UFfileno(&uf)); if (!save2tmp(uf, p) && PreserveTimestamp && uf.modtime != -1) setModtime(p, uf.modtime); @@ -7731,6 +8115,11 @@ doFileSave(URLFile uf, char *defstr) printf("Can't save. Load file and %s are identical.", p); return -1; } + if (uf.content_encoding != CMP_NOCOMPRESS && AutoUncompress) { + uncompress_stream(&uf, &tmpf); + if (tmpf) + unlink(tmpf); + } if (save2tmp(uf, p) < 0) { /* FIXME: gettextize? */ printf("Can't save to %s\n", p); @@ -7739,6 +8128,7 @@ doFileSave(URLFile uf, char *defstr) if (PreserveTimestamp && uf.modtime != -1) setModtime(p, uf.modtime); } +#endif /* __MINGW32_VERSION */ return 0; } @@ -7799,7 +8189,7 @@ inputAnswer(char *prompt) ans = inputChar(prompt); } else { - printf(prompt); + printf("%s", prompt); fflush(stdout); ans = Strfgets(stdin)->ptr; } @@ -7809,6 +8199,7 @@ inputAnswer(char *prompt) static void uncompress_stream(URLFile *uf, char **src) { +#ifndef __MINGW32_VERSION pid_t pid1; FILE *f1; char *expand_cmd = GUNZIP_CMDNAME; @@ -7891,7 +8282,8 @@ uncompress_stream(URLFile *uf, char **src) uf->scheme = SCM_LOCAL; } UFhalfclose(uf); - uf->stream = newFileStream(f1, (void (*)())pclose); + uf->stream = newFileStream(f1, (void (*)())fclose); +#endif /* __MINGW32_VERSION */ } static FILE * |