diff options
| author | Tatsuya Kinoshita <tats@debian.org> | 2013-07-30 11:13:51 +0000 | 
|---|---|---|
| committer | Tatsuya Kinoshita <tats@debian.org> | 2013-07-30 11:13:51 +0000 | 
| commit | 18b0cc756bc5d5145fc1abcd0ef46ff2455c79ab (patch) | |
| tree | 88966004acc26ea238b5414bd569b86aac1b569d | |
| parent | Sort anchors by sequence number in -dump (diff) | |
| parent | Merge branch 'feature/debian-version' (diff) | |
| download | w3m-18b0cc756bc5d5145fc1abcd0ef46ff2455c79ab.tar.gz w3m-18b0cc756bc5d5145fc1abcd0ef46ff2455c79ab.zip | |
Merge branch 'master' into bug/sort-dump-links
Conflicts:
	main.c
| -rw-r--r-- | Makefile.in | 4 | ||||
| -rw-r--r-- | acinclude.m4 | 2 | ||||
| -rw-r--r-- | anchor.c | 37 | ||||
| -rw-r--r-- | config.h.in | 1 | ||||
| -rwxr-xr-x | configure | 2 | ||||
| -rw-r--r-- | display.c | 2 | ||||
| -rw-r--r-- | doc-jp/README.siteconf | 60 | ||||
| -rw-r--r-- | doc/README.siteconf | 60 | ||||
| -rw-r--r-- | file.c | 380 | ||||
| -rw-r--r-- | fm.h | 22 | ||||
| -rw-r--r-- | form.c | 31 | ||||
| -rw-r--r-- | frame.c | 9 | ||||
| -rw-r--r-- | func.c | 88 | ||||
| -rw-r--r-- | history.c | 2 | ||||
| -rw-r--r-- | html.c | 37 | ||||
| -rw-r--r-- | html.h | 31 | ||||
| -rw-r--r-- | indep.c | 14 | ||||
| -rw-r--r-- | indep.h | 1 | ||||
| -rw-r--r-- | istream.c | 10 | ||||
| -rw-r--r-- | istream.h | 4 | ||||
| -rw-r--r-- | keybind.c | 2 | ||||
| -rw-r--r-- | linein.c | 4 | ||||
| -rw-r--r-- | main.c | 154 | ||||
| -rw-r--r-- | map.c | 27 | ||||
| -rw-r--r-- | menu.c | 12 | ||||
| -rw-r--r-- | po/ja.po | 4 | ||||
| -rw-r--r-- | proto.h | 30 | ||||
| -rw-r--r-- | rc.c | 222 | ||||
| -rw-r--r-- | table.c | 8 | ||||
| -rw-r--r-- | tagtable.tab | 1 | ||||
| -rw-r--r-- | terms.c | 4 | ||||
| -rw-r--r-- | url.c | 122 | ||||
| -rw-r--r-- | version.c.in | 2 | ||||
| -rw-r--r-- | w3mbookmark.c | 2 | ||||
| -rw-r--r-- | w3mimg/Makefile.in | 2 | 
35 files changed, 1078 insertions, 315 deletions
| diff --git a/Makefile.in b/Makefile.in index 7d692f9..339c95e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -150,7 +150,7 @@ parsetagx.o: html.c  funcname.tab: $(DEFUNS)  	(echo '#define DEFUN(x,y,z) x y';\ -	 sed -ne '/^DEFUN/{p;n;/^[ 	]/p;}' $(DEFUNS)) | $(CPP) - | \ +	 sed -ne '/^DEFUN/{p;n;/^[ 	]/p;}' $(DEFUNS)) | $(CPP) $(CPPFLAGS) - | \  	 awk '$$1 ~ /^[_A-Za-z]/ { \  	       for (i=2;i<=NF;i++) { print $$i, $$1} \  	 }' > $@.tmp @@ -199,7 +199,7 @@ dummy.o: entity.c  	$(CC) $(CFLAGS) -DDUMMY -c -o $@ $?  $(IMGDISPLAY): w3mimgdisplay.o $(ALIB) w3mimg/w3mimg.a -	$(IMGLINK) $(CFLAGS) -o $(IMGDISPLAY) w3mimgdisplay.o w3mimg/w3mimg.a $(LDFLAGS) $(LIBS) $(IMGLDFLAGS) +	$(IMGLINK) $(CFLAGS) -o $(IMGDISPLAY) w3mimgdisplay.o w3mimg/w3mimg.a $(LDFLAGS) $(LIBS) -lX11 $(IMGLDFLAGS)  w3mimgdisplay.o: w3mimgdisplay.c w3mimg/w3mimg.h  	$(CC) $(CFLAGS) $(IMGCFLAGS) -o $@ -c $(srcdir)/w3mimgdisplay.c diff --git a/acinclude.m4 b/acinclude.m4 index e4ccc3d..52c8874 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -866,7 +866,7 @@ AC_MSG_CHECKING(for sys_errlist)  AC_TRY_COMPILE(  changequote(<<,>>)dnl  <<extern char *sys_errlist[];>>, -<<printf(sys_errlist[0]);>>, +<<printf("%s", sys_errlist[0]);>>,  changequote([,])dnl  [have_sys_errlist="yes"; AC_DEFINE(HAVE_SYS_ERRLIST)],  [have_sys_errlist="no"]) @@ -200,10 +200,11 @@ _put_anchor_news(Buffer *buf, char *p1, char *p2, int line, int pos)  	if (*(p2 - 1) == '>')  	    p2--;      } -    tmp = wc_Str_conv_strict(Strnew_charp_n(p1, p2 - p1), InnerCharset, -			     buf->document_charset); -    tmp = Sprintf("news:%s", file_quote(tmp->ptr)); -    return registerHref(buf, tmp->ptr, NULL, NO_REFERER, NULL, '\0', line, +    tmp = Strnew_charp("news:"); +    Strcat_charp_n(tmp, p1, p2 - p1); +    return registerHref(buf, url_encode(tmp->ptr, baseURL(buf), +					buf->document_charset), +			NULL, NO_REFERER, NULL, '\0', line,  			pos);  }  #endif				/* USE_NNTP */ @@ -213,9 +214,10 @@ _put_anchor_all(Buffer *buf, char *p1, char *p2, int line, int pos)  {      Str tmp; -    tmp = wc_Str_conv_strict(Strnew_charp_n(p1, p2 - p1), InnerCharset, -			     buf->document_charset); -    return registerHref(buf, url_quote(tmp->ptr), NULL, NO_REFERER, NULL, +    tmp = Strnew_charp_n(p1, p2 - p1); +    return registerHref(buf, url_encode(tmp->ptr, baseURL(buf), +					buf->document_charset), +			NULL, NO_REFERER, NULL,  			'\0', line, pos);  } @@ -756,7 +758,7 @@ link_list_panel(Buffer *buf)  		p = parsedURL2Str(&pu)->ptr;  		u = html_quote(p);  		if (DecodeURL) -		    p = html_quote(url_unquote_conv(p, buf->document_charset)); +		    p = html_quote(url_decode2(p, buf));  		else  		    p = u;  	    } @@ -787,7 +789,7 @@ link_list_panel(Buffer *buf)  	    p = parsedURL2Str(&pu)->ptr;  	    u = html_quote(p);  	    if (DecodeURL) -		p = html_quote(url_unquote_conv(p, buf->document_charset)); +		p = html_quote(url_decode2(p, buf));  	    else  		p = u;  	    t = getAnchorText(buf, al, a); @@ -809,16 +811,13 @@ link_list_panel(Buffer *buf)  	    p = parsedURL2Str(&pu)->ptr;  	    u = html_quote(p);  	    if (DecodeURL) -		p = html_quote(url_unquote_conv(p, buf->document_charset)); +		p = html_quote(url_decode2(p, buf));  	    else  		p = u;  	    if (a->title && *a->title)  		t = html_quote(a->title); -	    else if (DecodeURL) -		t = html_quote(url_unquote_conv -			       (a->url, buf->document_charset));  	    else -		t = html_quote(a->url); +		t = html_quote(url_decode2(a->url, buf));  	    Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p,  			   "\n", NULL);  	    a = retrieveAnchor(buf->formitem, a->start.line, a->start.pos); @@ -842,19 +841,13 @@ link_list_panel(Buffer *buf)  		    p = parsedURL2Str(&pu)->ptr;  		    u = html_quote(p);  		    if (DecodeURL) -			p = html_quote(url_unquote_conv(p, -							buf-> -							document_charset)); +			p = html_quote(url_decode2(p, buf));  		    else  			p = u;  		    if (m->alt && *m->alt)  			t = html_quote(m->alt); -		    else if (DecodeURL) -			t = html_quote(url_unquote_conv(m->url, -							buf-> -							document_charset));  		    else -			t = html_quote(m->url); +			t = html_quote(url_decode2(m->url, buf));  		    Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t,  				   "</a><br>", p, "\n", NULL);  		} diff --git a/config.h.in b/config.h.in index 2f41eed..59997b4 100644 --- a/config.h.in +++ b/config.h.in @@ -25,6 +25,7 @@  #define PASSWD_FILE	RC_DIR "/passwd"  #define PRE_FORM_FILE	RC_DIR "/pre_form" +#define SITECONF_FILE	RC_DIR "/siteconf"  #define USER_MAILCAP	RC_DIR "/mailcap"  #define SYS_MAILCAP	CONF_DIR "/mailcap"  #define USER_MIMETYPES	"~/.mime.types" @@ -8986,7 +8986,7 @@ extern char *sys_errlist[];  int  main ()  { -printf(sys_errlist[0]); +printf("%s", sys_errlist[0]);    ;    return 0;  } @@ -257,7 +257,7 @@ make_lastline_link(Buffer *buf, char *title, char *url)      parseURL2(url, &pu, baseURL(buf));      u = parsedURL2Str(&pu);      if (DecodeURL) -	u = Strnew_charp(url_unquote_conv(u->ptr, buf->document_charset)); +	u = Strnew_charp(url_decode2(u->ptr, buf));  #ifdef USE_M17N      u = checkType(u, &pr, NULL);  #endif diff --git a/doc-jp/README.siteconf b/doc-jp/README.siteconf new file mode 100644 index 0000000..58b51c7 --- /dev/null +++ b/doc-jp/README.siteconf @@ -0,0 +1,60 @@ +siteconf: サイト別カスタマイズ + +siteconf は、 URL のパターンと、それに紐付けられた設定から成ります。 +siteconf を使うと、サイト毎に文字コードを指定して "decode_url" +の出力を改善したり、 Google のリダイレクタを迂回して性能や +プライバシーを向上させたりすることができます。 + +デフォルトでは siteconf は ~/.w3m/siteconf から読み込まれます。 + +===== 構文 ===== + +url <url>|/<re-url>/|m@<re-url>@i [exact] +substitute_url "<destination-url>" +url_charset <charset> +no_referer_from on|off +no_referer_to on|off + +後ろの方に書かれたものが優先されます。 + +===== 例 ===== + +url "http://twitter.com/#!/" +substitute_url "http://mobile.twitter.com/" + +twitter.com をモバイルサイトに転送します。 + +url "http://your.bookmark.net/" +no_referer_from on + +your.bookmark.net から張ったリンクを辿る際に、 HTTP referer を +送らないようにします。 + +url "http://www.google.com/url?" exact +substitute_url "file:///cgi-bin/your-redirector.cgi?" + +Google のリダイレクタを local CGI に転送します。 + +url /^http:\/\/[a-z]*\.wikipedia\.org\// +url_charset utf-8 + +同時に "decode_url" オプションをオンにすると、 Wikipedia への +リンクを UTF-8 としてデコードして表示します。 + +===== 正規表現について ===== + +次の正規表現はいずれも同じ意味を表します。 + +/http:\/\/www\.example\.com\// +m/http:\/\/www\.example\.com\// +m@http://www\.example\.com/@ +m!http://www\.example\.com/! + +最後に 'i' 修飾子を付けると、大文字小文字を区別せずに照合を行います。 +例えば、 m@^http://www\.example\.com/abc/@i は以下のいずれとも一致します。 + +http://www.example.com/abc/ +http://www.example.com/Abc/ +http://www.example.com/ABC/ + +ただし、ホスト名の部分は常に小文字に変換してから比較します。 diff --git a/doc/README.siteconf b/doc/README.siteconf new file mode 100644 index 0000000..f173087 --- /dev/null +++ b/doc/README.siteconf @@ -0,0 +1,60 @@ +The siteconf: Site-specific preferences  + +The siteconf consists of URL patterns and preferences associated to them. +You can improve "decode_url" feature by giving charsets of URLs site by site, +or bypass Google's redirector for performance and your privacy. + +The siteconf is read from ~/.w3m/siteconf by default. + +===== The syntax ===== + +url <url>|/<re-url>/|m@<re-url>@i [exact] +substitute_url "<destination-url>" +url_charset <charset> +no_referer_from on|off +no_referer_to on|off + +The last match wins. + +===== Examples ===== + +url "http://twitter.com/#!/" +substitute_url "http://mobile.twitter.com/" + +This forwards the twitter.com to its mobile site. + +url "http://your.bookmark.net/" +no_referer_from on + +This prevents HTTP referers from being sent when you follow links +at the your.bookmark.net. + +url "http://www.google.com/url?" exact +substitute_url "file:///cgi-bin/your-redirector.cgi?" + +This forwards the Google's redirector to your local CGI. + +url /^http:\/\/[a-z]*\.wikipedia\.org\// +url_charset utf-8 + +When combinated with "decode_url" option turned on, links to +Wikipedia will be human-readable. + +===== Regular expressions notes ===== + +Following expressions are all equivalent: + +/http:\/\/www\.example\.com\// +m/http:\/\/www\.example\.com\// +m@http://www\.example\.com/@ +m!http://www\.example\.com/! + +With a trailing 'i' modifier, you can specify a case-insensitive match. +For example, m@^http://www\.example\.com/abc/@i matches to: + +http://www.example.com/abc/ +http://www.example.com/Abc/ +http://www.example.com/ABC/ + +Hostnames, however, are always converted to lowercases before compared. + @@ -47,11 +47,11 @@ static JMP_BUF AbortLoading;  static struct table *tables[MAX_TABLE];  static struct table_mode table_mode[MAX_TABLE]; -#ifdef USE_IMAGE +#if defined(USE_M17N) || defined(USE_IMAGE)  static ParsedURL *cur_baseURL = NULL; -#ifdef USE_M17N -static char cur_document_charset;  #endif +#ifdef USE_M17N +static wc_ces cur_document_charset = 0;  #endif  static Str cur_title; @@ -215,7 +215,6 @@ currentLn(Buffer *buf)  static Buffer *  loadSomething(URLFile *f, -	      char *path,  	      Buffer *(*loadproc) (URLFile *, Buffer *), Buffer *defaultbuf)  {      Buffer *buf; @@ -223,17 +222,23 @@ loadSomething(URLFile *f,      if ((buf = loadproc(f, defaultbuf)) == NULL)  	return NULL; -    buf->filename = path;      if (buf->buffername == NULL || buf->buffername[0] == '\0') {  	buf->buffername = checkHeader(buf, "Subject:"); -	if (buf->buffername == NULL) -	    buf->buffername = conv_from_system(lastFileName(path)); +	if (buf->buffername == NULL && buf->filename != NULL) +	    buf->buffername = conv_from_system(lastFileName(buf->filename));      }      if (buf->currentURL.scheme == SCM_UNKNOWN)  	buf->currentURL.scheme = f->scheme; -    buf->real_scheme = f->scheme;      if (f->scheme == SCM_LOCAL && buf->sourcefile == NULL) -	buf->sourcefile = path; +	buf->sourcefile = buf->filename; +    if (loadproc == loadHTMLBuffer +#ifdef USE_IMAGE +	|| loadproc == loadImageBuffer +#endif +       ) +	buf->type = "text/html"; +    else +	buf->type = "text/plain";      return buf;  } @@ -484,28 +489,6 @@ convertLine0(URLFile *uf, Str line, int mode)      return line;  } -/*  - * loadFile: load file to buffer - */ -Buffer * -loadFile(char *path) -{ -    Buffer *buf; -    URLFile uf; -    init_stream(&uf, SCM_LOCAL, NULL); -    examineFile(path, &uf); -    if (uf.stream == NULL) -	return NULL; -    buf = newBuffer(INIT_BUFFER_WIDTH); -    current_content_length = 0; -#ifdef USE_M17N -    content_charset = 0; -#endif -    buf = loadSomething(&uf, path, loadBuffer, buf); -    UFclose(&uf); -    return buf; -} -  int  matchattr(char *p, char *attr, int len, Str *value)  { @@ -1697,13 +1680,15 @@ getLinkNumberStr(int correction)  /*    * loadGeneralFile: load file to buffer   */ +#define DO_EXTERNAL ((Buffer *(*)(URLFile *, Buffer *))doExternal)  Buffer *  loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,  		int flag, FormList *volatile request)  {      URLFile f, *volatile of = NULL;      ParsedURL pu; -    Buffer *b = NULL, *(*volatile proc)() = loadBuffer; +    Buffer *b = NULL; +    Buffer *(*volatile proc)(URLFile *, Buffer *) = loadBuffer;      char *volatile tpath;      char *volatile t = "text/plain", *p, *volatile real_type = NULL;      Buffer *volatile t_buf = NULL; @@ -1730,7 +1715,22 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,      add_auth_cookie_flag = 0;      checkRedirection(NULL); +    load_doc: +    { +	const char *sc_redirect; +	parseURL2(tpath, &pu, current); +	sc_redirect = query_SCONF_SUBSTITUTE_URL(&pu); +	if (sc_redirect && *sc_redirect && checkRedirection(&pu)) { +	    tpath = (char *)sc_redirect; +	    request = NULL; +	    add_auth_cookie_flag = 0; +	    current = New(ParsedURL); +	    *current = pu; +	    status = HTST_NORMAL; +	    goto load_doc; +	} +    }      TRAP_OFF;      url_option.referer = referer;      url_option.flag = flag; @@ -1863,7 +1863,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,  	    /* 302: Found */  	    /* 303: See Other */  	    /* 307: Temporary Redirect (HTTP/1.1) */ -	    tpath = url_quote_conv(p, DocumentCharset); +	    tpath = url_encode(p, NULL, 0);  	    request = NULL;  	    UFclose(&f);  	    current = New(ParsedURL); @@ -2022,7 +2022,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,  	if (f.is_cgi && (p = checkHeader(t_buf, "Location:")) != NULL &&  	    checkRedirection(&pu)) {  	    /* document moved */ -	    tpath = url_quote_conv(remove_space(p), DocumentCharset); +	    tpath = url_encode(remove_space(p), NULL, 0);  	    request = NULL;  	    UFclose(&f);  	    add_auth_cookie_flag = 0; @@ -2123,10 +2123,6 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,      if (real_type == NULL)  	real_type = t;      proc = loadBuffer; -#ifdef USE_IMAGE -    cur_baseURL = New(ParsedURL); -    copyParsedURL(cur_baseURL, &pu); -#endif      current_content_length = 0;      if ((p = checkHeader(t_buf, "Content-Length:")) != NULL) @@ -2197,18 +2193,8 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,  #endif      else if (w3m_backend) ;      else if (!(w3m_dump & ~DUMP_FRAME) || is_dump_text_type(t)) { -	if (!do_download && doExternal(f, -				       pu.real_file ? pu.real_file : pu.file, -				       t, &b, t_buf)) { -	    if (b && b != NO_BUFFER) { -		b->real_scheme = f.scheme; -		b->real_type = real_type; -		if (b->currentURL.host == NULL && b->currentURL.file == NULL) -		    copyParsedURL(&b->currentURL, &pu); -	    } -	    UFclose(&f); -	    TRAP_OFF; -	    return b; +	if (!do_download && searchExtViewer(t) != NULL) { +	    proc = DO_EXTERNAL;  	}  	else {  	    TRAP_OFF; @@ -2232,36 +2218,30 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,      else if (w3m_dump & DUMP_FRAME)  	return NULL; +    if (t_buf == NULL) +	t_buf = newBuffer(INIT_BUFFER_WIDTH); +    copyParsedURL(&t_buf->currentURL, &pu); +    t_buf->filename = pu.real_file ? pu.real_file : +	pu.file ? conv_to_system(pu.file) : NULL;      if (flag & RG_FRAME) { -	if (t_buf == NULL) -	    t_buf = newBuffer(INIT_BUFFER_WIDTH);  	t_buf->bufferprop |= BP_FRAME;      }  #ifdef USE_SSL -    if (t_buf) -	t_buf->ssl_certificate = f.ssl_certificate; +    t_buf->ssl_certificate = f.ssl_certificate;  #endif      frame_source = flag & RG_FRAME_SRC; -    b = loadSomething(&f, pu.real_file ? pu.real_file : pu.file, proc, t_buf); +    if (proc == DO_EXTERNAL) { +	b = doExternal(f, t, t_buf); +    } else { +	b = loadSomething(&f, proc, t_buf); +    }      UFclose(&f);      frame_source = 0; -    if (b) { +    if (b && b != NO_BUFFER) {  	b->real_scheme = f.scheme;  	b->real_type = real_type; -	if (b->currentURL.host == NULL && b->currentURL.file == NULL) -	    copyParsedURL(&b->currentURL, &pu); -	if (is_html_type(t)) -	    b->type = "text/html"; -	else if (w3m_backend) { -	    Str s = Strnew_charp(t); -	    b->type = s->ptr; -	} -#ifdef USE_IMAGE -	else if (proc == loadImageBuffer) -	    b->type = "text/html"; -#endif -	else -	    b->type = "text/plain"; +	if (w3m_backend) +	    b->type = allocStr(t, -1);  	if (pu.label) {  	    if (proc == loadHTMLBuffer) {  		Anchor *a; @@ -2469,6 +2449,7 @@ set_breakpoint(struct readbuffer *obuf, int tag_length)      bcopy((void *)&obuf->anchor, (void *)&obuf->bp.anchor,  	  sizeof(obuf->anchor));      obuf->bp.img_alt = obuf->img_alt; +    obuf->bp.input_alt = obuf->input_alt;      obuf->bp.in_bold = obuf->in_bold;      obuf->bp.in_italic = obuf->in_italic;      obuf->bp.in_under = obuf->in_under; @@ -2486,6 +2467,7 @@ back_to_breakpoint(struct readbuffer *obuf)      bcopy((void *)&obuf->bp.anchor, (void *)&obuf->anchor,  	  sizeof(obuf->anchor));      obuf->img_alt = obuf->bp.img_alt; +    obuf->input_alt = obuf->bp.input_alt;      obuf->in_bold = obuf->bp.in_bold;      obuf->in_italic = obuf->bp.in_italic;      obuf->in_under = obuf->bp.in_under; @@ -2729,7 +2711,7 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent,      Str line = obuf->line, pass = NULL;      char *hidden_anchor = NULL, *hidden_img = NULL, *hidden_bold = NULL,  	*hidden_under = NULL, *hidden_italic = NULL, *hidden_strike = NULL, -	*hidden_ins = NULL, *hidden = NULL; +	*hidden_ins = NULL, *hidden_input, *hidden = NULL;  #ifdef DEBUG      if (w3m_debug) { @@ -2761,6 +2743,12 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent,  		hidden = hidden_img;  	}      } +    if (obuf->input_alt.in) { +	if ((hidden_input = has_hidden_link(obuf, HTML_INPUT_ALT)) != NULL) { +	    if (!hidden || hidden_input < hidden) +		hidden = hidden_input; +	} +    }      if (obuf->in_bold) {  	if ((hidden_bold = has_hidden_link(obuf, HTML_B)) != NULL) {  	    if (!hidden || hidden_bold < hidden) @@ -2812,6 +2800,8 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent,  	Strcat_charp(line, "</a>");      if (obuf->img_alt && !hidden_img)  	Strcat_charp(line, "</img_alt>"); +    if (obuf->input_alt.in && !hidden_input) +	Strcat_charp(line, "</input_alt>");      if (obuf->in_bold && !hidden_bold)  	Strcat_charp(line, "</b>");      if (obuf->in_italic && !hidden_italic) @@ -3022,6 +3012,18 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent,  	Strcat_charp(tmp, "\">");  	push_tag(obuf, tmp->ptr, HTML_IMG_ALT);      } +    if (!hidden_input && obuf->input_alt.in) { +	Str tmp; +	if (obuf->input_alt.hseq > 0) +	    obuf->input_alt.hseq = - obuf->input_alt.hseq; +	tmp = Sprintf("<INPUT_ALT hseq=\"%d\" fid=\"%d\" name=\"%s\" type=\"%s\" value=\"%s\">", +		     obuf->input_alt.hseq, +		     obuf->input_alt.fid, +		     obuf->input_alt.name->ptr, +		     obuf->input_alt.type->ptr, +		     obuf->input_alt.value->ptr); +	push_tag(obuf, tmp->ptr, HTML_INPUT_ALT); +    }      if (!hidden_bold && obuf->in_bold)  	push_tag(obuf, "<B>", HTML_B);      if (!hidden_italic && obuf->in_italic) @@ -3228,7 +3230,7 @@ process_img(struct parsed_tag *tag, int width)      if (!parsedtag_get_value(tag, ATTR_SRC, &p))  	return tmp; -    p = remove_space(p); +    p = url_encode(remove_space(p), cur_baseURL, cur_document_charset);      q = NULL;      parsedtag_get_value(tag, ATTR_ALT, &q);      if (!pseudoInlines && (q == NULL || (*q == '\0' && ignore_null_img_alt))) @@ -3322,12 +3324,7 @@ process_img(struct parsed_tag *tag, int width)  	    Image image;  	    ParsedURL u; -#ifdef USE_M17N -	    parseURL2(wc_conv(p, InnerCharset, cur_document_charset)->ptr, &u, -		      cur_baseURL); -#else  	    parseURL2(p, &u, cur_baseURL); -#endif  	    image.url = parsedURL2Str(&u)->ptr;  	    if (!uncompressed_file_type(u.file, &image.ext))  		image.ext = filename_extension(u.file, TRUE); @@ -3732,6 +3729,63 @@ process_input(struct parsed_tag *tag)  }  Str +process_button(struct parsed_tag *tag) +{ +    Str tmp = NULL; +    char *p, *q, *r, *qq = ""; +    int qlen, v; + +    if (cur_form_id < 0) { +       char *s = "<form_int method=internal action=none>"; +       tmp = process_form(parse_tag(&s, TRUE)); +    } +    if (tmp == NULL) +       tmp = Strnew(); + +    p = "submit"; +    parsedtag_get_value(tag, ATTR_TYPE, &p); +    q = NULL; +    parsedtag_get_value(tag, ATTR_VALUE, &q); +    r = ""; +    parsedtag_get_value(tag, ATTR_NAME, &r); + +    v = formtype(p); +    if (v == FORM_UNKNOWN) +       return NULL; + +    if (!q) { +       switch (v) { +       case FORM_INPUT_SUBMIT: +       case FORM_INPUT_BUTTON: +           q = "SUBMIT"; +           break; +       case FORM_INPUT_RESET: +           q = "RESET"; +           break; +       } +    } +    if (q) { +       qq = html_quote(q); +       qlen = strlen(q); +    } + +    //    Strcat_charp(tmp, "<pre_int>"); +    Strcat(tmp, Sprintf("<input_alt hseq=\"%d\" fid=\"%d\" type=%s " +                       "name=\"%s\" value=\"%s\">", +                       cur_hseq++, cur_form_id, p, html_quote(r), qq)); +    return tmp; +} + +Str +process_n_button(void) +{ +    Str tmp = Strnew(); +    Strcat_charp(tmp, "</input_alt>"); +    //    Strcat_charp(tmp, "</pre_int>"); +    return tmp; +} + +Str  process_select(struct parsed_tag *tag)  {      Str tmp = NULL; @@ -4084,6 +4138,7 @@ process_form_int(struct parsed_tag *tag, int fid)      parsedtag_get_value(tag, ATTR_METHOD, &p);      q = "!CURRENT_URL!";      parsedtag_get_value(tag, ATTR_ACTION, &q); +    q = url_encode(remove_space(q), cur_baseURL, cur_document_charset);      r = NULL;  #ifdef USE_M17N      if (parsedtag_get_value(tag, ATTR_ACCEPT_CHARSET, &r)) @@ -4861,7 +4916,35 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)  	    if (i > obuf->bottom_margin)  		obuf->bottom_margin = i;  	} +	if (parsedtag_get_value(tag, ATTR_HSEQ, &hseq)) { +	    obuf->input_alt.hseq = hseq; +	} +	if (parsedtag_get_value(tag, ATTR_FID, &i)) { +	    obuf->input_alt.fid = i; +	} +	if (parsedtag_get_value(tag, ATTR_TYPE, &p)) { +	    obuf->input_alt.type = Strnew_charp(p); +	} +	if (parsedtag_get_value(tag, ATTR_VALUE, &p)) { +	    obuf->input_alt.value = Strnew_charp(p); +	} +	if (parsedtag_get_value(tag, ATTR_NAME, &p)) { +	    obuf->input_alt.name = Strnew_charp(p); +	} +	obuf->input_alt.in = 1;  	return 0; +    case HTML_N_INPUT_ALT: +	if (obuf->input_alt.in) { +	    if (!close_effect0(obuf, HTML_INPUT_ALT)) +		push_tag(obuf, "</input_alt>", HTML_N_INPUT_ALT); +	    obuf->input_alt.hseq = 0; +	    obuf->input_alt.fid = -1; +	    obuf->input_alt.in = 0; +	    obuf->input_alt.type = NULL; +	    obuf->input_alt.name = NULL; +	    obuf->input_alt.value = NULL; +	} +	return 1;      case HTML_TABLE:  	close_anchor(h_env, obuf);  	obuf->table_level++; @@ -4970,6 +5053,16 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)      case HTML_INPUT:  	close_anchor(h_env, obuf);  	tmp = process_input(tag); +       if (tmp) +           HTMLlineproc1(tmp->ptr, h_env); +       return 1; +    case HTML_BUTTON: +       tmp = process_button(tag); +       if (tmp) +           HTMLlineproc1(tmp->ptr, h_env); +       return 1; +    case HTML_N_BUTTON: +       tmp = process_n_button();  	if (tmp)  	    HTMLlineproc1(tmp->ptr, h_env);  	return 1; @@ -5067,11 +5160,10 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env)  	}  	return 1;      case HTML_BASE: -#ifdef USE_IMAGE +#if defined(USE_M17N) || defined(USE_IMAGE)  	p = NULL;  	if (parsedtag_get_value(tag, ATTR_HREF, &p)) { -	    if (!cur_baseURL) -		cur_baseURL = New(ParsedURL); +	    cur_baseURL = New(ParsedURL);  	    parseURL(p, cur_baseURL, NULL);  	}  #endif @@ -5329,6 +5421,13 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  #ifdef MENU_SELECT      Anchor **a_select = NULL;  #endif +#if defined(USE_M17N) || defined(USE_IMAGE) +    ParsedURL *base = baseURL(buf); +#endif +#ifdef USE_M17N +    wc_ces name_charset = url_to_charset(NULL, &buf->currentURL, +					 buf->document_charset); +#endif      if (out_size == 0) {  	out_size = LINELEN; @@ -5523,16 +5622,17 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  		    hseq = 0;  		    id = NULL;  		    if (parsedtag_get_value(tag, ATTR_NAME, &id)) { -			id = url_quote_conv(id, buf->document_charset); +			id = url_quote_conv(id, name_charset);  			registerName(buf, id, currentLn(buf), pos);  		    }  		    if (parsedtag_get_value(tag, ATTR_HREF, &p)) -			p = url_quote_conv(remove_space(p), -					   buf->document_charset); +			p = url_encode(remove_space(p), base, +				       buf->document_charset);  		    if (parsedtag_get_value(tag, ATTR_TARGET, &q))  			q = url_quote_conv(q, buf->document_charset);  		    if (parsedtag_get_value(tag, ATTR_REFERER, &r)) -			r = url_quote_conv(r, buf->document_charset); +			r = url_encode(r, base, +				       buf->document_charset);  		    parsedtag_get_value(tag, ATTR_TITLE, &s);  		    parsedtag_get_value(tag, ATTR_ACCESSKEY, &t);  		    parsedtag_get_value(tag, ATTR_HSEQ, &hseq); @@ -5618,7 +5718,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  			    ParsedURL u;  			    Image *image; -			    parseURL2(a_img->url, &u, cur_baseURL); +			    parseURL2(a_img->url, &u, base);  			    a_img->image = image = New(Image);  			    image->url = parsedURL2Str(&u)->ptr;  			    if (!uncompressed_file_type(u.file, &image->ext)) @@ -5639,7 +5739,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  			    image->map = q;  			    image->ismap = ismap;  			    image->touch = 0; -			    image->cache = getImage(image, cur_baseURL, +			    image->cache = getImage(image, base,  						    IMG_FLAG_SKIP);  			}  			else if (iseq < 0) { @@ -5689,6 +5789,21 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  				putHmarker(buf->hmarklist, currentLn(buf),  					   hpos, hseq - 1);  			} +			else if (hseq < 0) { +			    int h = -hseq - 1; +			    int hpos = pos; +			    if (*str == '[') +				hpos++; +			    if (buf->hmarklist && +				h < buf->hmarklist->nmark && +				buf->hmarklist->marks[h].invalid) { +				buf->hmarklist->marks[h].pos = hpos; +				buf->hmarklist->marks[h].line = currentLn(buf); +				buf->hmarklist->marks[h].invalid = 0; +				hseq = -hseq; +			    } +			} +  			if (!form->target)  			    form->target = buf->baseTarget;  			if (a_textarea && @@ -5761,8 +5876,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  			break;  		    if (parsedtag_get_value(tag, ATTR_HREF, &p)) {  			MapArea *a; -			p = url_quote_conv(remove_space(p), -					   buf->document_charset); +			p = url_encode(remove_space(p), base, +				       buf->document_charset);  			t = NULL;  			parsedtag_get_value(tag, ATTR_TARGET, &t);  			q = ""; @@ -5811,11 +5926,14 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  		    break;  		case HTML_BASE:  		    if (parsedtag_get_value(tag, ATTR_HREF, &p)) { -			p = url_quote_conv(remove_space(p), -					   buf->document_charset); +			p = url_encode(remove_space(p), NULL, +				       buf->document_charset);  			if (!buf->baseURL)  			    buf->baseURL = New(ParsedURL);  			parseURL(p, buf->baseURL, NULL); +#if defined(USE_M17N) || defined(USE_IMAGE) +			base = buf->baseURL; +#endif  		    }  		    if (parsedtag_get_value(tag, ATTR_TARGET, &p))  			buf->baseTarget = @@ -5830,8 +5948,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  			int refresh_interval = getMetaRefreshParam(q, &tmp);  #ifdef USE_ALARM  			if (tmp) { -			    p = url_quote_conv(remove_space(tmp->ptr), -					       buf->document_charset); +			    p = url_encode(remove_space(tmp->ptr), base, +					   buf->document_charset);  			    buf->event = setAlarmEvent(buf->event,  						       refresh_interval,  						       AL_IMPLICIT_ONCE, @@ -5844,8 +5962,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  						       FUNCNAME_reload, NULL);  #else  			if (tmp && refresh_interval == 0) { -			    p = url_quote_conv(remove_space(tmp->ptr), -					       buf->document_charset); +			    p = url_encode(remove_space(tmp->ptr), base, +					   buf->document_charset);  			    pushEvent(FUNCNAME_gorURL, p);  			}  #endif @@ -5929,7 +6047,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit)  #ifdef	ID_EXT  		id = NULL;  		if (parsedtag_get_value(tag, ATTR_ID, &id)) { -		    id = url_quote_conv(id, buf->document_charset); +		    id = url_quote_conv(id, name_charset);  		    registerName(buf, id, currentLn(buf), pos);  		}  		if (renderFrameSet && @@ -5982,7 +6100,8 @@ addLink(Buffer *buf, struct parsed_tag *tag)      parsedtag_get_value(tag, ATTR_HREF, &href);      if (href) -	href = url_quote_conv(remove_space(href), buf->document_charset); +	href = url_encode(remove_space(href), baseURL(buf), +			  buf->document_charset);      parsedtag_get_value(tag, ATTR_TITLE, &title);      parsedtag_get_value(tag, ATTR_TYPE, &ctype);      parsedtag_get_value(tag, ATTR_REL, &rel); @@ -6756,6 +6875,12 @@ init_henv(struct html_feed_environ *h_env, struct readbuffer *obuf,      obuf->nobr_level = 0;      bzero((void *)&obuf->anchor, sizeof(obuf->anchor));      obuf->img_alt = 0; +    obuf->input_alt.hseq = 0; +    obuf->input_alt.fid = -1; +    obuf->input_alt.in = 0; +    obuf->input_alt.type = NULL; +    obuf->input_alt.name = NULL; +    obuf->input_alt.value = NULL;      obuf->in_bold = 0;      obuf->in_italic = 0;      obuf->in_under = 0; @@ -6791,6 +6916,15 @@ completeHTMLstream(struct html_feed_environ *h_env, struct readbuffer *obuf)  	push_tag(obuf, "</img_alt>", HTML_N_IMG_ALT);  	obuf->img_alt = NULL;      } +    if (obuf->input_alt.in) { +	push_tag(obuf, "</input_alt>", HTML_N_INPUT_ALT); +	obuf->input_alt.hseq = 0; +	obuf->input_alt.fid = -1; +	obuf->input_alt.in = 0; +	obuf->input_alt.type = NULL; +	obuf->input_alt.name = NULL; +	obuf->input_alt.value = NULL; +    }      if (obuf->in_bold) {  	push_tag(obuf, "</b>", HTML_N_B);  	obuf->in_bold = 0; @@ -6963,8 +7097,6 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal)  	image_flag = IMG_FLAG_AUTO;      else  	image_flag = IMG_FLAG_SKIP; -    if (newBuf->currentURL.file) -	cur_baseURL = baseURL(newBuf);  #endif      if (w3m_halfload) { @@ -6987,6 +7119,9 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal)  	htmlenv1.f = stdout;      else  	htmlenv1.buf = newTextLineList(); +#if defined(USE_M17N) || defined(USE_IMAGE) +    cur_baseURL = baseURL(newBuf); +#endif      if (SETJMP(AbortLoading) != 0) {  	HTMLlineproc1("<br>Transfer Interrupted!<br>", &htmlenv1); @@ -7048,7 +7183,7 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal)  	}  #endif  	lineBuf2 = convertLine(f, lineBuf2, HTML_MODE, &charset, doc_charset); -#if defined(USE_M17N) && defined(USE_IMAGE) +#ifdef USE_M17N  	cur_document_charset = charset;  #endif  	HTMLlineproc0(lineBuf2->ptr, &htmlenv1, internal); @@ -7060,6 +7195,12 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal)      obuf.status = R_ST_NORMAL;      completeHTMLstream(&htmlenv1, &obuf);      flushline(&htmlenv1, &obuf, 0, 2, htmlenv1.limit); +#if defined(USE_M17N) || defined(USE_IMAGE) +    cur_baseURL = NULL; +#endif +#ifdef USE_M17N +    cur_document_charset = 0; +#endif      if (htmlenv1.title)  	newBuf->buffername = htmlenv1.title;      if (w3m_halfdump) { @@ -7207,7 +7348,7 @@ loadGopherDir(URLFile *uf, ParsedURL *pu, wc_ces * charset)  	q = Strnew_m_charp("gopher://", host->ptr, ":", port->ptr,  			   "/", file->ptr, NULL)->ptr;  	Strcat_m_charp(tmp, "<a href=\"", -		       html_quote(url_quote_conv(q, *charset)), +		       html_quote(url_encode(q, NULL, *charset)),  		       "\">", p, html_quote(name->ptr + 1), "</a>\n", NULL);      } @@ -7331,6 +7472,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf)      URLFile f;      MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;      struct stat st; +    const ParsedURL *pu = newBuf ? &newBuf->currentURL : NULL;      loadImage(newBuf, IMG_FLAG_STOP);      image.url = uf->url; @@ -7338,8 +7480,8 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf)      image.width = -1;      image.height = -1;      image.cache = NULL; -    cache = getImage(&image, cur_baseURL, IMG_FLAG_AUTO); -    if (!cur_baseURL->is_nocache && cache->loaded & IMG_FLAG_LOADED && +    cache = getImage(&image, (ParsedURL *)pu, IMG_FLAG_AUTO); +    if (!(pu && pu->is_nocache) && cache->loaded & IMG_FLAG_LOADED &&  	!stat(cache->file, &st))  	goto image_buffer; @@ -7580,8 +7722,11 @@ openGeneralPagerBuffer(InputStream stream)  #ifdef USE_M17N      content_charset = 0;  #endif +    t_buf = newBuffer(INIT_BUFFER_WIDTH); +    copyParsedURL(&t_buf->currentURL, NULL); +    t_buf->currentURL.scheme = SCM_LOCAL; +    t_buf->currentURL.file = "-";      if (SearchHeader) { -	t_buf = newBuffer(INIT_BUFFER_WIDTH);  	readHeader(&uf, t_buf, TRUE, NULL);  	t = checkContentType(t_buf);  	if (t == NULL) @@ -7609,14 +7754,13 @@ openGeneralPagerBuffer(InputStream stream)  #ifdef USE_IMAGE      else if (activeImage && displayImage && !useExtImageViewer &&  	     !(w3m_dump & ~DUMP_FRAME) && !strncasecmp(t, "image/", 6)) { -	cur_baseURL = New(ParsedURL); -	parseURL("-", cur_baseURL, NULL);  	buf = loadImageBuffer(&uf, t_buf);  	buf->type = "text/html";      }  #endif      else { -	if (doExternal(uf, "-", t, &buf, t_buf)) { +	if (searchExtViewer(t)) { +	    buf = doExternal(uf, t, t_buf);  	    UFclose(&uf);  	    if (buf == NULL || buf == NO_BUFFER)  		return buf; @@ -7629,8 +7773,6 @@ openGeneralPagerBuffer(InputStream stream)  	}      }      buf->real_type = t; -    buf->currentURL.scheme = SCM_LOCAL; -    buf->currentURL.file = "-";      return buf;  } @@ -7823,9 +7965,8 @@ save2tmp(URLFile uf, char *tmpf)      return 0;  } -int -doExternal(URLFile uf, char *path, char *type, Buffer **bufp, -	   Buffer *defaultbuf) +Buffer * +doExternal(URLFile uf, char *type, Buffer *defaultbuf)  {      Str tmpf, command;      struct mailcap *mcap; @@ -7834,7 +7975,7 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp,      char *header, *src = NULL, *ext = uf.ext;      if (!(mcap = searchExtViewer(type))) -	return 0; +	return NULL;      if (mcap->nametemplate) {  	tmpf = unquote_mailcap(mcap->nametemplate, NULL, "", NULL, NULL); @@ -7867,15 +8008,13 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp,  	    UFclose(&uf);  	    myExec(command->ptr);  	} -	*bufp = NO_BUFFER; -	return 1; +	return NO_BUFFER;      }      else  #endif      {  	if (save2tmp(uf, tmpf->ptr) < 0) { -	    *bufp = NULL; -	    return 1; +	    return NULL;  	}      }      if (mcap->flags & (MAILCAP_HTMLOUTPUT | MAILCAP_COPIOUSOUTPUT)) { @@ -7918,14 +8057,13 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp,  	buf = NO_BUFFER;      }      if (buf && buf != NO_BUFFER) { -	buf->filename = path; -	if (buf->buffername == NULL || buf->buffername[0] == '\0') -	    buf->buffername = conv_from_system(lastFileName(path)); +	if ((buf->buffername == NULL || buf->buffername[0] == '\0') && +	    buf->filename) +	    buf->buffername = conv_from_system(lastFileName(buf->filename));  	buf->edit = mcap->edit;  	buf->mailcap = mcap;      } -    *bufp = buf; -    return 1; +    return buf;  }  static int @@ -264,6 +264,18 @@ extern int REV_LB[];  #define IMG_FLAG_ERROR		2  #define IMG_FLAG_DONT_REMOVE	4 +#define IS_EMPTY_PARSED_URL(pu) ((pu)->scheme == SCM_UNKNOWN && !(pu)->file) +#define SCONF_RESERVED		0 +#define SCONF_SUBSTITUTE_URL	1 +#define SCONF_URL_CHARSET	2 +#define SCONF_NO_REFERER_FROM	3 +#define SCONF_NO_REFERER_TO	4 +#define SCONF_N_FIELD		5 +#define query_SCONF_SUBSTITUTE_URL(pu) ((const char *)querySiteconf(pu, SCONF_SUBSTITUTE_URL)) +#define query_SCONF_URL_CHARSET(pu) ((const wc_ces *)querySiteconf(pu, SCONF_URL_CHARSET)) +#define query_SCONF_NO_REFERER_FROM(pu) ((const int *)querySiteconf(pu, SCONF_NO_REFERER_FROM)) +#define query_SCONF_NO_REFERER_TO(pu) ((const int *)querySiteconf(pu, SCONF_NO_REFERER_TO)) +  /*    * Macros.   */ @@ -562,6 +574,13 @@ typedef struct _DownloadList {  #define INIT_BUFFER_WIDTH ((_INIT_BUFFER_WIDTH > 0) ? _INIT_BUFFER_WIDTH : 0)  #define FOLD_BUFFER_WIDTH (FoldLine ? (INIT_BUFFER_WIDTH + 1) : -1) +struct input_alt_attr { +  int hseq; +  int fid; +  int in; +  Str type, name, value; +}; +  typedef struct {      int pos;      int len; @@ -569,6 +588,7 @@ typedef struct {      long flag;      Anchor anchor;      Str img_alt; +    struct input_alt_attr input_alt;      char fontstat[FONTSTAT_SIZE];      short nobr_level;      Lineprop prev_ctype; @@ -591,6 +611,7 @@ struct readbuffer {      short nobr_level;      Anchor anchor;      Str img_alt; +    struct input_alt_attr input_alt;      char fontstat[FONTSTAT_SIZE];      char fontstat_stack[FONT_STACK_SIZE][FONTSTAT_SIZE];      int fontstat_sp; @@ -972,6 +993,7 @@ global int BackgroundExtViewer init(TRUE);  global int disable_secret_security_check init(FALSE);  global char *passwd_file init(PASSWD_FILE);  global char *pre_form_file init(PRE_FORM_FILE); +global char *siteconf_file init(SITECONF_FILE);  global char *ftppasswd init(NULL);  global int ftppass_hostnamegen init(TRUE);  global int do_download init(FALSE); @@ -196,7 +196,7 @@ formtype(char *typestr)  	if (!strcasecmp(typestr, _formtypetbl[i]))  	    return i;      } -    return FORM_UNKNOWN; +    return FORM_INPUT_TEXT;  }  void @@ -787,7 +787,7 @@ struct pre_form {  static struct pre_form *PreForm = NULL;  static struct pre_form * -add_pre_form(struct pre_form *prev, char *url, char *name, char *action) +add_pre_form(struct pre_form *prev, char *url, Regex *re_url, char *name, char *action)  {      ParsedURL pu;      struct pre_form *new; @@ -796,21 +796,13 @@ add_pre_form(struct pre_form *prev, char *url, char *name, char *action)  	new = prev->next = New(struct pre_form);      else  	new = PreForm = New(struct pre_form); -    if (url && *url == '/') { -	int l = strlen(url); -	if (l > 1 && url[l - 1] == '/') -	    new->url = allocStr(url + 1, l - 2); -	else -	    new->url = url + 1; -	new->re_url = newRegex(new->url, FALSE, NULL, NULL); -	if (!new->re_url) -	    new->url = NULL; -    } -    else if (url) { +    if (url && !re_url) {  	parseURL2(url, &pu, NULL);  	new->url = parsedURL2Str(&pu)->ptr; -	new->re_url = NULL;      } +    else +	new->url = url; +    new->re_url = re_url;      new->name = (name && *name) ? name : NULL;      new->action = (action && *action) ? action : NULL;      new->item = NULL; @@ -834,7 +826,7 @@ add_pre_form_item(struct pre_form *pf, struct pre_form_item *prev, int type,      new->name = name;      new->value = value;      if (checked && *checked && (!strcmp(checked, "0") || -				strcasecmp(checked, "off") +				!strcasecmp(checked, "off")  				|| !strcasecmp(checked, "no")))  	new->checked = 0;      else @@ -875,6 +867,7 @@ loadPreForm(void)  	return;      while (1) {  	char *p, *s, *arg; +	Regex *re_arg;  	line = Strfgets(fp);  	if (line->length == 0) @@ -890,18 +883,20 @@ loadPreForm(void)  	if (*p == '#' || *p == '\0')  	    continue;		/* comment or empty line */  	s = getWord(&p); -	arg = getWord(&p);  	if (!strcmp(s, "url")) { +	    arg = getRegexWord((const char **)&p, &re_arg);  	    if (!arg || !*arg)  		continue;  	    p = getQWord(&p); -	    pf = add_pre_form(pf, arg, NULL, p); +	    pf = add_pre_form(pf, arg, re_arg, NULL, p);  	    pi = pf->item;  	    continue;  	}  	if (!pf)  	    continue; + +	arg = getWord(&p);  	if (!strcmp(s, "form")) {  	    if (!arg || !*arg)  		continue; @@ -913,7 +908,7 @@ loadPreForm(void)  	    }  	    if (pf->item) {  		struct pre_form *prev = pf; -		pf = add_pre_form(prev, "", s, p); +		pf = add_pre_form(prev, "", NULL, s, p);  		/* copy previous URL */  		pf->url = prev->url;  		pf->re_url = prev->re_url; @@ -91,7 +91,8 @@ newFrame(struct parsed_tag *tag, Buffer *buf)      body->baseURL = baseURL(buf);      if (tag) {  	if (parsedtag_get_value(tag, ATTR_SRC, &p)) -	    body->url = url_quote_conv(remove_space(p), buf->document_charset); +	    body->url = url_encode(remove_space(p), body->baseURL, +				   buf->document_charset);  	if (parsedtag_get_value(tag, ATTR_NAME, &p) && *p != '_')  	    body->name = url_quote_conv(p, buf->document_charset);      } @@ -639,7 +640,7 @@ createFrameFile(struct frameset *f, FILE * f1, Buffer *current, int level,  			case HTML_BASE:  			    /* "BASE" is prohibit tag */  			    if (parsedtag_get_value(tag, ATTR_HREF, &q)) { -				q = url_quote_conv(remove_space(q), charset); +				q = url_encode(remove_space(q), NULL, charset);  				parseURL(q, &base, NULL);  			    }  			    if (parsedtag_get_value(tag, ATTR_TARGET, &q)) { @@ -768,8 +769,8 @@ createFrameFile(struct frameset *f, FILE * f1, Buffer *current, int level,  				if (!tag->value[j])  				    break;  				tag->value[j] = -				    url_quote_conv(remove_space(tag->value[j]), -						   charset); +				    url_encode(remove_space(tag->value[j]), +					       &base, charset);  				tag->need_reconstruct = TRUE;  				parseURL2(tag->value[j], &url, &base);  				if (url.scheme == SCM_UNKNOWN || @@ -8,6 +8,7 @@  #include "fm.h"  #include "func.h"  #include "myctype.h" +#include "regex.h"  #include "funcname.c"  #include "functable.c" @@ -434,6 +435,93 @@ getQWord(char **str)      return tmp->ptr;  } +/* This extracts /regex/i or m@regex@i from the given string. + * Then advances *str to the end of regex. + * If the input does not seems to be a regex, this falls back to getQWord(). + *  + * Returns a word (no matter whether regex or not) in the give string. + * If regex_ret is non-NULL, compiles the regex and stores there. + * + * XXX: Actually this is unrelated to func.c. + */ +char * +getRegexWord(const char **str, Regex **regex_ret) +{ +    char *word = NULL; +    const char *p, *headp, *bodyp, *tailp; +    char delimiter; +    int esc; +    int igncase = 0; + +    p = *str; +    SKIP_BLANKS(p); +    headp = p; + +    /* Get the opening delimiter */ +    if (p[0] == 'm' && IS_PRINT(p[1]) && !IS_ALNUM(p[1]) && p[1] != '\\') { +	delimiter = p[1]; +	p += 2; +    } +    else if (p[0] == '/') { +	delimiter = '/'; +	p += 1; +    } +    else { +	goto not_regex; +    } +    bodyp = p; + +    /* Scan the end of the expression */ +    for (esc = 0; *p; ++p) { +	if (esc) { +	    esc = 0; +	} else { +	    if (*p == delimiter) +		break; +	    else if (*p == '\\') +		esc = 1; +	} +    } +    if (!*p && *headp == '/') +	goto not_regex; +    tailp = p; + +    /* Check the modifiers */ +    if (*p == delimiter) { +	while (*++p && !IS_SPACE(*p)) { +	    switch (*p) { +	    case 'i': +		igncase = 1; +		break; +	    } +	    /* ignore unknown modifiers */ +	} +    } + +    /* Save the expression */ +    word = allocStr(headp, p - headp); + +    /* Compile */ +    if (regex_ret) { +	if (*tailp == delimiter) +	    word[tailp - headp] = 0; +	*regex_ret = newRegex(word + (bodyp - headp), igncase, NULL, NULL); +	if (*tailp == delimiter) +	    word[tailp - headp] = delimiter; +    } +    goto last; + +not_regex: +    p = headp; +    word = getQWord((char **)&p); +    if (regex_ret) +	*regex_ret = NULL; + +last: +    *str = p; +    return word; +} +  #ifdef USE_MOUSE  static MouseAction default_mouse_action = {      NULL, @@ -17,7 +17,7 @@ historyBuffer(Hist *hist)  	for (item = hist->list->last; item; item = item->prev) {  	    q = html_quote((char *)item->ptr);  	    if (DecodeURL) -		p = html_quote(url_unquote_conv((char *)item->ptr, 0)); +		p = html_quote(url_decode2((char *)item->ptr, NULL));  	    else  		p = q;  	    Strcat_charp(src, "<li><a href=\""); @@ -56,6 +56,9 @@ unsigned char ALST_INPUT[] =      ATTR_CORE  };  #define MAXA_INPUT      MAXA_CORE + 12 +unsigned char ALST_BUTTON[] = +    { ATTR_TYPE, ATTR_VALUE, ATTR_NAME, ATTR_CORE }; +#define MAXA_BUTTON	MAXA_CORE + 3  unsigned char ALST_TEXTAREA[] =      { ATTR_COLS, ATTR_ROWS, ATTR_NAME, ATTR_READONLY, ATTR_CORE };  #define MAXA_TEXTAREA   MAXA_CORE + 4 @@ -247,24 +250,24 @@ TagInfo TagMAP[MAX_HTMLTAG] = {      {"/bdo", NULL, 0, TFLG_END},	/* 121 HTML_N_BDO */      {"big", ALST_NOP, MAXA_NOP, 0},		/* 122 HTML_BIG */      {"/big", NULL, 0, TFLG_END},	/* 123 HTML_N_BIG */ -    {"button", ALST_NOP, MAXA_NOP, 0},		/* 124 HTML_BUTTON */ -    {"fieldset", ALST_NOP, MAXA_NOP, 0},	        /* 125 HTML_FIELDSET */ -    {"/fieldset", NULL, 0, TFLG_END},	/* 126 HTML_N_FIELDSET */ -    {"iframe", ALST_NOP, MAXA_NOP, 0},		/* 127 HTML_IFRAME */ -    {"label", ALST_NOP, MAXA_NOP, 0}, 		/* 128 HTML_LABEL */ -    {"/label", NULL, 0, TFLG_END},	/* 129 HTML_N_LABEL */ -    {"legend", ALST_NOP, MAXA_NOP, 0},		/* 130 HTML_LEGEND */ -    {"/legend", NULL, 0, TFLG_END},	/* 131 HTML_N_LEGEND */ -    {"noscript", ALST_NOP, MAXA_NOP, 0},	        /* 132 HTML_NOSCRIPT */ -    {"/noscript", NULL, 0, TFLG_END},	/* 133 HTML_N_NOSCRIPT */ -    {"object", ALST_NOP, MAXA_NOP, 0},		/* 134 HTML_OBJECT */ -    {"optgroup", ALST_NOP, MAXA_NOP, 0},	        /* 135 HTML_OPTGROUP */ -    {"/optgroup", NULL, 0, TFLG_END},	/* 136 HTML_N_OPTGROUP */ -    {"param", ALST_NOP, MAXA_NOP, 0},		/* 137 HTML_PARAM */ -    {"small", ALST_NOP, MAXA_NOP, 0}, 		/* 138 HTML_SMALL */ -    {"/small", NULL, 0, TFLG_END},	/* 139 HTML_N_SMALL */ +    {"button", ALST_BUTTON, MAXA_BUTTON, 0},	/* 124 HTML_BUTTON */ +    {"/button", NULL, 0, TFLG_END},	/* 125 HTML_N_BUTTON */ +    {"fieldset", ALST_NOP, MAXA_NOP, 0},	/* 126 HTML_FIELDSET */ +    {"/fieldset", NULL, 0, TFLG_END},	/* 127 HTML_N_FIELDSET */ +    {"iframe", ALST_NOP, MAXA_NOP, 0},		/* 128 HTML_IFRAME */ +    {"label", ALST_NOP, MAXA_NOP, 0}, 		/* 129 HTML_LABEL */ +    {"/label", NULL, 0, TFLG_END},	/* 130 HTML_N_LABEL */ +    {"legend", ALST_NOP, MAXA_NOP, 0},		/* 131 HTML_LEGEND */ +    {"/legend", NULL, 0, TFLG_END},	/* 132 HTML_N_LEGEND */ +    {"noscript", ALST_NOP, MAXA_NOP, 0},	        /* 133 HTML_NOSCRIPT */ +    {"/noscript", NULL, 0, TFLG_END},	/* 134 HTML_N_NOSCRIPT */ +    {"object", ALST_NOP, MAXA_NOP, 0},		/* 135 HTML_OBJECT */ +    {"optgroup", ALST_NOP, MAXA_NOP, 0},	        /* 136 HTML_OPTGROUP */ +    {"/optgroup", NULL, 0, TFLG_END},	/* 137 HTML_N_OPTGROUP */ +    {"param", ALST_NOP, MAXA_NOP, 0},		/* 138 HTML_PARAM */ +    {"small", ALST_NOP, MAXA_NOP, 0}, 		/* 139 HTML_SMALL */ +    {"/small", NULL, 0, TFLG_END},	/* 140 HTML_N_SMALL */ -    {NULL, NULL, 0, 0},		/* 140 Undefined */      {NULL, NULL, 0, 0},		/* 141 Undefined */      {NULL, NULL, 0, 0},		/* 142 Undefined */      {NULL, NULL, 0, 0},		/* 143 Undefined */ @@ -214,21 +214,22 @@ typedef struct {  #define HTML_BIG        122  #define HTML_N_BIG      123  #define HTML_BUTTON     124 -#define HTML_FIELDSET   125 -#define HTML_N_FIELDSET 126 -#define HTML_IFRAME     127 -#define HTML_LABEL      128 -#define HTML_N_LABEL    129 -#define HTML_LEGEND     130 -#define HTML_N_LEGEND   131 -#define HTML_NOSCRIPT   132 -#define HTML_N_NOSCRIPT 133 -#define HTML_OBJECT     134 -#define HTML_OPTGROUP   135 -#define HTML_N_OPTGROUP 136 -#define HTML_PARAM      137 -#define HTML_SMALL      138 -#define HTML_N_SMALL    139 +#define HTML_N_BUTTON   125 +#define HTML_FIELDSET   126 +#define HTML_N_FIELDSET 127 +#define HTML_IFRAME     128 +#define HTML_LABEL      129 +#define HTML_N_LABEL    130 +#define HTML_LEGEND     131 +#define HTML_N_LEGEND   132 +#define HTML_NOSCRIPT   133 +#define HTML_N_NOSCRIPT 134 +#define HTML_OBJECT     135 +#define HTML_OPTGROUP   136 +#define HTML_N_OPTGROUP 137 +#define HTML_PARAM      138 +#define HTML_SMALL      139 +#define HTML_N_SMALL    140     /* pseudo tag */  #define HTML_SELECT_INT     160 @@ -357,6 +357,20 @@ strcasemstr(char *str, char *srch[], char **ret_ptr)      return -1;  } +int +strmatchlen(const char *s1, const char *s2, int maxlen) +{ +    int i; + +    /* To allow the maxlen to be negatie (infinity), +     * compare by "!=" instead of "<=". */ +    for (i = 0; i != maxlen; ++i) { +	if (!s1[i] || !s2[i] || s1[i] != s2[i]) +	    break; +    } +    return i; +} +  char *  remove_space(char *str)  { @@ -52,6 +52,7 @@ extern int strncasecmp(const char *s1, const char *s2, size_t n);  extern char *strcasestr(const char *s1, const char *s2);  #endif  extern int strcasemstr(char *str, char *srch[], char **ret_ptr); +int strmatchlen(const char *s1, const char *s2, int maxlen);  extern char *remove_space(char *str);  extern int non_null(char *s);  extern void cleanup_line(Str s, int mode); @@ -22,8 +22,8 @@  static void basic_close(int *handle);  static int basic_read(int *handle, char *buf, int len); -static void file_close(struct file_handle *handle); -static int file_read(struct file_handle *handle, char *buf, int len); +static void file_close(struct io_file_handle *handle); +static int file_read(struct io_file_handle *handle, char *buf, int len);  static int str_read(Str handle, char *buf, int len); @@ -114,7 +114,7 @@ newFileStream(FILE * f, void (*closep) ())      stream = New(union input_stream);      init_base_stream(&stream->base, STREAM_BUF_SIZE);      stream->file.type = IST_FILE; -    stream->file.handle = New(struct file_handle); +    stream->file.handle = New(struct io_file_handle);      stream->file.handle->f = f;      if (closep)  	stream->file.handle->close = closep; @@ -658,13 +658,13 @@ basic_read(int *handle, char *buf, int len)  }  static void -file_close(struct file_handle *handle) +file_close(struct io_file_handle *handle)  {      handle->close(handle->f);  }  static int -file_read(struct file_handle *handle, char *buf, int len) +file_read(struct io_file_handle *handle, char *buf, int len)  {      return fread(buf, 1, len, handle->f);  } @@ -20,7 +20,7 @@ struct stream_buffer {  typedef struct stream_buffer *StreamBuffer; -struct file_handle { +struct io_file_handle {      FILE *f;      void (*close) ();  }; @@ -53,7 +53,7 @@ struct base_stream {  struct file_stream {      struct stream_buffer stream; -    struct file_handle *handle; +    struct io_file_handle *handle;      char type;      char iseos;      int (*read) (); @@ -91,7 +91,7 @@ unsigned char EscBKeymap[128] = {      /*  0       1       2       3       4       5       6       7        */      nulcmd, nulcmd, nulcmd, nulcmd, nulcmd, nulcmd, nulcmd, nulcmd,      /*  8       9       :       ;       <       =       >       ?        */ -    nulcmd, nulcmd, nulcmd, nulcmd, nulcmd, nulcmd, nulcmd, nulcmd, +    nulcmd, nulcmd, nulcmd, nulcmd, sgrmouse, nulcmd, nulcmd, nulcmd,      /*  @       A       B       C       D       E       F       G        */      nulcmd, movU, movD, movR, movL, nulcmd, goLineL, pgFore,      /*  H       I       J       K       L       M       N       O        */ @@ -1026,7 +1026,7 @@ _prev(void)  	strCurrentBuf = strBuf;      }      if (DecodeURL && (cm_mode & CPL_URL) ) -	p = url_unquote_conv(p, 0); +	p = url_decode2(p, NULL);      strBuf = Strnew_charp(p);      CLen = CPos = setStrType(strBuf, strProp);      offset = 0; @@ -1045,7 +1045,7 @@ _next(void)      p = nextHist(hist);      if (p) {  	if (DecodeURL && (cm_mode & CPL_URL) ) -	    p = url_unquote_conv(p, 0); +	    p = url_decode2(p, NULL);  	strBuf = Strnew_charp(p);      }      else { @@ -200,10 +200,12 @@ fusage(FILE * f, int err)  #ifdef USE_M17N      fprintf(f, "    -I charset       document charset\n");      fprintf(f, "    -O charset       display/output charset\n"); +#if 0				/* use -O{s|j|e} instead */      fprintf(f, "    -e               EUC-JP\n");      fprintf(f, "    -s               Shift_JIS\n");      fprintf(f, "    -j               JIS\n");  #endif +#endif      fprintf(f, "    -B               load bookmark\n");      fprintf(f, "    -bookmark file   specify bookmark file\n");      fprintf(f, "    -T type          specify content-type\n"); @@ -248,7 +250,11 @@ fusage(FILE * f, int err)  #endif				/* USE_COOKIE */      fprintf(f, "    -graph           use DEC special graphics for border of table and menu\n");      fprintf(f, "    -no-graph        use ACII character for border of table and menu\n"); +#if 1				/* pager requires -s */ +    fprintf(f, "    -s               squeeze multiple blank lines\n"); +#else      fprintf(f, "    -S               squeeze multiple blank lines\n"); +#endif      fprintf(f, "    -W               toggle wrap search mode\n");      fprintf(f, "    -X               don't use termcap init/deinit\n");      fprintf(f, @@ -311,7 +317,11 @@ wrap_GC_warn_proc(char *msg, GC_word arg)  	    lock = 0;  	}      } +#if GC_VERSION_MAJOR >= 7 && GC_VERSION_MINOR >= 2 +    else if (orig_GC_warn_proc = GC_get_warn_proc()) +#else      else if (orig_GC_warn_proc) +#endif  	orig_GC_warn_proc(msg, arg);      else  	fprintf(stderr, msg, (unsigned long)arg); @@ -530,12 +540,14 @@ main(int argc, char **argv, char **envp)  		    PagerMax = atoi(argv[i]);  	    }  #ifdef USE_M17N +#if 0				/* use -O{s|j|e} instead */  	    else if (!strcmp("-s", argv[i]))  		DisplayCharset = WC_CES_SHIFT_JIS;  	    else if (!strcmp("-j", argv[i]))  		DisplayCharset = WC_CES_ISO_2022_JP;  	    else if (!strcmp("-e", argv[i]))  		DisplayCharset = WC_CES_EUC_JP; +#endif  	    else if (!strncmp("-I", argv[i], 2)) {  		if (argv[i][2] != '\0')  		    p = argv[i] + 2; @@ -703,7 +715,11 @@ main(int argc, char **argv, char **envp)  		accept_cookie = TRUE;  	    }  #endif				/* USE_COOKIE */ +#if 1				/* pager requires -s */ +	    else if (!strcmp("-s", argv[i])) +#else  	    else if (!strcmp("-S", argv[i])) +#endif  		squeezeBlankLine = TRUE;  	    else if (!strcmp("-X", argv[i]))  		Do_not_use_ti_te = TRUE; @@ -833,7 +849,11 @@ main(int argc, char **argv, char **envp)      mySignal(SIGPIPE, SigPipe);  #endif +#if GC_VERSION_MAJOR >= 7 && GC_VERSION_MINOR >= 2 +    GC_set_warn_proc(wrap_GC_warn_proc); +#else      orig_GC_warn_proc = GC_set_warn_proc(wrap_GC_warn_proc); +#endif      err_msg = Strnew();      if (load_argc == 0) {  	/* no URL specified */ @@ -894,12 +914,17 @@ main(int argc, char **argv, char **envp)  	if (i >= 0) {  	    SearchHeader = search_header;  	    DefaultType = default_type; +	    char *url; +	     +	    url = load_argv[i]; +	    if (getURLScheme(&url) == SCM_MISSING && !ArgvIsURL) +		url = file_to_url(load_argv[i]); +	    else +		url = url_encode(conv_from_system(load_argv[i]), NULL, 0);  	    if (w3m_dump == DUMP_HEAD) {  		request = New(FormList);  		request->method = FORM_METHOD_HEAD; -		newbuf = -		    loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0, -				    request); +		newbuf = loadGeneralFile(url, NULL, NO_REFERER, 0, request);  	    }  	    else {  		if (post_file && i == 0) { @@ -928,9 +953,7 @@ main(int argc, char **argv, char **envp)  		else {  		    request = NULL;  		} -		newbuf = -		    loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0, -				    request); +		newbuf = loadGeneralFile(url, NULL, NO_REFERER, 0, request);  	    }  	    if (newbuf == NULL) {  		/* FIXME: gettextize? */ @@ -945,7 +968,7 @@ main(int argc, char **argv, char **envp)  		break;  	    case SCM_LOCAL:  	    case SCM_LOCAL_CGI: -		unshiftHist(LoadHist, conv_from_system(load_argv[i])); +		unshiftHist(LoadHist, url);  	    default:  		pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr);  		break; @@ -1280,15 +1303,12 @@ do_dump(Buffer *buf)  	    qsort(in_order, nanchor, sizeof(Anchor *), cmp_anchor_hseq);  	    for (i = 0; i < nanchor; i++) {  		ParsedURL pu; -		static Str s = NULL; +		char *url;  		if (in_order[i]->slave)  		    continue;  		parseURL2(in_order[i]->url, &pu, baseURL(buf)); -		s = parsedURL2Str(&pu); -		if (DecodeURL) -		    s = Strnew_charp(url_unquote_conv -				     (s->ptr, Currentbuf->document_charset)); -		printf("[%d] %s\n", in_order[i]->hseq + 1, s->ptr); +		url = url_decode2(parsedURL2Str(&pu)->ptr, Currentbuf); +		printf("[%d] %s\n", in_order[i]->hseq + 1, url);  	    }  	}      } @@ -2272,7 +2292,7 @@ DEFUN(movR1, MOVE_RIGHT1,  static wc_uint32  getChar(char *p)  { -    return wc_any_to_ucs(wtf_parse1(&p)); +    return wc_any_to_ucs(wtf_parse1((wc_uchar **)&p));  }  static int @@ -2815,12 +2835,15 @@ loadLink(char *url, char *target, char *referer, FormList *request)      union frameset_element *f_element = NULL;      int flag = 0;      ParsedURL *base, pu; +    const int *no_referer_ptr;      message(Sprintf("loading %s", url)->ptr, 0, 0);      refresh(); +    no_referer_ptr = query_SCONF_NO_REFERER_FROM(&Currentbuf->currentURL);      base = baseURL(Currentbuf); -    if (base == NULL || +    if ((no_referer_ptr && *no_referer_ptr) || +	base == NULL ||  	base->scheme == SCM_LOCAL || base->scheme == SCM_LOCAL_CGI)  	referer = NO_REFERER;      if (referer == NULL) @@ -4066,6 +4089,7 @@ goURL0(char *prompt, int relative)      char *url, *referer;      ParsedURL p_url, *current;      Buffer *cur_buf = Currentbuf; +    const int *no_referer_ptr;      url = searchKeyData();      if (url == NULL) { @@ -4075,11 +4099,8 @@ goURL0(char *prompt, int relative)  	current = baseURL(Currentbuf);  	if (current) {  	    char *c_url = parsedURL2Str(current)->ptr; -	    if (DefaultURLString == DEFAULT_URL_CURRENT) { -		url = c_url; -		if (DecodeURL) -		    url = url_unquote_conv(url, 0); -	    } +	    if (DefaultURLString == DEFAULT_URL_CURRENT) +		url = url_decode2(c_url, NULL);  	    else  		pushHist(hist, c_url);  	} @@ -4088,11 +4109,8 @@ goURL0(char *prompt, int relative)  	    char *a_url;  	    parseURL2(a->url, &p_url, current);  	    a_url = parsedURL2Str(&p_url)->ptr; -	    if (DefaultURLString == DEFAULT_URL_LINK) { -		url = a_url; -		if (DecodeURL) -		    url = url_unquote_conv(url, Currentbuf->document_charset); -	    } +	    if (DefaultURLString == DEFAULT_URL_LINK) +		url = url_decode2(a_url, Currentbuf);  	    else  		pushHist(hist, a_url);  	} @@ -4100,15 +4118,22 @@ goURL0(char *prompt, int relative)  	if (url != NULL)  	    SKIP_BLANKS(url);      } -#ifdef USE_M17N -    if (url != NULL) { -	if ((relative || *url == '#') && Currentbuf->document_charset) -	    url = wc_conv_strict(url, InnerCharset, -				 Currentbuf->document_charset)->ptr; +    if (relative) { +	no_referer_ptr = query_SCONF_NO_REFERER_FROM(&Currentbuf->currentURL); +	current = baseURL(Currentbuf); +	if ((no_referer_ptr && *no_referer_ptr) || +	    current == NULL || +	    current->scheme == SCM_LOCAL || current->scheme == SCM_LOCAL_CGI) +	    referer = NO_REFERER;  	else -	    url = conv_to_system(url); +	    referer = parsedURL2Str(&Currentbuf->currentURL)->ptr; +	url = url_encode(url, current, Currentbuf->document_charset); +    } +    else { +	current = NULL; +	referer = NULL; +	url = url_encode(url, NULL, 0);      } -#endif      if (url == NULL || *url == '\0') {  	displayBuffer(Currentbuf, B_FORCE_REDRAW);  	return; @@ -4117,14 +4142,6 @@ goURL0(char *prompt, int relative)  	gotoLabel(url + 1);  	return;      } -    if (relative) { -	current = baseURL(Currentbuf); -	referer = parsedURL2Str(&Currentbuf->currentURL)->ptr; -    } -    else { -	current = NULL; -	referer = NULL; -    }      parseURL2(url, &p_url, current);      pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);      cmd_loadURL(url, current, referer, NULL); @@ -4521,8 +4538,7 @@ _peekURL(int only_img)  	s = parsedURL2Str(&pu);      }      if (DecodeURL) -	s = Strnew_charp(url_unquote_conv -			 (s->ptr, Currentbuf->document_charset)); +	s = Strnew_charp(url_decode2(s->ptr, Currentbuf));  #ifdef USE_M17N      s = checkType(s, &pp, NULL);      p = NewAtom_N(Lineprop, s->length); @@ -4581,7 +4597,7 @@ DEFUN(curURL, PEEK, "Peek current URL")  	offset = 0;  	s = currentURL();  	if (DecodeURL) -	    s = Strnew_charp(url_unquote_conv(s->ptr, 0)); +	    s = Strnew_charp(url_decode2(s->ptr, NULL));  #ifdef USE_M17N  	s = checkType(s, &pp, NULL);  	p = NewAtom_N(Lineprop, s->length); @@ -5409,6 +5425,58 @@ DEFUN(mouse, MOUSE, "mouse operation")      process_mouse(btn, x, y);  } +DEFUN(sgrmouse, SGRMOUSE, "SGR 1006 mouse operation") +{ +    int btn = 0, x = 0, y = 0; +    unsigned char c; + +    do { +	c = getch(); +	if (IS_DIGIT(c)) +	    btn = btn * 10 + c - '0'; +	else if (c == ';') +	    break; +	else +	    return; +    } while (1); + +#if defined(__CYGWIN__) && CYGWIN_VERSION_DLL_MAJOR < 1005 +    if (cygwin_mouse_btn_swapped) { +	if (btn == MOUSE_BTN2_DOWN) +	    btn = MOUSE_BTN3_DOWN; +	else if (btn == MOUSE_BTN3_DOWN) +	    btn = MOUSE_BTN2_DOWN; +    }; +#endif + +    do { +	c = getch(); +	if (IS_DIGIT(c)) +	    x = x * 10 + c - '0'; +	else if (c == ';') +	    break; +	else +	  return; +    } while (1); + +    do { +	c = getch(); +	if (IS_DIGIT(c)) +	    y = y * 10 + c - '0'; +	else if (c == 'M') +	    break; +	else if (c == 'm') { +	    btn |= 3; +	    break; +	} else +    return; +    } while (1); + +    if (x < 0 || x >= COLS || y < 0 || y > LASTLINE) +	return; +    process_mouse(btn, x, y); +} +  #ifdef USE_GPM  int  gpm_process_mouse(Gpm_Event * event, void *data) @@ -279,7 +279,7 @@ follow_map_panel(Buffer *buf, char *name)  	p = parsedURL2Str(&pu)->ptr;  	q = html_quote(p);  	if (DecodeURL) -	    p = html_quote(url_unquote_conv(p, buf->document_charset)); +	    p = html_quote(url_decode2(p, buf));  	else  	    p = q;  	Strcat_m_charp(mappage, "<tr valign=top><td><a href=\"", q, "\">", @@ -417,10 +417,7 @@ append_map_info(Buffer *buf, Str tmp, FormItemList *fi)  	    continue;  	parseURL2(a->url, &pu, baseURL(buf));  	q = html_quote(parsedURL2Str(&pu)->ptr); -	if (DecodeURL) -	    p = html_quote(url_unquote_conv(a->url, buf->document_charset)); -	else -	    p = html_quote(a->url); +	p = html_quote(url_decode2(a->url, buf));  	Strcat_m_charp(tmp, "<tr valign=top><td>  <td><a href=\"",  		       q, "\">",  		       html_quote(*a->alt ? a->alt : mybasename(a->url)), @@ -457,10 +454,8 @@ append_link_info(Buffer *buf, Str html, LinkList * link)  	    Strcat_charp(html, "[Rev]");  	if (!l->url)  	    url = "(empty)"; -	else if (DecodeURL) -	    url = html_quote(url_unquote_conv(l->url, buf->document_charset));  	else -	    url = html_quote(l->url); +	    url = html_quote(url_decode2(l->url, buf));  	Strcat_m_charp(html, "<td>", url, NULL);  	if (l->ctype)  	    Strcat_m_charp(html, " (", html_quote(l->ctype), ")", NULL); @@ -498,8 +493,7 @@ append_frame_info(Buffer *buf, Str html, struct frameset *set, int level)  		    Strcat_charp(html, p);  		}  		if (DecodeURL) -		    p = html_quote(url_unquote_conv(frame.body->url, -						    buf->document_charset)); +		    p = html_quote(url_decode2(frame.body->url, buf));  		else  		    p = q;  		Strcat_m_charp(html, " ", p, "</a></pre_int><br>\n", NULL); @@ -550,9 +544,7 @@ page_info_panel(Buffer *buf)  #ifdef USE_M17N      Strcat_charp(tmp, "<form method=internal action=charset>");  #endif -    p = parsedURL2Str(&buf->currentURL)->ptr; -    if (DecodeURL) -	p = url_unquote_conv(p, 0); +    p = url_decode2(parsedURL2Str(&buf->currentURL)->ptr, NULL);      Strcat_m_charp(tmp, "<table cellpadding=0>",  		   "<tr valign=top><td nowrap>Title<td>",  		   html_quote(buf->buffername), @@ -589,7 +581,7 @@ page_info_panel(Buffer *buf)  	p = parsedURL2Str(&pu)->ptr;  	q = html_quote(p);  	if (DecodeURL) -	    p = html_quote(url_unquote_conv(p, buf->document_charset)); +	    p = html_quote(url_decode2(p, buf));  	else  	    p = q;  	Strcat_m_charp(tmp, @@ -602,7 +594,7 @@ page_info_panel(Buffer *buf)  	p = parsedURL2Str(&pu)->ptr;  	q = html_quote(p);  	if (DecodeURL) -	    p = html_quote(url_unquote_conv(p, buf->document_charset)); +	    p = html_quote(url_decode2(p, buf));  	else  	    p = q;  	Strcat_m_charp(tmp, @@ -613,10 +605,7 @@ page_info_panel(Buffer *buf)      if (a != NULL) {  	FormItemList *fi = (FormItemList *)a->url;  	p = form2str(fi); -	if (DecodeURL) -	    p = html_quote(url_unquote_conv(p, buf->document_charset)); -	else -	    p = html_quote(p); +	p = html_quote(url_decode2(p, buf));  	Strcat_m_charp(tmp,  		       "<tr valign=top><td nowrap>Method/type of current form <td>",  		       p, NULL); @@ -1365,9 +1365,7 @@ initSelectMenu(void)  		break;  	    default:  		Strcat_char(str, ' '); -		p = parsedURL2Str(&buf->currentURL)->ptr; -		if (DecodeURL) -		    p = url_unquote_conv(p, 0); +		p = url_decode2(parsedURL2Str(&buf->currentURL)->ptr, NULL);  		Strcat_charp(str, p);  		break;  	    } @@ -1513,9 +1511,7 @@ initSelTabMenu(void)  	    case SCM_MISSING:  		break;  	    default: -		p = parsedURL2Str(&buf->currentURL)->ptr; -		if (DecodeURL) -		    p = url_unquote_conv(p, 0); +		p = url_decode2(parsedURL2Str(&buf->currentURL)->ptr, NULL);  		Strcat_charp(str, p);  		break;  	    } @@ -1845,10 +1841,8 @@ link_menu(Buffer *buf)  	    Strcat_charp(str, " ");  	if (!l->url)  	    p = ""; -	else if (DecodeURL) -	    p = url_unquote_conv(l->url, buf->document_charset);  	else -	    p = l->url; +	    p = url_decode2(l->url, buf);  	Strcat_charp(str, p);  	label[i] = str->ptr;  	if (len < str->length) @@ -407,6 +407,10 @@ msgid "File for setting form on loading"  msgstr "梧莨惹若荐絎<ゃ"  #: rc.c:149 +msgid "File for preferences for each site" +msgstr "泣ゃヨ┃絎<ゃ" + +#: rc.c:149  msgid "Password for anonymous FTP (your mail address)"  msgstr "FTP鴻若(mail address篏帥)" @@ -162,6 +162,24 @@ extern Str searchURIMethods(ParsedURL *pu);  extern void chkExternalURIBuffer(Buffer *buf);  #endif  extern ParsedURL *schemeToProxy(int scheme); +#ifdef USE_M17N +extern wc_ces url_to_charset(const char *url, const ParsedURL *base, +			     wc_ces doc_charset); +extern char *url_encode(const char *url, const ParsedURL *base, +			wc_ces doc_charset); +#if 0 +extern char *url_decode(const char *url, const ParsedURL *base, +			wc_ces doc_charset); +#endif +extern char *url_decode2(const char *url, const Buffer *buf); +#else /* !defined(USE_M17N) */ +#define url_encode(url, base, cs) url_quote(url) +extern char *url_decode0(const char *url); +#if 0 +#define url_decode(url, base, cs) url_decode0(url) +#endif +#define url_decode2(url, buf) url_decode0(url) +#endif /* !defined(USE_M17N) */  extern void examineFile(char *path, URLFile *uf);  extern char *acceptableEncoding();  extern int dir_exist(char *path); @@ -180,7 +198,6 @@ extern void push_symbol(Str str, char symbol, int width, int n);  #ifdef USE_UNICODE  extern void update_utf8_symbol(void);  #endif -extern Buffer *loadFile(char *path);  extern Buffer *loadGeneralFile(char *path, ParsedURL *current, char *referer,  			       int flag, FormList *request);  extern int is_boundary(unsigned char *, unsigned char *); @@ -207,6 +224,8 @@ extern int getImageSize(ImageCache * cache);  extern Str process_img(struct parsed_tag *tag, int width);  extern Str process_anchor(struct parsed_tag *tag, char *tagbuf);  extern Str process_input(struct parsed_tag *tag); +extern Str process_button(struct parsed_tag *tag); +extern Str process_n_button(void);  extern Str process_select(struct parsed_tag *tag);  extern Str process_n_select(void);  extern void feed_select(char *str); @@ -249,8 +268,7 @@ extern Buffer *openPagerBuffer(InputStream stream, Buffer *buf);  extern Buffer *openGeneralPagerBuffer(InputStream stream);  extern Line *getNextPage(Buffer *buf, int plen);  extern int save2tmp(URLFile uf, char *tmpf); -extern int doExternal(URLFile uf, char *path, char *type, Buffer **bufp, -		      Buffer *defaultbuf); +extern Buffer *doExternal(URLFile uf, char *type, Buffer *defaultbuf);  extern int _doFileCopy(char *tmpf, char *defstr, int download);  #define doFileCopy(tmpf, defstr) _doFileCopy(tmpf, defstr, FALSE);  extern int doFileMove(char *tmpf, char *defstr); @@ -507,7 +525,7 @@ extern ParsedURL *baseURL(Buffer *buf);  extern int openSocket(char *hostname, char *remoteport_name,  		      unsigned short remoteport_num);  extern void parseURL(char *url, ParsedURL *p_url, ParsedURL *current); -extern void copyParsedURL(ParsedURL *p, ParsedURL *q); +extern void copyParsedURL(ParsedURL *p, const ParsedURL *q);  extern void parseURL2(char *url, ParsedURL *pu, ParsedURL *current);  extern Str parsedURL2Str(ParsedURL *pu);  extern int getURLScheme(char **url); @@ -611,6 +629,7 @@ extern char *confFile(char *base);  extern char *auxbinFile(char *base);  extern char *libFile(char *base);  extern char *helpFile(char *base); +extern const void *querySiteconf(const ParsedURL *query_pu, int field);  extern Str localCookie(void);  extern Str loadLocalDir(char *dirname);  extern void set_environ(char *var, char *value); @@ -683,6 +702,7 @@ extern void reMark(void);  #ifdef USE_MOUSE  extern void mouse(void); +extern void sgrmouse(void);  extern void mouse_init(void);  extern void mouse_end(void);  extern void mouse_active(void); @@ -723,6 +743,8 @@ extern int getKey(char *s);  extern char *getKeyData(int key);  extern char *getWord(char **str);  extern char *getQWord(char **str); +struct regex; +extern char *getRegexWord(const char **str, struct regex **regex_ret);  #ifdef USE_MOUSE  extern void initMouseAction(void);  #endif @@ -9,7 +9,9 @@  #include <errno.h>  #include "parsetag.h"  #include "local.h" +#include "regex.h"  #include <stdlib.h> +#include <stddef.h>  struct param_ptr {      char *name; @@ -146,6 +148,7 @@ static int OptionEncode = FALSE;  #define CMT_DISABLE_SECRET_SECURITY_CHECK	N_("Disable secret file security check")  #define CMT_PASSWDFILE	 N_("Password file")  #define CMT_PRE_FORM_FILE	N_("File for setting form on loading") +#define CMT_SITECONF_FILE	N_("File for preferences for each site")  #define CMT_FTPPASS      N_("Password for anonymous FTP (your mail address)")  #define CMT_FTPPASS_HOSTNAMEGEN N_("Generate domain part of password for FTP")  #define CMT_USERAGENT    N_("User-Agent identification string") @@ -619,6 +622,8 @@ struct param_ptr params9[] = {       CMT_FTPPASS_HOSTNAMEGEN, NULL},      {"pre_form_file", P_STRING, PI_TEXT, (void *)&pre_form_file,       CMT_PRE_FORM_FILE, NULL}, +    {"siteconf_file", P_STRING, PI_TEXT, (void *)&siteconf_file, +     CMT_SITECONF_FILE, NULL},      {"user_agent", P_STRING, PI_TEXT, (void *)&UserAgent, CMT_USERAGENT, NULL},      {"no_referer", P_INT, PI_ONOFF, (void *)&NoSendReferer, CMT_NOSENDREFERER,       NULL}, @@ -1173,6 +1178,8 @@ do_mkdir(const char *dir, long mode)  #endif				/* not __MINW32_VERSION */  #endif				/* not __EMX__ */ +static void loadSiteconf(void); +  void  sync_with_option(void)  { @@ -1199,6 +1206,7 @@ sync_with_option(void)  #endif      loadPasswd();      loadPreForm(); +    loadSiteconf();      if (AcceptLang == NULL || *AcceptLang == '\0') {  	/* TRANSLATORS:  @@ -1556,3 +1564,217 @@ helpFile(char *base)      return expandPath(Strnew_m_charp(w3m_help_dir(), "/", base, NULL)->ptr);  }  #endif + +/* siteconf */ +/* + * url "<url>"|/<re-url>/|m@<re-url>@i [exact] + * substitute_url "<destination-url>" + * url_charset <charset> + * no_referer_from on|off + * no_referer_to on|off + *  + * The last match wins. + */ + +struct siteconf_rec { +    struct siteconf_rec *next; +    char *url; +    Regex *re_url; +    int url_exact; +    unsigned char mask[(SCONF_N_FIELD + 7) >> 3]; + +    char *substitute_url; +#ifdef USE_M17N +    wc_ces url_charset; +#endif +    int no_referer_from; +    int no_referer_to; +}; +#define SCONF_TEST(ent, f) ((ent)->mask[(f)>>3] & (1U<<((f)&7))) +#define SCONF_SET(ent, f) ((ent)->mask[(f)>>3] |= (1U<<((f)&7))) +#define SCONF_CLEAR(ent, f) ((ent)->mask[(f)>>3] &= ~(1U<<((f)&7))) + +static struct siteconf_rec *siteconf_head = NULL; +static struct siteconf_rec *newSiteconfRec(void); + +static struct siteconf_rec * +newSiteconfRec(void) +{ +    struct siteconf_rec *ent; + +    ent = New(struct siteconf_rec); +    ent->next = NULL; +    ent->url = NULL; +    ent->re_url = NULL; +    ent->url_exact = FALSE; +    memset(ent->mask, 0, sizeof(ent->mask)); + +    ent->substitute_url = NULL; +#ifdef USE_M17N +    ent->url_charset = 0; +#endif +    return ent; +} + +static void +loadSiteconf(void) +{ +    char *efname; +    FILE *fp; +    Str line; +    struct siteconf_rec *ent = NULL; + +    siteconf_head = NULL; +    if (!siteconf_file) +	return; +    if ((efname = expandPath(siteconf_file)) == NULL) +	return; +    fp = fopen(efname, "r"); +    if (fp == NULL) +	return; +    while (line = Strfgets(fp), line->length > 0) { +	char *p, *s; + +	Strchop(line); +	p = line->ptr; +	SKIP_BLANKS(p); +	if (*p == '#' || *p == '\0') +	    continue; +	s = getWord(&p); + +	/* The "url" begins a new record. */ +	if (strcmp(s, "url") == 0) { +	    char *url, *opt; +	    struct siteconf_rec *newent; + +	    /* First, register the current record. */ +	    if (ent) { +		ent->next = siteconf_head; +		siteconf_head = ent; +		ent = NULL; +	    } + +	    /* Second, create a new record. */ +	    newent = newSiteconfRec(); +	    url = getRegexWord((const char **)&p, &newent->re_url); +	    opt = getWord(&p); +	    SKIP_BLANKS(p); +	    if (!newent->re_url) { +		ParsedURL pu; +		if (!url || !*url) +		    continue; +		parseURL2(url, &pu, NULL); +		newent->url = parsedURL2Str(&pu)->ptr; +	    } +	    /* If we have an extra or unknown option, ignore this record +	     * for future extensions. */ +	    if (strcmp(opt, "exact") == 0) { +		newent->url_exact = TRUE; +	    } +	    else if (*opt != 0) +		    continue; +	    if (*p) +		continue; +	    ent = newent; +	    continue; +	} + +	/* If the current record is broken, skip to the next "url". */ +	if (!ent) +	    continue; + +	/* Fill the new record. */ +	if (strcmp(s, "substitute_url") == 0) { +	    ent->substitute_url = getQWord(&p); +	    SCONF_SET(ent, SCONF_SUBSTITUTE_URL); +	} +#ifdef USE_M17N +	else if (strcmp(s, "url_charset") == 0) { +	    char *charset = getWord(&p); +	    ent->url_charset = (charset && *charset) ? +		wc_charset_to_ces(charset) : 0; +	    SCONF_SET(ent, SCONF_URL_CHARSET); +	} +#endif /* USE_M17N */ +	else if (strcmp(s, "no_referer_from") == 0) { +	    ent->no_referer_from = str_to_bool(getWord(&p), 0); +	    SCONF_SET(ent, SCONF_NO_REFERER_FROM); +	} +	else if (strcmp(s, "no_referer_to") == 0) { +	    ent->no_referer_to = str_to_bool(getWord(&p), 0); +	    SCONF_SET(ent, SCONF_NO_REFERER_TO); +	} +    } +    if (ent) { +	ent->next = siteconf_head; +	siteconf_head = ent; +	ent = NULL; +    } +    fclose(fp); +} + +const void * +querySiteconf(const ParsedURL *query_pu, int field) +{ +    const struct siteconf_rec *ent; +    Str u; +    char *firstp, *lastp; + +    if (field < 0 || field >= SCONF_N_FIELD) +	return NULL; +    if (!query_pu || IS_EMPTY_PARSED_URL(query_pu)) +	return NULL; +    u = parsedURL2Str((ParsedURL *)query_pu); +    if (u->length == 0) +	return NULL; + +    for (ent = siteconf_head; ent; ent = ent->next) { +	if (!SCONF_TEST(ent, field)) +	    continue; +	if (ent->re_url) { +	    if (RegexMatch(ent->re_url, u->ptr, u->length, 1)) { +		MatchedPosition(ent->re_url, &firstp, &lastp); +		if (!ent->url_exact) +		    goto url_found; +		if (firstp != u->ptr || lastp == firstp) +		    continue; +		if (*lastp == 0 || *lastp == '?' || *(lastp - 1) == '?' || +		    *lastp == '#' || *(lastp - 1) == '#') +		    goto url_found; +	    } +	} else { +	    int matchlen = strmatchlen(ent->url, u->ptr, u->length); +	    if (matchlen == 0 || ent->url[matchlen] != 0) +		continue; +	    firstp = u->ptr; +	    lastp = u->ptr + matchlen; +	    if (*lastp == 0 || *lastp == '?' || *(lastp - 1) == '?' || +		*lastp == '#' || *(lastp - 1) == '#') +		goto url_found; +	    if (!ent->url_exact && (*lastp == '/' || *(lastp - 1) == '/')) +		goto url_found; +	} +    } +    return NULL; + +url_found: +    switch (field) { +    case SCONF_SUBSTITUTE_URL: +	if (ent->substitute_url && *ent->substitute_url) { +	    Str tmp = Strnew_charp_n(u->ptr, firstp - u->ptr); +	    Strcat_charp(tmp, ent->substitute_url); +	    Strcat_charp(tmp, lastp); +	    return tmp->ptr; +	} +	return NULL; +#ifdef USE_M17N +    case SCONF_URL_CHARSET: +	return &ent->url_charset; +#endif +    case SCONF_NO_REFERER_FROM: +	return &ent->no_referer_from; +    case SCONF_NO_REFERER_TO: +	return &ent->no_referer_to; +    } +    return NULL; +} @@ -2878,6 +2878,14 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode,  	tmp = process_input(tag);  	feed_table1(tbl, tmp, mode, width);  	break; +    case HTML_BUTTON: +       tmp = process_button(tag); +       feed_table1(tbl, tmp, mode, width); +       break; +    case HTML_N_BUTTON: +       tmp = process_n_button(); +       feed_table1(tbl, tmp, mode, width); +       break;      case HTML_SELECT:  	tmp = process_select(tag);  	if (tmp) diff --git a/tagtable.tab b/tagtable.tab index f9b7b76..f5a2c30 100644 --- a/tagtable.tab +++ b/tagtable.tab @@ -176,6 +176,7 @@ bdo		HTML_BDO  big		HTML_BIG  /big		HTML_N_BIG  button		HTML_BUTTON +/button		HTML_N_BUTTON  fieldset	HTML_FIELDSET  /fieldset	HTML_N_FIELDSET  iframe		HTML_IFRAME @@ -2027,8 +2027,8 @@ sleep_till_anykey(int sec, int purge)  #ifdef USE_MOUSE -#define XTERM_ON   {fputs("\033[?1001s\033[?1000h",ttyf); flush_tty();} -#define XTERM_OFF  {fputs("\033[?1000l\033[?1001r",ttyf); flush_tty();} +#define XTERM_ON   {fputs("\033[?1001s\033[?1000h\033[?1006h",ttyf); flush_tty();} +#define XTERM_OFF  {fputs("\033[?1006l\033[?1000l\033[?1001r",ttyf); flush_tty();}  #define CYGWIN_ON  {fputs("\033[?1000h",ttyf); flush_tty();}  #define CYGWIN_OFF {fputs("\033[?1000l",ttyf); flush_tty();} @@ -444,6 +444,8 @@ baseURL(Buffer *buf)  	/* <BASE> tag is defined in the document */  	return buf->baseURL;      } +    else if (IS_EMPTY_PARSED_URL(&buf->currentURL)) +	return NULL;      else  	return &buf->currentURL;  } @@ -638,16 +640,21 @@ openSocket(char *const hostname,  #define COPYPATH_SPC_ALLOW 0  #define COPYPATH_SPC_IGNORE 1  #define COPYPATH_SPC_REPLACE 2 +#define COPYPATH_SPC_MASK 3 +#define COPYPATH_LOWERCASE 4  static char *  copyPath(char *orgpath, int length, int option)  {      Str tmp = Strnew(); -    while (*orgpath && length != 0) { -	if (IS_SPACE(*orgpath)) { -	    switch (option) { +    char ch; +    while ((ch = *orgpath) != 0 && length != 0) { +	if (option & COPYPATH_LOWERCASE) +	    ch = TOLOWER(ch); +	if (IS_SPACE(ch)) { +	    switch (option & COPYPATH_SPC_MASK) {  	    case COPYPATH_SPC_ALLOW: -		Strcat_char(tmp, *orgpath); +		Strcat_char(tmp, ch);  		break;  	    case COPYPATH_SPC_IGNORE:  		/* do nothing */ @@ -658,7 +665,7 @@ copyPath(char *orgpath, int length, int option)  	    }  	}  	else -	    Strcat_char(tmp, *orgpath); +	    Strcat_char(tmp, ch);  	orgpath++;  	length--;      } @@ -668,22 +675,14 @@ copyPath(char *orgpath, int length, int option)  void  parseURL(char *url, ParsedURL *p_url, ParsedURL *current)  { -    char *p, *q; +    char *p, *q, *qq;      Str tmp;      url = url_quote(url);	/* quote 0x01-0x20, 0x7F-0xFF */      p = url; +    copyParsedURL(p_url, NULL);      p_url->scheme = SCM_MISSING; -    p_url->port = 0; -    p_url->user = NULL; -    p_url->pass = NULL; -    p_url->host = NULL; -    p_url->is_nocache = 0; -    p_url->file = NULL; -    p_url->real_file = NULL; -    p_url->query = NULL; -    p_url->label = NULL;      /* RFC1808: Relative Uniform Resource Locators       * 4.  Resolving Relative URLs @@ -694,7 +693,7 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)  	goto do_label;      }  #if defined( __EMX__ ) || defined( __CYGWIN__ ) -    if (!strncmp(url, "file://localhost/", 17)) { +    if (!strncasecmp(url, "file://localhost/", 17)) {  	p_url->scheme = SCM_LOCAL;  	p += 17 - 1;  	url += 17 - 1; @@ -802,19 +801,20 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)  	/* scheme://user:pass@host or  	 * scheme://host:port  	 */ -	p_url->host = copyPath(q, p - q, COPYPATH_SPC_IGNORE); +	qq = q;  	q = ++p;  	while (*p && strchr("@/?#", *p) == NULL)  	    p++;  	if (*p == '@') {  	    /* scheme://user:pass@...       */ +	    p_url->user = copyPath(qq, q - 1 - qq, COPYPATH_SPC_IGNORE);  	    p_url->pass = copyPath(q, p - q, COPYPATH_SPC_ALLOW);  	    q = ++p; -	    p_url->user = p_url->host; -	    p_url->host = NULL;  	    goto analyze_url;  	}  	/* scheme://host:port/ */ +	p_url->host = copyPath(qq, q - 1 - qq, +			       COPYPATH_SPC_IGNORE | COPYPATH_LOWERCASE);  	tmp = Strnew_charp_n(q, p - q);  	p_url->port = atoi(tmp->ptr);  	/* *p is one of ['\0', '/', '?', '#'] */ @@ -829,7 +829,8 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)      case '/':      case '?':      case '#': -	p_url->host = copyPath(q, p - q, COPYPATH_SPC_IGNORE); +	p_url->host = copyPath(q, p - q, +			       COPYPATH_SPC_IGNORE | COPYPATH_LOWERCASE);  	p_url->port = DefaultPort[p_url->scheme];  	break;      } @@ -956,12 +957,16 @@ parseURL(char *url, ParsedURL *p_url, ParsedURL *current)  	p_url->label = NULL;  } -#define initParsedURL(p) bzero(p,sizeof(ParsedURL))  #define ALLOC_STR(s) ((s)==NULL?NULL:allocStr(s,-1))  void -copyParsedURL(ParsedURL *p, ParsedURL *q) +copyParsedURL(ParsedURL *p, const ParsedURL *q)  { +    if (q == NULL) { +	memset(p, 0, sizeof(ParsedURL)); +	p->scheme = SCM_UNKNOWN; +	return; +    }      p->scheme = q->scheme;      p->port = q->port;      p->is_nocache = q->is_nocache; @@ -1283,6 +1288,8 @@ static char *  otherinfo(ParsedURL *target, ParsedURL *current, char *referer)  {      Str s = Strnew(); +    const int *no_referer_ptr; +    int no_referer;      Strcat_charp(s, "User-Agent: ");      if (UserAgent == NULL || *UserAgent == '\0') @@ -1306,7 +1313,12 @@ otherinfo(ParsedURL *target, ParsedURL *current, char *referer)  	Strcat_charp(s, "Pragma: no-cache\r\n");  	Strcat_charp(s, "Cache-control: no-cache\r\n");      } -    if (!NoSendReferer) { +    no_referer = NoSendReferer; +    no_referer_ptr = query_SCONF_NO_REFERER_FROM(current); +    no_referer = NoSendReferer || (no_referer_ptr && *no_referer_ptr); +    no_referer_ptr = query_SCONF_NO_REFERER_TO(target); +    no_referer = no_referer || (no_referer_ptr && *no_referer_ptr); +    if (!no_referer) {  #ifdef USE_SSL          if (current && current->scheme == SCM_HTTPS && target->scheme != SCM_HTTPS) {  	  /* Don't send Referer: if https:// -> http:// */ @@ -1314,6 +1326,7 @@ otherinfo(ParsedURL *target, ParsedURL *current, char *referer)  	else  #endif  	if (referer == NULL && current && current->scheme != SCM_LOCAL && +	    current->scheme != SCM_LOCAL_CGI &&  	    (current->scheme != SCM_FTP ||  	     (current->user == NULL && current->pass == NULL))) {  	    char *p = current->label; @@ -2234,3 +2247,66 @@ schemeToProxy(int scheme)      }      return pu;  } + +#ifdef USE_M17N +wc_ces +url_to_charset(const char *url, const ParsedURL *base, wc_ces doc_charset) +{ +    const ParsedURL *pu; +    ParsedURL pu_buf; +    const wc_ces *csptr; + +    if (url && *url && *url != '#') { +	parseURL2((char *)url, &pu_buf, (ParsedURL *)base); +	pu = &pu_buf; +    } else { +	pu = base; +    } +    if (pu && (pu->scheme == SCM_LOCAL || pu->scheme == SCM_LOCAL_CGI)) +	return SystemCharset; +    csptr = query_SCONF_URL_CHARSET(pu); +    return (csptr && *csptr) ? *csptr : +	doc_charset ? doc_charset : DocumentCharset; +} + +char * +url_encode(const char *url, const ParsedURL *base, wc_ces doc_charset) +{ +    return url_quote_conv((char *)url, +			  url_to_charset(url, base, doc_charset)); +} + +#if 0 /* unused */ +char * +url_decode(const char *url, const ParsedURL *base, wc_ces doc_charset) +{ +    if (!DecodeURL) +	return (char *)url; +    return url_unquote_conv((char *)url, +			    url_to_charset(url, base, doc_charset)); +} +#endif + +char * +url_decode2(const char *url, const Buffer *buf) +{ +    wc_ces url_charset; + +    if (!DecodeURL) +	return (char *)url; +    url_charset = buf ? +	url_to_charset(url, baseURL((Buffer *)buf), buf->document_charset) : +	url_to_charset(url, NULL, 0); +    return url_unquote_conv((char *)url, url_charset); +} + +#else /* !defined(USE_M17N) */ + +char * +url_decode0(const char *url) +{ +    if (!DecodeURL) +	return (char *)url; +    return url_unquote_conv((char *)url, 0); +} +#endif /* !defined(USE_M17N) */ diff --git a/version.c.in b/version.c.in index 31d30e4..1256607 100644 --- a/version.c.in +++ b/version.c.in @@ -1,5 +1,5 @@  /* $Id: version.c.in,v 1.49 2012/05/22 09:45:56 inu Exp $ */ -#define CURRENT_VERSION "w3m/0.5.3+cvs" +#define CURRENT_VERSION "w3m/0.5.3+debian-9+"  #ifndef FM_H  char *w3m_version = CURRENT_VERSION; diff --git a/w3mbookmark.c b/w3mbookmark.c index 4355536..fcbad11 100644 --- a/w3mbookmark.c +++ b/w3mbookmark.c @@ -99,7 +99,7 @@ create_new_bookmark(char *bmark, char *section, char *title, char *url,  	fprintf(f, "<body>\n<h1>Bookmarks</h1>\n");  	fprintf(f, "<h2>%s</h2>\n<ul>\n", section);  	fprintf(f, "<li><a href=\"%s\">%s</a>\n", url, title); -	fprintf(f, end_section); +	fprintf(f, "%s", end_section);  	fprintf(f, "</ul>\n</body>\n</html>\n");  	fclose(f);      } diff --git a/w3mimg/Makefile.in b/w3mimg/Makefile.in index dfc550c..0a964a1 100644 --- a/w3mimg/Makefile.in +++ b/w3mimg/Makefile.in @@ -22,6 +22,8 @@ w3mimg.a: $(IMGOBJS)  	$(AR) rv $@ $(IMGOBJS)  	$(RANLIB) $@ +$(IMGOBJS): @IMGTARGETS@ +  w3mimg.o: w3mimg.c  	$(CC) $(CFLAGS) -c $< | 
