diff options
| -rw-r--r-- | ChangeLog | 189 | ||||
| -rw-r--r-- | Makefile.in | 4 | ||||
| -rw-r--r-- | Str.c | 4 | ||||
| -rw-r--r-- | acinclude.m4 | 4 | ||||
| -rw-r--r-- | anchor.c | 37 | ||||
| -rw-r--r-- | config.h.in | 5 | ||||
| -rwxr-xr-x | configure | 4 | ||||
| -rw-r--r-- | display.c | 2 | ||||
| -rw-r--r-- | doc-jp/MANUAL.html | 12 | ||||
| -rw-r--r-- | doc-jp/README | 5 | ||||
| -rw-r--r-- | doc-jp/README.siteconf | 60 | ||||
| -rw-r--r-- | doc-jp/w3m.1 | 15 | ||||
| -rw-r--r-- | doc/MANUAL.html | 12 | ||||
| -rw-r--r-- | doc/README | 5 | ||||
| -rw-r--r-- | doc/README.img | 2 | ||||
| -rw-r--r-- | doc/README.siteconf | 60 | ||||
| -rw-r--r-- | doc/w3m.1 | 2 | ||||
| -rw-r--r-- | entity.c | 2 | ||||
| -rw-r--r-- | file.c | 449 | ||||
| -rw-r--r-- | fm.h | 28 | ||||
| -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 | 38 | ||||
| -rw-r--r-- | image.c | 33 | ||||
| -rw-r--r-- | indep.c | 119 | ||||
| -rw-r--r-- | indep.h | 24 | ||||
| -rw-r--r-- | istream.c | 242 | ||||
| -rw-r--r-- | istream.h | 17 | ||||
| -rw-r--r-- | keybind.c | 2 | ||||
| -rw-r--r-- | linein.c | 4 | ||||
| -rw-r--r-- | local.c | 20 | ||||
| -rw-r--r-- | main.c | 262 | ||||
| -rw-r--r-- | map.c | 27 | ||||
| -rw-r--r-- | menu.c | 12 | ||||
| -rw-r--r-- | mimehead.c | 61 | ||||
| -rw-r--r-- | po/ja.po | 4 | ||||
| -rw-r--r-- | proto.h | 38 | ||||
| -rw-r--r-- | rc.c | 222 | ||||
| -rw-r--r-- | scripts/w3mman/w3mman2html.cgi.in | 8 | ||||
| -rw-r--r-- | table.c | 8 | ||||
| -rw-r--r-- | table.h | 2 | ||||
| -rw-r--r-- | tagtable.tab | 1 | ||||
| -rw-r--r-- | terms.c | 9 | ||||
| -rw-r--r-- | url.c | 161 | ||||
| -rw-r--r-- | version.c.in | 2 | ||||
| -rw-r--r-- | w3mbookmark.c | 2 | ||||
| -rw-r--r-- | w3mimg/Makefile.in | 4 | 
50 files changed, 1833 insertions, 557 deletions
| @@ -1,3 +1,192 @@ +2013-10-13  Tatsuya Kinoshita  <tats@debian.org> + +	* version.c.in: Update to 0.5.3+debian-12 + +	* doc-jp/MANUAL.html, doc-jp/w3m.1, doc/MANUAL.html, doc/w3m.1: +	Update document for the -s option change +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=75527 + +	* terms.c: Do not fail when LANG is not set +	Check whether the value of LC_ALL, LC_CTYPE or LANG is not NULL in +	check_cygwin_console(). +	Bug: https://sourceforge.net/p/w3m/patches/66/ + +2013-10-12  Tatsuya Kinoshita  <tats@debian.org> + +	* table.h: Bump MAXCOL to 256 +	Bug: https://sourceforge.net/p/w3m/feature-requests/24/ + +2013-10-12  Laurence Richert  <laurencerichert@yahoo.de> + +	* main.c, proto.h: vim/-perator like handling +	- half page scrolling +	- jumping to elements numbered by getLinkNumberStr() from Karsten +	  Schoelzel +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=724028 + +2013-10-12  Tatsuya Kinoshita  <tats@debian.org> + +	* doc-jp/README, doc/README: +	Mention project page rather than unavailable mailing lists + +2013-10-09  Rafael Laboissiere  <rafael@laboissiere.net> + +	* doc/README.img: Fix typo +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=725892 + +2013-08-12  Tatsuya Kinoshita  <tats@debian.org> + +	* version.c.in: Update to 0.5.3+debian-11+ + +	* ChangeLog: Update ChangeLog to use contributor's name + +2013-08-08  Tatsuya Kinoshita  <tats@debian.org> + +	* version.c.in: Update to 0.5.3+debian-11 + +2013-08-04  Tatsuya Kinoshita  <tats@debian.org> + +	* Str.c: Check length for Strchop() + +	* main.c: Fix potentially segfault of execdict() + +	* version.c.in: Update to 0.5.3+debian-10+ + +	* file.c: Fix segfault of loadGeneralFile() +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=718612 + +2013-08-02  Tatsuya Kinoshita  <tats@debian.org> + +	* version.c.in: Update to 0.5.3+debian-10 + +2013-08-02  Piotr P. Karwasz <piotr.p@karwasz.org> + +	* scripts/w3mman/w3mman2html.cgi.in: +	Correct underline processing and more UTF-8 support for w3mman2html.cgi +	Patch from <https://bugs.launchpad.net/ubuntu/+source/w3m/+bug/680202> +	on 2010-11-23. + +2013-08-01  Hilko Bengen  <bengen@debian.org> + +	* entity.c: Ignore SOFT HYPHEN to prevent drawing hyphens everywhere +	Patch from <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=441934> +	on 2011-03-01. + +2013-08-01  Tatsuya Kinoshita  <tats@debian.org> + +	* doc-jp/README, doc/README: Update contact list in README +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=696209 + +2013-07-30  Tatsuya Kinoshita  <tats@debian.org> + +	* config.guess, config.sub: +	Update config.guess and config.sub to supprot aarch64 +	Updated with Debian autotools-dev version 20130515.1. + +2013-07-30  Conrad J.C. Hughes  <debbugs@xrad.org> + +	* main.c: Sort anchors by sequence number in -dump +	Patch from <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=657666> +	on 2012-01-27. + +2013-07-30  Tatsuya Kinoshita  <tats@debian.org> + +	* version.c.in: Update to 0.5.3+debian-9+ + +2013-07-29  Tatsuya Kinoshita  <tats@debian.org> + +	* version.c.in: Update version to w3m/0.5.3+debian-9 + +	* version.c.in: Set CURRENT_VERSION to debian version + +2013-07-28  Tatsuya Kinoshita  <tats@debian.org> + +	* file.c: Fix segfault of process_button() + +2013-04-08  AIDA Shinra  <shinra@j10n.org> + +	* file.c: One more patch for siteconf from [w3m-dev 04464] + +	* anchor.c, config.h.in, display.c, doc-jp/README.siteconf: +	* doc/README.siteconf, file.c, fm.h, form.c, frame.c, func.c: +	* history.c, indep.c, indep.h, linein.c, main.c, map.c, menu.c: +	* po/ja.po, proto.h, rc.c, url.c: Support the siteconf feature +	Patch to support the siteconf feature, from [w3m-dev 04463] +	on 2012-06-27. + +2013-04-08  Hayaki Saito  <user@zuse.jp> + +	* keybind.c, main.c, proto.h, terms.c: +	Support SGR 1006 mouse reporting +	Patch to support SGR 1006 mouse reporting, from [w3m-dev 04466] +	on 2012-07-15. + +2012-05-19  Hilko Bengen  <bengen@debian.org> + +	* form.c: Assume "text" if an input type is unknown +	Patch from <http://bugs.debian.org/615843> on 2011-03-01. + +2012-05-19  Simon Ruderich  <simon@ruderich.org> + +	* Makefile.in: Use $(CPPFLAGS) with $(CPP) +	Patch from <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=665491> +	on 2012-03-24. + +2012-05-03  Miroslav Šulc  <fordfrog@gentoo.org> + +	* w3mimg/Makefile.in: Fix parallel make issue +	Patch from Gentoo +	<http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/www-client/w3m/files/w3m-0.5.3-parallel-make.patch?revision=1.1&view=markup> +	<https://bugs.gentoo.org/show_bug.cgi?id=353390> on 2011-02-01. + +2012-05-03  MATSUU Takuto  <matsuu@gentoo.org> + +	* main.c: Support Boehm GC 7.2 +	Patch from Gentoo +	<http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/www-client/w3m/files/w3m-0.5.2-gc72.patch?revision=1.1&view=markup> +	on 2009-12-13. + +2012-05-02  Reinhard Tartler  <siretart@tauware.de> + +	* istream.c, istream.h: +	Fix that struct file_handle conflicts with glibc 2.14 +	Patch from <https://bugs.launchpad.net/ubuntu/+source/w3m/+bug/935540> +	on 2012-02-19. + +2011-10-30  Colin Watson  <cjwatson@ubuntu.com> + +	* acinclude.m4, configure, w3mbookmark.c: +	Appease gcc -Werror=format-security. +	Patch from 0.5.3-3ubuntu1 on 2011-10-23. +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=646321 + +2011-06-19  Martin Pitt  <martin.pitt@ubuntu.com> + +	* Makefile.in: +	Explicitly link w3mimgdisplay with -lX11 to build with gcc 4.5 +	Patch from 0.5.2-10ubuntu1 on 2010-12-03. +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=605761 + +2011-06-19  Fumitoshi UKAI  <ukai@debian.or.jp> + +	* main.c: +	Change the -s option to "squeeze multiple blank lines" for pager +	Change the -s option from "display charset Shift_JIS" to "squeeze +	multiple blank lines" to work as /usr/bin/pager.  In addition, the +	options -j and -e are disabled.  To specify the display charset, +	use -O{s|j|e} instead. +	Patch from [w3m-dev 01275] on 2000-10-26. +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=75527 + +2011-06-19  Hiroyuki Ito  <ZXB01226@nifty.com> + +	* file.c, fm.h, html.c, html.h, proto.h, table.c, tagtable.tab: +	Support the button element as defined in HTML 4.01 +	Patch from upstream, [w3m-dev 04411] on 2010-09-17, to support the +	button element.  It is discussed upstream and incomplete, but enough +	to login Launchpad. +	Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=136810 +  2012-05-22  Tatsuya Kinoshita <tats@vega.ocn.ne.jp>  	* [w3m-dev 04451] w3m/entity.h should be removed when `make clean' diff --git a/Makefile.in b/Makefile.in index 7d692f9..8fa799e 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 @@ -250,7 +250,7 @@ install-po:  	 (cd $$subdir && $(MAKE) install); \  	done -all-scripts: +all-scripts: funcname.tab  	for dir in $(SCRIPTSUBDIRS);	\  	do	\  		(cd $$dir && $(MAKE) $(MAKE_ARGS)); \ @@ -278,8 +278,8 @@ void  Strchop(Str s)  {      STR_LENGTH_CHECK(s); -    while ((s->ptr[s->length - 1] == '\n' || s->ptr[s->length - 1] == '\r') && -	   s->length > 0) { +    while (s->length > 0 && +	   (s->ptr[s->length - 1] == '\n' || s->ptr[s->length - 1] == '\r')) {  	s->length--;      }      s->ptr[s->length] = '\0'; diff --git a/acinclude.m4 b/acinclude.m4 index e4ccc3d..48e0ff8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -706,7 +706,7 @@ AC_DEFUN([AC_W3M_IMAGE],       AC_DEFINE(USE_GDKPIXBUF)       AC_DEFINE(USE_GTK2)       IMGX11CFLAGS="`${PKG_CONFIG} --cflags gdk-pixbuf-2.0 gdk-pixbuf-xlib-2.0 gtk+-2.0`" -     IMGX11LDFLAGS="`${PKG_CONFIG} --libs gdk-pixbuf-2.0 gdk-pixbuf-xlib-2.0 gtk+-2.0`" +     IMGX11LDFLAGS="-lX11 `${PKG_CONFIG} --libs gdk-pixbuf-2.0 gdk-pixbuf-xlib-2.0 gtk+-2.0`"     elif test x"$have_gdkpixbuf" = xyes; then       AC_DEFINE(USE_W3MIMG_X11)       IMGOBJS="$IMGOBJS x11/x11_w3mimg.o" @@ -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..a4110ea 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" @@ -209,6 +210,10 @@ typedef RETSIGTYPE MySignalHandler;  #define SUPPORT_WIN9X_CONSOLE_MBCS 1  #endif +#if defined(__CYGWIN__) && defined(__x86_64__) +#define DONT_CALL_GC_AFTER_FORK +#endif +  #if defined(__DJGPP__)  #define DEFAULT_TERM	"dosansi"  #else @@ -6927,7 +6927,7 @@ $as_echo "$as_me: WARNING: Imlib2 is not installed.  Install Imlib2 (version >=       $as_echo "#define USE_GTK2 1" >>confdefs.h       IMGX11CFLAGS="`${PKG_CONFIG} --cflags gdk-pixbuf-2.0 gdk-pixbuf-xlib-2.0 gtk+-2.0`" -     IMGX11LDFLAGS="`${PKG_CONFIG} --libs gdk-pixbuf-2.0 gdk-pixbuf-xlib-2.0 gtk+-2.0`" +     IMGX11LDFLAGS="-lX11 `${PKG_CONFIG} --libs gdk-pixbuf-2.0 gdk-pixbuf-xlib-2.0 gtk+-2.0`"     elif test x"$have_gdkpixbuf" = xyes; then       $as_echo "#define USE_W3MIMG_X11 1" >>confdefs.h @@ -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/MANUAL.html b/doc-jp/MANUAL.html index 41d70f1..f197cfb 100644 --- a/doc-jp/MANUAL.html +++ b/doc-jp/MANUAL.html @@ -51,15 +51,9 @@ w3m ϡƥȥ١Υڡ/WWW֥饦ǤȤȡkterm ʤɤΥ  <dt>-l Կ  <dd>ɸϤƤɽȤ¸Կꤹ  롥ǥեȤ 10000 -<dt>-s -<dd>Shift_JIS ɤɽ롥 -<dt>-e -<dd>EUC ɤɽ롥 -<dt>-j -<dd>JIS(ISO-2022-JP) ɤɽ롥 -<dt>-O e|s|j|N|m|n +<dt>-O ʸ  <dd>ɽѤʸɤꤹ롥 -<dt>-I e|s +<dt>-I ʸ  <dd>ʸʸɤꤹ롥  <dt>-T   <dd>ɽʸΥפꤹ롥λ꤬ʤ硤ե @@ -89,7 +83,7 @@ HTMLեΥɽ  <dd>顼ɽʤ  <dt>-F  <dd>ե졼ưɽ롥 -<dt>-S +<dt>-s  <dd>Ϣ³Ԥ1ԤˤޤȤɽ롥  <dt>-X  <dd>w3mλˡβ̤ʤ diff --git a/doc-jp/README b/doc-jp/README index 074766f..e5e59b1 100644 --- a/doc-jp/README +++ b/doc-jp/README @@ -122,7 +122,6 @@ w3m ϡƣ§°Ƥޤ  	±  	satodai@w3m.jp -ոۤMLޤǤ -	w3m-dev@sic.med.tohoku.ac.jp (ܸ) -	w3m-dev-en@sic.med.tohoku.ac.jp (Ѹ) +ոۤ  	http://w3m.sourceforge.net/ +	https://sourceforge.net/projects/w3m/ 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-jp/w3m.1 b/doc-jp/w3m.1 index 89aacb6..099a803 100644 --- a/doc-jp/w3m.1 +++ b/doc-jp/w3m.1 @@ -39,19 +39,10 @@ text/plainʸɽ硤ŤǤˤ붯Ĵʸɽʤ  ɸϤƤɽȤ¸Կꤹ롥  ǥեȤ10000  .TP -.B \-s -Shift_JISɤɽ롥 -.TP -.B \-e -EUCɤɽ롥 -.TP -.B \-j -JIS (ISO-2022-JP)ɤɽ롥 -.TP -.BI \-O\  e|s|j|N|m +.BI \-O\  ʸ  ɽ˻Ȥʸɤꤹ.  .TP -.BI \-I\  e|s +.BI \-I\  ʸ  ʸʸɤꤹ롥  .TP  .BI \-T\   @@ -90,7 +81,7 @@ Bookmark Υեꤹ롥  .B \-F  ե졼ưɽ롥  .TP -.B \-S +.B \-s  Ϣ³Ԥ1ԤˤޤȤɽ롥  .TP  .B \-X diff --git a/doc/MANUAL.html b/doc/MANUAL.html index aff0189..0a00b59 100644 --- a/doc/MANUAL.html +++ b/doc/MANUAL.html @@ -55,12 +55,10 @@ If you don't specify this option,  <dt>-l number  <dd>Specify line number preserved internally when reading text/plain document  fron standard input. Default is 10000. -<dt>-s -<dd>Display documents with Shift_JIS code. -<dt>-e -<dd>Display documents with EUC_JP code. -<dt>-j -<dd>Display documents with ISO-2022-JP code. +<dt>-O charset +<dd>Specify display/output charset. +<dt>-I charset +<dd>Specify document charset.  <dt>-T type  <dd>Specify document type. Without this option, document type  is determined from extension of a file. If the determination @@ -90,7 +88,7 @@ It is useful when reading E-mail or NetNews messages.  <dd>Monochrome display mode.  <dt>-F  <dd>Automatically render frame. -<dt>-S +<dt>-s  <dd>Squeeze blank lines.  <dt>-X  <dd>Upon exit, do not display preserved screen. @@ -115,7 +115,6 @@ Current Maintainer  	Tohoku University Hospital  	satodai@w3m.jp -Feel free to send your opinion to the w3m mailing-lists. -	w3m-dev@sic.med.tohoku.ac.jp (Japanese) -	w3m-dev-en@sic.med.tohoku.ac.jp (English) +Feel free to send your opinion to:  	http://w3m.sourceforge.net/ +	https://sourceforge.net/projects/w3m/ diff --git a/doc/README.img b/doc/README.img index 0c10114..f11362f 100644 --- a/doc/README.img +++ b/doc/README.img @@ -41,7 +41,7 @@ Key functions    Specify the following keymaps in ~/.w3m/keymap.        keymap  X    DISPLAY_IMAGE        keymap  C-c  STOP_IMAGE -      keyamp  t    SET_OPTION  display_image=toggle +      keymap  t    SET_OPTION  display_image=toggle  Commandline options 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. + @@ -143,7 +143,7 @@ use graphic character  .B -no-graph  don't use graphic character  .TP -.B -S +.B -s  squeeze multiple blank lines  .TP  .B -W @@ -44,6 +44,8 @@ conv_entity(unsigned int c)  	return " ";      if (c == 0xa0)  	return NBSP; +    if (c == 0xad)		/* SOFT HYPHEN */ +        return "";      if (c < 0x100) {		/* Latin1 (ISO 8859-1) */  	if (UseAltEntity)  	    return alt_latin1[c - 0xa0]; @@ -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)  { @@ -694,6 +677,7 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu)  #endif  		    init_stream(&f, SCM_LOCAL, newStrStream(src));  		    loadHTMLstream(&f, newBuf, NULL, TRUE); +		    UFclose(&f);  		    for (l = newBuf->lastLine; l && l->real_linenumber;  			 l = l->prev)  			l->real_linenumber = 0; @@ -1697,13 +1681,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 +1716,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 +1864,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 +2023,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 +2124,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 +2194,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 +2219,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; @@ -2287,10 +2268,11 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,      if (header_string)  	header_string = NULL;  #ifdef USE_NNTP -    if (f.scheme == SCM_NNTP || f.scheme == SCM_NEWS) +    if (b && b != NO_BUFFER && (f.scheme == SCM_NNTP || f.scheme == SCM_NEWS))  	reAnchorNewsheader(b);  #endif -    preFormUpdateBuffer(b); +    if (b && b != NO_BUFFER) +	preFormUpdateBuffer(b);      TRAP_OFF;      return b;  } @@ -2469,6 +2451,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 +2469,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 +2713,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 +2745,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 +2802,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 +3014,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 +3232,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 +3326,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 +3731,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 +4140,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)) @@ -4284,15 +4341,15 @@ getMetaRefreshParam(char *q, Str *refresh_uri)      while (*q) {  	if (!strncasecmp(q, "url=", 4)) {  	    q += 4; -	    if (*q == '\"')	/* " */ +	    if (*q == '\"' || *q == '\'')	/* " or ' */  		q++;  	    r = q;  	    while (*r && !IS_SPACE(*r) && *r != ';')  		r++;  	    s_tmp = Strnew_charp_n(q, r - q); -	    if (s_tmp->ptr[s_tmp->length - 1] == '\"') {	/* "  -								 */ +	    if (s_tmp->ptr[s_tmp->length - 1] == '\"'          /* " */ +	       || s_tmp->ptr[s_tmp->length - 1] == '\'') {     /* ' */  		s_tmp->length--;  		s_tmp->ptr[s_tmp->length] = '\0';  	    } @@ -4861,7 +4918,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 +5055,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 +5162,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 +5423,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 +5624,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 +5720,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 +5741,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 +5791,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 +5878,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 +5928,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 +5950,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 +5964,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 +6049,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 +6102,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 +6877,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 +6918,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 +7099,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 +7121,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 +7185,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 +7197,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) { @@ -7096,16 +7239,17 @@ loadHTMLString(Str page)      MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;      Buffer *newBuf; +    init_stream(&f, SCM_LOCAL, newStrStream(page)); +      newBuf = newBuffer(INIT_BUFFER_WIDTH);      if (SETJMP(AbortLoading) != 0) {  	TRAP_OFF;  	discardBuffer(newBuf); +	UFclose(&f);  	return NULL;      }      TRAP_ON; -    init_stream(&f, SCM_LOCAL, newStrStream(page)); -  #ifdef USE_M17N      newBuf->document_charset = InnerCharset;  #endif @@ -7115,6 +7259,7 @@ loadHTMLString(Str page)  #endif      TRAP_OFF; +    UFclose(&f);      newBuf->topLine = newBuf->firstLine;      newBuf->lastLine = newBuf->currentLine;      newBuf->currentLine = newBuf->firstLine; @@ -7207,7 +7352,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 +7476,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,20 +7484,18 @@ 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; -    TRAP_ON;      if (IStype(uf->stream) != IST_ENCODED)  	uf->stream = newEncodedStream(uf->stream, uf->encoding); +    TRAP_ON;      if (save2tmp(*uf, cache->file) < 0) { -	UFclose(uf);  	TRAP_OFF;  	return NULL;      } -    UFclose(uf);      TRAP_OFF;      cache->loaded = IMG_FLAG_LOADED; @@ -7371,6 +7515,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf)      init_stream(&f, SCM_LOCAL, newStrStream(tmp));      loadHTMLstream(&f, newBuf, src, TRUE); +    UFclose(&f);      if (src)  	fclose(src); @@ -7580,8 +7725,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 +7757,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 +7776,6 @@ openGeneralPagerBuffer(InputStream stream)  	}      }      buf->real_type = t; -    buf->currentURL.scheme = SCM_LOCAL; -    buf->currentURL.file = "-";      return buf;  } @@ -7766,6 +7911,8 @@ save2tmp(URLFile uf, char *tmpf)      clen_t linelen = 0, trbyte = 0;      MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;      static JMP_BUF env_bak; +    volatile int retval = 0; +    char *volatile buf = NULL;      ff = fopen(tmpf, "wb");      if (ff == NULL) { @@ -7802,30 +7949,29 @@ save2tmp(URLFile uf, char *tmpf)      else  #endif				/* USE_NNTP */      { -	Str buf = Strnew_size(SAVE_BUF_SIZE); -	while (UFread(&uf, buf, SAVE_BUF_SIZE)) { -	    if (Strfputs(buf, ff) != buf->length) { -		bcopy(env_bak, AbortLoading, sizeof(JMP_BUF)); -		TRAP_OFF; -		fclose(ff); -		current_content_length = 0; -		return -2; +	int count; + +	buf = NewWithoutGC_N(char, SAVE_BUF_SIZE); +	while ((count = ISread_n(uf.stream, buf, SAVE_BUF_SIZE)) > 0) { +	    if (fwrite(buf, 1, count, ff) != count) { +		retval = -2; +		goto _end;  	    } -	    linelen += buf->length; +	    linelen += count;  	    showProgress(&linelen, &trbyte);  	}      }    _end:      bcopy(env_bak, AbortLoading, sizeof(JMP_BUF));      TRAP_OFF; +    xfree(buf);      fclose(ff);      current_content_length = 0; -    return 0; +    return retval;  } -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 +7980,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 +8013,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 +8062,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 @@ -7935,7 +8078,8 @@ _MoveFile(char *path1, char *path2)      FILE *f2;      int is_pipe;      clen_t linelen = 0, trbyte = 0; -    Str buf; +    char *buf = NULL; +    int count;      f1 = openIS(path1);      if (f1 == NULL) @@ -7953,12 +8097,13 @@ _MoveFile(char *path1, char *path2)  	return -1;      }      current_content_length = 0; -    buf = Strnew_size(SAVE_BUF_SIZE); -    while (ISread(f1, buf, SAVE_BUF_SIZE)) { -	Strfputs(buf, f2); -	linelen += buf->length; +    buf = NewWithoutGC_N(char, SAVE_BUF_SIZE); +    while ((count = ISread_n(f1, buf, SAVE_BUF_SIZE)) > 0) { +	fwrite(buf, 1, count, f2); +	linelen += count;  	showProgress(&linelen, &trbyte);      } +    xfree(buf);      ISclose(f1);      if (is_pipe)  	pclose(f2); @@ -8317,21 +8462,23 @@ uncompress_stream(URLFile *uf, char **src)  	}  	if (pid2 == 0) {  	    /* child2 */ -	    Str buf = Strnew_size(SAVE_BUF_SIZE); +	    char *buf = NewWithoutGC_N(char, SAVE_BUF_SIZE); +	    int count;  	    FILE *f = NULL;  	    setup_child(TRUE, 2, UFfileno(uf));  	    if (tmpf)  		f = fopen(tmpf, "wb"); -	    while (UFread(uf, buf, SAVE_BUF_SIZE)) { -		if (Strfputs(buf, stdout) < 0) +	    while ((count = ISread_n(uf->stream, buf, SAVE_BUF_SIZE)) > 0) { +		if (fwrite(buf, 1, count, stdout) != count) +		    break; +		if (f && fwrite(buf, 1, count, f) != count)  		    break; -		if (f) -		    Strfputs(buf, f);  	    }  	    UFclose(uf);  	    if (f)  		fclose(f); +	    xfree(buf);  	    exit(0);  	}  	/* child1 */ @@ -76,6 +76,7 @@ typedef int wc_ces;	/* XXX: not used */  #include "textlist.h"  #include "funcname1.h"  #include "terms.h" +#include "istream.h"  #ifndef HAVE_BCOPY  void bcopy(const void *, void *, int); @@ -264,6 +265,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.   */ @@ -276,8 +289,6 @@ extern int REV_LB[];  #define inputFilenameHist(p,d,h)	inputLineHist(p,d,IN_FILENAME,h)  #define inputChar(p)		inputLine(p,"",IN_CHAR) -#define free(x)  GC_free(x)	/* let GC do it. */ -  #ifdef __EMX__  #define HAVE_STRCASECMP  #define strcasecmp	stricmp @@ -562,6 +573,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 +587,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 +610,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; @@ -874,6 +894,9 @@ global char *index_file init(NULL);  global char *CurrentDir;  global int CurrentPid; +#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) +global char *MyProgramName init("w3m"); +#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */  /*   * global Buffer *Currentbuf;   * global Buffer *Firstbuf; @@ -972,6 +995,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 */ @@ -1,19 +1,17 @@  /* $Id: html.h,v 1.31 2010/08/14 01:29:40 htrb Exp $ */  #ifndef _HTML_H  #define _HTML_H +#include "config.h"  #ifdef USE_SSL  #include <openssl/bio.h>  #include <openssl/x509.h>  #include <openssl/ssl.h>  #endif				/* USE_SSL */ -#include "istream.h" -  #define StrUFgets(f) StrISgets((f)->stream)  #define StrmyUFgets(f) StrmyISgets((f)->stream)  #define UFgetc(f) ISgetc((f)->stream)  #define UFundogetc(f) ISundogetc((f)->stream) -#define UFread(f,buf,len) ISread((f)->stream,buf,len)  #define UFclose(f) (void)(ISclose((f)->stream) == 0 && ((f)->stream = NULL))  #define UFfileno(f) ISfileno((f)->stream) @@ -62,11 +60,12 @@ typedef struct _ParsedURL {      int is_nocache;  } ParsedURL; +union input_stream;  typedef struct {      unsigned char scheme;      char is_cgi;      char encoding; -    InputStream stream; +    union input_stream *stream;      char *ext;      int compression;      int content_encoding; @@ -214,21 +213,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 @@ -90,17 +90,18 @@ termImage()  static int  openImgdisplay()  { +    char *cmd; + +    if (!strchr(Imgdisplay, '/')) +	cmd = Strnew_m_charp(w3m_auxbin_dir(), "/", Imgdisplay, NULL)->ptr; +    else +	cmd = Imgdisplay;      Imgdisplay_pid = open_pipe_rw(&Imgdisplay_rf, &Imgdisplay_wf);      if (Imgdisplay_pid < 0)  	goto err0;      if (Imgdisplay_pid == 0) {  	/* child */ -	char *cmd;  	setup_child(FALSE, 2, -1); -	if (!strchr(Imgdisplay, '/')) -	    cmd = Strnew_m_charp(w3m_auxbin_dir(), "/", Imgdisplay, NULL)->ptr; -	else -	    cmd = Imgdisplay;  	myExec(cmd);  	/* XXX: ifdef __EMX__, use start /f ? */      } @@ -333,6 +334,9 @@ loadImage(Buffer *buf, int flag)      struct stat st;      int i, draw = FALSE;      /* int wait_st; */ +#ifdef DONT_CALL_GC_AFTER_FORK +    char *loadargs[7]; +#endif      if (maxLoadImage > MAX_LOAD_IMAGE)  	maxLoadImage = MAX_LOAD_IMAGE; @@ -433,6 +437,24 @@ loadImage(Buffer *buf, int flag)  	image_cache[i] = cache;  	flush_tty(); +#ifdef DONT_CALL_GC_AFTER_FORK +	loadargs[0] = MyProgramName; +	loadargs[1] = "-$$getimage"; +	loadargs[2] = conv_to_system(cache->url); +	loadargs[3] = conv_to_system(parsedURL2Str(cache->current)->ptr); +	loadargs[4] = cache->file; +	loadargs[5] = cache->touch; +	loadargs[6] = NULL; +	if ((cache->pid = fork()) == 0) { +	    setup_child(FALSE, 0, -1); +	    execvp(MyProgramName, loadargs); +	    exit(1); +	} +	else if (cache->pid < 0) { +	    cache->pid = 0; +	    return; +	} +#else /* !DONT_CALL_GC_AFTER_FORK */  	if ((cache->pid = fork()) == 0) {  	    Buffer *b;  	    /* @@ -458,6 +480,7 @@ loadImage(Buffer *buf, int flag)  	    cache->pid = 0;  	    return;  	} +#endif /* !DONT_CALL_GC_AFTER_FORK */      }  } @@ -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)  { @@ -707,6 +721,111 @@ shell_quote(char *str)      return str;  } +void * +xrealloc(void *ptr, size_t size) +{ +    void *newptr = realloc(ptr, size); +    if (newptr == NULL) { +	fprintf(stderr, "Out of memory\n"); +	exit(-1); +    } +    return newptr; +} + +/* Define this as a separate function in case the free() has + * an incompatible prototype. */ +void +xfree(void *ptr) +{ +    free(ptr); +} + +void * +w3m_GC_realloc_atomic(void *ptr, size_t size) +{ +    return ptr ? GC_REALLOC(ptr, size) : GC_MALLOC_ATOMIC(size); +} + +void +w3m_GC_free(void *ptr) +{ +    GC_FREE(ptr); +} + +void +growbuf_init(struct growbuf *gb) +{ +    gb->ptr = NULL; +    gb->length = 0; +    gb->area_size = 0; +    gb->realloc_proc = &w3m_GC_realloc_atomic; +    gb->free_proc = &w3m_GC_free; +} + +void +growbuf_init_without_GC(struct growbuf *gb) +{ +    gb->ptr = NULL; +    gb->length = 0; +    gb->area_size = 0; +    gb->realloc_proc = &xrealloc; +    gb->free_proc = &xfree; +} + +void +growbuf_clear(struct growbuf *gb) +{ +    (*gb->free_proc) (gb->ptr); +    gb->ptr = NULL; +    gb->length = 0; +    gb->area_size = 0; +} + +Str +growbuf_to_Str(struct growbuf *gb) +{ +    Str s; + +    if (gb->free_proc == &w3m_GC_free) { +	growbuf_reserve(gb, gb->length + 1); +	gb->ptr[gb->length] = '\0'; +	s = New(struct _Str); +	s->ptr = gb->ptr; +	s->length = gb->length; +	s->area_size = gb->area_size; +    } else { +	s = Strnew_charp_n(gb->ptr, gb->length); +	(*gb->free_proc) (gb->ptr); +    } +    gb->ptr = NULL; +    gb->length = 0; +    gb->area_size = 0; +    return s; +} + +void +growbuf_reserve(struct growbuf *gb, int leastarea) +{ +    int newarea; + +    if (gb->area_size < leastarea) { +	newarea = gb->area_size * 3 / 2; +	if (newarea < leastarea) +	    newarea = leastarea; +	newarea += 16; +	gb->ptr = (*gb->realloc_proc) (gb->ptr, newarea); +	gb->area_size = newarea; +    } +} + +void +growbuf_append(struct growbuf *gb, const char *src, int len) +{ +    growbuf_reserve(gb, gb->length + len); +    memcpy(&gb->ptr[gb->length], src, len); +    gb->length += len; +} +  static char *  w3m_dir(const char *name, char *dft)  { @@ -12,6 +12,14 @@  #define FALSE 0  #endif				/* FALSE */ +struct growbuf { +    char *ptr; +    int length; +    int area_size; +    void *(*realloc_proc) (void *, size_t); +    void (*free_proc) (void *); +}; +  #define RAW_MODE	0  #define PAGER_MODE	1  #define HTML_MODE	2 @@ -52,6 +60,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); @@ -64,6 +73,18 @@ extern Str Str_url_unquote(Str x, int is_form, int safe);  extern Str Str_form_quote(Str x);  #define Str_form_unquote(x) Str_url_unquote((x), TRUE, FALSE)  extern char *shell_quote(char *str); +#define xmalloc(s) xrealloc(NULL, s) +extern void *xrealloc(void *ptr, size_t size); +extern void xfree(void *ptr); +extern void *w3m_GC_realloc_atomic(void *ptr, size_t size); +extern void w3m_GC_free(void *ptr); +extern void growbuf_init(struct growbuf *gb); +extern void growbuf_init_without_GC(struct growbuf *gb); +extern void growbuf_clear(struct growbuf *gb); +extern Str growbuf_to_Str(struct growbuf *gb); +extern void growbuf_reserve(struct growbuf *gb, int leastarea); +extern void growbuf_append(struct growbuf *gb, const char *src, int len); +#define GROWBUF_ADD_CHAR(gb,ch) ((((gb)->length>=(gb)->area_size)?growbuf_reserve(gb,(gb)->length+1):(void)0),(void)((gb)->ptr[(gb)->length++] = (ch)))  extern char *w3m_auxbin_dir();  extern char *w3m_lib_dir(); @@ -76,5 +97,8 @@ extern char *w3m_help_dir();  #define New_N(type,n)	((type*)GC_MALLOC((n)*sizeof(type)))  #define NewAtom_N(type,n)	((type*)GC_MALLOC_ATOMIC((n)*sizeof(type)))  #define New_Reuse(type,ptr,n)   ((type*)GC_REALLOC((ptr),(n)*sizeof(type))) +#define NewWithoutGC(type)	((type*)xmalloc(sizeof(type))) +#define NewWithoutGC_N(type,n)	((type*)xmalloc((n)*sizeof(type))) +#define NewWithoutGC_Reuse(type,ptr,n)	((type*)xrealloc(ptr,(n)*sizeof(type)))  #endif				/* INDEP_H */ @@ -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); @@ -35,12 +35,14 @@ static int ssl_read(struct ssl_handle *handle, char *buf, int len);  static int ens_read(struct ens_handle *handle, char *buf, int len);  static void ens_close(struct ens_handle *handle); +static void memchop(char *p, int *len); +  static void  do_update(BaseStream base)  {      int len;      base->stream.cur = base->stream.next = 0; -    len = base->read(base->handle, base->stream.buf, base->stream.size); +    len = (*base->read) (base->handle, base->stream.buf, base->stream.size);      if (len <= 0)  	base->iseos = TRUE;      else @@ -66,12 +68,12 @@ init_buffer(BaseStream base, char *buf, int bufsize)      StreamBuffer sb = &base->stream;      sb->size = bufsize;      sb->cur = 0; +    sb->buf = NewWithoutGC_N(uchar, bufsize);      if (buf) { -	sb->buf = (uchar *) buf; +	memcpy(sb->buf, buf, bufsize);  	sb->next = bufsize;      }      else { -	sb->buf = NewAtom_N(uchar, bufsize);  	sb->next = 0;      }      base->iseos = FALSE; @@ -95,10 +97,10 @@ newInputStream(int des)      InputStream stream;      if (des < 0)  	return NULL; -    stream = New(union input_stream); +    stream = NewWithoutGC(union input_stream);      init_base_stream(&stream->base, STREAM_BUF_SIZE);      stream->base.type = IST_BASIC; -    stream->base.handle = New(int); +    stream->base.handle = NewWithoutGC(int);      *(int *)stream->base.handle = des;      stream->base.read = (int (*)())basic_read;      stream->base.close = (void (*)())basic_close; @@ -111,10 +113,10 @@ newFileStream(FILE * f, void (*closep) ())      InputStream stream;      if (f == NULL)  	return NULL; -    stream = New(union input_stream); +    stream = NewWithoutGC(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 = NewWithoutGC(struct io_file_handle);      stream->file.handle->f = f;      if (closep)  	stream->file.handle->close = closep; @@ -131,10 +133,10 @@ newStrStream(Str s)      InputStream stream;      if (s == NULL)  	return NULL; -    stream = New(union input_stream); +    stream = NewWithoutGC(union input_stream);      init_str_stream(&stream->base, s);      stream->str.type = IST_STR; -    stream->str.handle = s; +    stream->str.handle = NULL;      stream->str.read = (int (*)())str_read;      stream->str.close = NULL;      return stream; @@ -147,10 +149,10 @@ newSSLStream(SSL * ssl, int sock)      InputStream stream;      if (sock < 0)  	return NULL; -    stream = New(union input_stream); +    stream = NewWithoutGC(union input_stream);      init_base_stream(&stream->base, SSL_BUF_SIZE);      stream->ssl.type = IST_SSL; -    stream->ssl.handle = New(struct ssl_handle); +    stream->ssl.handle = NewWithoutGC(struct ssl_handle);      stream->ssl.handle->ssl = ssl;      stream->ssl.handle->sock = sock;      stream->ssl.read = (int (*)())ssl_read; @@ -166,14 +168,14 @@ newEncodedStream(InputStream is, char encoding)      if (is == NULL || (encoding != ENC_QUOTE && encoding != ENC_BASE64 &&  		       encoding != ENC_UUENCODE))  	return is; -    stream = New(union input_stream); +    stream = NewWithoutGC(union input_stream);      init_base_stream(&stream->base, STREAM_BUF_SIZE);      stream->ens.type = IST_ENCODED; -    stream->ens.handle = New(struct ens_handle); +    stream->ens.handle = NewWithoutGC(struct ens_handle);      stream->ens.handle->is = is;      stream->ens.handle->pos = 0;      stream->ens.handle->encoding = encoding; -    stream->ens.handle->s = NULL; +    growbuf_init_without_GC(&stream->ens.handle->gb);      stream->ens.read = (int (*)())ens_read;      stream->ens.close = (void (*)())ens_close;      return stream; @@ -187,8 +189,10 @@ ISclose(InputStream stream)  	stream->base.type & IST_UNCLOSE)  	return -1;      prevtrap = mySignal(SIGINT, SIG_IGN); -    stream->base.close(stream->base.handle); +    stream->base.close (stream->base.handle);      mySignal(SIGINT, prevtrap); +    xfree(stream->base.stream.buf); +    xfree(stream);      return 0;  } @@ -218,122 +222,97 @@ ISundogetc(InputStream stream)      return -1;  } -#define MARGIN_STR_SIZE 10  Str -StrISgets(InputStream stream) +StrISgets2(InputStream stream, char crnl)  { -    BaseStream base; -    StreamBuffer sb; -    Str s = NULL; -    uchar *p; -    int len; +    struct growbuf gb;      if (stream == NULL) -	return '\0'; -    base = &stream->base; -    sb = &base->stream; - -    while (!base->iseos) { -	if (MUST_BE_UPDATED(base)) { -	    do_update(base); -	} -	else { -	    if ((p = memchr(&sb->buf[sb->cur], '\n', sb->next - sb->cur))) { -		len = p - &sb->buf[sb->cur] + 1; -		if (s == NULL) -		    s = Strnew_size(len); -		Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len); -		sb->cur += len; -		return s; -	    } -	    else { -		if (s == NULL) -		    s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE); -		Strcat_charp_n(s, (char *)&sb->buf[sb->cur], -			       sb->next - sb->cur); -		sb->cur = sb->next; -	    } -	} -    } - -    if (s == NULL) -	return Strnew(); -    return s; +	return NULL; +    growbuf_init(&gb); +    ISgets_to_growbuf(stream, &gb, crnl); +    return growbuf_to_Str(&gb);  } -Str -StrmyISgets(InputStream stream) +void +ISgets_to_growbuf(InputStream stream, struct growbuf *gb, char crnl)  { -    BaseStream base; -    StreamBuffer sb; -    Str s = NULL; -    int i, len; +    BaseStream base = &stream->base; +    StreamBuffer sb = &base->stream; +    int i; -    if (stream == NULL) -	return '\0'; -    base = &stream->base; -    sb = &base->stream; +    gb->length = 0;      while (!base->iseos) {  	if (MUST_BE_UPDATED(base)) {  	    do_update(base); +	    continue;  	} -	else { -	    if (s && Strlastchar(s) == '\r') { -		if (sb->buf[sb->cur] == '\n') -		    Strcat_char(s, (char)sb->buf[sb->cur++]); -		return s; +	if (crnl && gb->length > 0  && gb->ptr[gb->length - 1] == '\r') { +	    if (sb->buf[sb->cur] == '\n') { +		GROWBUF_ADD_CHAR(gb, '\n'); +		++sb->cur;  	    } -	    for (i = sb->cur; -		 i < sb->next && sb->buf[i] != '\n' && sb->buf[i] != '\r'; -		 i++) ; -	    if (i < sb->next) { -		len = i - sb->cur + 1; -		if (s == NULL) -		    s = Strnew_size(len + MARGIN_STR_SIZE); -		Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len); -		sb->cur = i + 1; -		if (sb->buf[i] == '\n') -		    return s; -	    } -	    else { -		if (s == NULL) -		    s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE); -		Strcat_charp_n(s, (char *)&sb->buf[sb->cur], -			       sb->next - sb->cur); -		sb->cur = sb->next; +	    break; +	} +	for (i = sb->cur; i < sb->next; ++i) { +	    if (sb->buf[i] == '\n' || (crnl && sb->buf[i] == '\r')) { +		++i; +		break;  	    }  	} +	growbuf_append(gb, &sb->buf[sb->cur], i - sb->cur); +	sb->cur = i; +	if (gb->length > 0 && gb->ptr[gb->length - 1] == '\n') +	    break;      } -    if (s == NULL) -	return Strnew(); -    return s; +    growbuf_reserve(gb, gb->length + 1); +    gb->ptr[gb->length] = '\0'; +    return;  } +#ifdef unused  int  ISread(InputStream stream, Str buf, int count)  { -    int rest, len; +    int len; + +    if (count + 1 > buf->area_size) { +	char *newptr = GC_MALLOC_ATOMIC(count + 1); +	memcpy(newptr, buf->ptr, buf->length); +	newptr[buf->length] = '\0'; +	buf->ptr = newptr; +	buf->area_size = count + 1; +    } +    len = ISread_n(stream, buf->ptr, count); +    buf->length = (len > 0) ? len : 0; +    buf->ptr[buf->length] = '\0'; +    return (len > 0) ? 1 : 0; +} +#endif + +int +ISread_n(InputStream stream, char *dst, int count) +{ +    int len, l;      BaseStream base; -    if (stream == NULL || (base = &stream->base)->iseos) +    if (stream == NULL || count <= 0) +	return -1; +    if ((base = &stream->base)->iseos)  	return 0; -    len = buffer_read(&base->stream, buf->ptr, count); -    rest = count - len; +    len = buffer_read(&base->stream, dst, count);      if (MUST_BE_UPDATED(base)) { -	len = base->read(base->handle, &buf->ptr[len], rest); -	if (len <= 0) { +	l = (*base->read) (base->handle, &dst[len], count - len); +	if (l <= 0) {  	    base->iseos = TRUE; -	    len = 0; +	} else { +	    len += l;  	} -	rest -= len;      } -    Strtruncate(buf, count - rest); -    if (buf->length > 0) -	return 1; -    return 0; +    return len;  }  int @@ -645,6 +624,7 @@ basic_close(int *handle)  #else      close(*(int *)handle);  #endif +    xfree(handle);  }  static int @@ -658,13 +638,14 @@ 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); +    xfree(handle);  }  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);  } @@ -682,6 +663,7 @@ ssl_close(struct ssl_handle *handle)      close(handle->sock);      if (handle->ssl)  	SSL_free(handle->ssl); +    xfree(handle);  }  static int @@ -717,38 +699,60 @@ static void  ens_close(struct ens_handle *handle)  {      ISclose(handle->is); +    growbuf_clear(&handle->gb); +    xfree(handle);  }  static int  ens_read(struct ens_handle *handle, char *buf, int len)  { -    if (handle->s == NULL || handle->pos == handle->s->length) { +    if (handle->pos == handle->gb.length) {  	char *p; -	handle->s = StrmyISgets(handle->is); -	if (handle->s->length == 0) +	struct growbuf gbtmp; + +	ISgets_to_growbuf(handle->is, &handle->gb, TRUE); +	if (handle->gb.length == 0)  	    return 0; -	cleanup_line(handle->s, PAGER_MODE);  	if (handle->encoding == ENC_BASE64) -	    Strchop(handle->s); +	    memchop(handle->gb.ptr, &handle->gb.length);  	else if (handle->encoding == ENC_UUENCODE) { -	    if (!strncmp(handle->s->ptr, "begin", 5)) -		handle->s = StrmyISgets(handle->is); -	    Strchop(handle->s); +	    if (handle->gb.length >= 5 && +		!strncmp(handle->gb.ptr, "begin", 5)) +		ISgets_to_growbuf(handle->is, &handle->gb, TRUE); +	    memchop(handle->gb.ptr, &handle->gb.length);  	} -	p = handle->s->ptr; +	growbuf_init_without_GC(&gbtmp); +	p = handle->gb.ptr;  	if (handle->encoding == ENC_QUOTE) -	    handle->s = decodeQP(&p); +	    decodeQP_to_growbuf(&gbtmp, &p);  	else if (handle->encoding == ENC_BASE64) -	    handle->s = decodeB(&p); +	    decodeB_to_growbuf(&gbtmp, &p);  	else if (handle->encoding == ENC_UUENCODE) -	    handle->s = decodeU(&p); +	    decodeU_to_growbuf(&gbtmp, &p); +	growbuf_clear(&handle->gb); +	handle->gb = gbtmp;  	handle->pos = 0;      } -    if (len > handle->s->length - handle->pos) -	len = handle->s->length - handle->pos; +    if (len > handle->gb.length - handle->pos) +	len = handle->gb.length - handle->pos; -    bcopy(&handle->s->ptr[handle->pos], buf, len); +    memcpy(buf, &handle->gb.ptr[handle->pos], len);      handle->pos += len;      return len;  } + +static void +memchop(char *p, int *len) +{ +    char *q; + +    for (q = p + *len; q > p; --q) { +	if (q[-1] != '\n' && q[-1] != '\r') +	    break; +    } +    if (q != p + *len) +	*q = '\0'; +    *len = q - p; +    return; +} @@ -2,13 +2,13 @@  #ifndef IO_STREAM_H  #define IO_STREAM_H +#include "indep.h"  #include <stdio.h>  #ifdef USE_SSL  #include <openssl/bio.h>  #include <openssl/x509.h>  #include <openssl/ssl.h>  #endif -#include "Str.h"  #include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h> @@ -20,7 +20,7 @@ struct stream_buffer {  typedef struct stream_buffer *StreamBuffer; -struct file_handle { +struct io_file_handle {      FILE *f;      void (*close) ();  }; @@ -36,7 +36,7 @@ union input_stream;  struct ens_handle {      union input_stream *is; -    Str s; +    struct growbuf gb;      int pos;      char encoding;  }; @@ -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) (); @@ -119,9 +119,14 @@ extern InputStream newEncodedStream(InputStream is, char encoding);  extern int ISclose(InputStream stream);  extern int ISgetc(InputStream stream);  extern int ISundogetc(InputStream stream); -extern Str StrISgets(InputStream stream); -extern Str StrmyISgets(InputStream stream); +extern Str StrISgets2(InputStream stream, char crnl); +#define StrISgets(stream) StrISgets2(stream, FALSE) +#define StrmyISgets(stream) StrISgets2(stream, TRUE) +void ISgets_to_growbuf(InputStream stream, struct growbuf *gb, char crnl); +#ifdef unused  extern int ISread(InputStream stream, Str buf, int count); +#endif +int ISread_n(InputStream stream, char *dst, int bufsize);  extern int ISfileno(InputStream stream);  extern int ISeos(InputStream stream);  #ifdef USE_SSL @@ -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 { @@ -109,6 +109,7 @@ loadLocalDir(char *dname)  	    n++;  	}      } +    closedir(d);      if (multicolList) {  	l = COLS / (maxlen + 2); @@ -359,6 +360,10 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)      int status;      pid_t pid;      char *file = uri, *name = uri, *path_info = NULL, *tmpf = NULL; +#ifdef HAVE_CHDIR +    char *cgi_dir; +#endif +    char *cgi_basename;  #ifdef __MINGW32_VERSION      return NULL; @@ -373,7 +378,14 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)  	if (!fw)  	    return NULL;      } +    if (qstr) +	uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr; +#ifdef HAVE_CHDIR +    cgi_dir = mydirname(file); +#endif +    cgi_basename = mybasename(file);      pid = open_pipe_rw(&fr, NULL); +    /* Don't invoke gc after here, or the program might crash in some platforms */      if (pid < 0)  	return NULL;      else if (pid) { @@ -383,8 +395,6 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)      }      setup_child(TRUE, 2, fw ? fileno(fw) : -1); -    if (qstr) -	uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr;      set_cgi_environ(name, file, uri);      if (path_info)  	set_environ("PATH_INFO", path_info); @@ -415,11 +425,11 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)      }  #ifdef HAVE_CHDIR		/* ifndef __EMX__ ? */ -    chdir(mydirname(file)); +    chdir(cgi_dir);  #endif -    execl(file, mybasename(file), NULL); +    execl(file, cgi_basename, NULL);      fprintf(stderr, "execl(\"%s\", \"%s\", NULL): %s\n", -	    file, mybasename(file), strerror(errno)); +	    file, cgi_basename, strerror(errno));      exit(1);      return NULL;  #endif @@ -11,6 +11,9 @@  #include <sys/wait.h>  #endif  #include <time.h> +#if defined(__CYGWIN__) && defined(USE_BINMODE_STREAM) +#include <io.h> +#endif  #include "terms.h"  #include "myctype.h"  #include "regex.h" @@ -200,10 +203,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 +253,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 +320,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); @@ -397,6 +410,10 @@ main(int argc, char **argv, char **envp)      wc_ces CodePage;  #endif  #endif +#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) +    char **getimage_args = NULL; +#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */ +      GC_INIT();  #if defined(ENABLE_NLS) || (defined(USE_M17N) && defined(HAVE_LANGINFO_CODESET))      setlocale(LC_ALL, ""); @@ -418,6 +435,10 @@ main(int argc, char **argv, char **envp)      CurrentDir = currentdir();      CurrentPid = (int)getpid(); +#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) +    if (argv[0] && *argv[0]) +	MyProgramName = argv[0]; +#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */      BookmarkFile = NULL;      config_file = NULL; @@ -530,12 +551,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 +726,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; @@ -735,6 +762,15 @@ main(int argc, char **argv, char **envp)  	    else if (!strcmp("-reqlog",argv[i])) {  		w3m_reqlog=rcFile("request.log");  	    } +#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) +	    else if (!strcmp("-$$getimage", argv[i])) { +		++i; +		getimage_args = argv + i; +		i += 4; +		if (i > argc) +		    usage(); +	    } +#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */  	    else {  		usage();  	    } @@ -823,6 +859,30 @@ main(int argc, char **argv, char **envp)      if (w3m_backend)  	backend(); +#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) +    if (getimage_args) { +	char *image_url = conv_from_system(getimage_args[0]); +	char *base_url = conv_from_system(getimage_args[1]); +	ParsedURL base_pu; +	 +	parseURL2(base_url, &base_pu, NULL); +	image_source = getimage_args[2]; +	newbuf = loadGeneralFile(image_url, &base_pu, NULL, 0, NULL); +	if (!newbuf || !newbuf->real_type || +	    strncasecmp(newbuf->real_type, "image/", 6)) +	    unlink(getimage_args[2]); +#if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT) +	symlink(getimage_args[2], getimage_args[3]); +#else +	{ +	    FILE *f = fopen(getimage_args[3], "w"); +	    if (f) +		fclose(f); +	} +#endif +	w3m_exit(0); +    } +#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */      if (w3m_dump)  	mySignal(SIGINT, SIG_IGN); @@ -833,7 +893,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 +958,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 +997,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 +1012,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; @@ -1246,6 +1313,12 @@ dump_extra(Buffer *buf)  #endif  } +static int +cmp_anchor_hseq(const void *a, const void *b) +{ +    return (*((const Anchor **) a))->hseq - (*((const Anchor **) b))->hseq; +} +  static void  do_dump(Buffer *buf)  { @@ -1266,18 +1339,20 @@ do_dump(Buffer *buf)  	int i;  	saveBuffer(buf, stdout, FALSE);  	if (displayLinkNumber && buf->href) { +	    int nanchor = buf->href->nanchor;  	    printf("\nReferences:\n\n"); -	    for (i = 0; i < buf->href->nanchor; i++) { -	        ParsedURL pu; -	        static Str s = NULL; -		if (buf->href->anchors[i].slave) +	    Anchor **in_order = New_N(Anchor *, buf->href->nanchor); +	    for (i = 0; i < nanchor; i++) +		in_order[i] = buf->href->anchors + i; +	    qsort(in_order, nanchor, sizeof(Anchor *), cmp_anchor_hseq); +	    for (i = 0; i < nanchor; i++) { +		ParsedURL pu; +		char *url; +		if (in_order[i]->slave)  		    continue; -	        parseURL2(buf->href->anchors[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", buf->href->anchors[i].hseq + 1, s->ptr); +		parseURL2(in_order[i]->url, &pu, baseURL(buf)); +		url = url_decode2(parsedURL2Str(&pu)->ptr, Currentbuf); +		printf("[%d] %s\n", in_order[i]->hseq + 1, url);  	    }  	}      } @@ -1566,6 +1641,18 @@ DEFUN(pgBack, PREV_PAGE, "Move to previous page")  		  * (Currentbuf->LINES - 1)), prec_num ? B_SCROLL : B_NORMAL);  } +/* Move half page forward */ +DEFUN(hpgFore, NEXT_HALF_PAGE, "Scroll down half page") +{ +	nscroll(searchKeyNum() * (Currentbuf->LINES / 2 - 1), B_NORMAL); +} + +/* Move half page backward */ +DEFUN(hpgBack, PREV_HALF_PAGE, "Scroll up half page") +{ +	nscroll(-searchKeyNum() * (Currentbuf->LINES / 2 - 1), B_NORMAL); +} +  /* 1 line up */  DEFUN(lup1, UP, "Scroll up one line")  { @@ -1844,6 +1931,10 @@ srch_nxtprv(int reverse)      result = srchcore(SearchString, routine[reverse]);      if (result & SR_FOUND)  	clear_mark(Currentbuf->currentLine); +    else { +	if (reverse == 0) +	    Currentbuf->pos -= 1; +    }      displayBuffer(Currentbuf, B_NORMAL);      disp_srchresult(result, (reverse ? "Backward: " : "Forward: "),  		    SearchString); @@ -2261,7 +2352,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 @@ -2804,12 +2895,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) @@ -3568,6 +3662,33 @@ DEFUN(lastA, LINK_END, "Go to the last link")      displayBuffer(Currentbuf, B_NORMAL);  } +/* go to the nth anchor */ +DEFUN(nthA, LINK_N, "Go to the nth link") +{ +    HmarkerList *hl = Currentbuf->hmarklist; +	BufferPoint *po; +	Anchor *an; + +	int n = searchKeyNum(); +	if (n < 0 || n > hl->nmark) return; + +	if (Currentbuf->firstLine == NULL) +		return; +    if (!hl || hl->nmark == 0) +		return; + +	po = hl->marks + n-1; +	an = retrieveAnchor(Currentbuf->href, po->line, po->pos); +	if (an == NULL) +		an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos); +	if (an == NULL) return; + +    gotoLine(Currentbuf, po->line); +    Currentbuf->pos = po->pos; +    arrangeCursor(Currentbuf); +    displayBuffer(Currentbuf, B_NORMAL); +} +  /* go to the next anchor */  DEFUN(nextA, NEXT_LINK, "Move to next link")  { @@ -4055,6 +4176,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) { @@ -4064,11 +4186,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);  	} @@ -4077,11 +4196,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);  	} @@ -4089,15 +4205,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; @@ -4106,14 +4229,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); @@ -4510,8 +4625,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); @@ -4570,7 +4684,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); @@ -5398,6 +5512,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) @@ -5604,7 +5770,7 @@ execdict(char *word)  	disp_message("Execution failed", TRUE);  	return;      } -    else { +    else if (buf != NO_BUFFER) {  	buf->filename = w;  	buf->buffername = Sprintf("%s %s", DICTBUFFERNAME, word)->ptr;  	if (buf->type == NULL) @@ -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) @@ -64,12 +64,22 @@ ha2d(char x, char y)  Str  decodeB(char **ww)  { +    struct growbuf gb; + +    growbuf_init(&gb); +    decodeB_to_growbuf(&gb, ww); +    return growbuf_to_Str(&gb); +} + +void +decodeB_to_growbuf(struct growbuf *gb, char **ww) +{      unsigned char c[4];      char *wp = *ww;      char d[3];      int i, n_pad; -    Str ap = Strnew_size(strlen(wp)); +    growbuf_reserve(gb, strlen(wp) + 1);      n_pad = 0;      while (1) {  	for (i = 0; i < 4; i++) { @@ -93,39 +103,50 @@ decodeB(char **ww)  	for (i = 0; i < 4; i++) {  	    c[i] = c2e(c[i]);  	    if (c[i] == BAD_BASE64) { -		*ww = wp; -		return ap; +		goto last;  	    }  	}  	d[0] = ((c[0] << 2) | (c[1] >> 4));  	d[1] = ((c[1] << 4) | (c[2] >> 2));  	d[2] = ((c[2] << 6) | c[3]);  	for (i = 0; i < 3 - n_pad; i++) { -	    Strcat_char(ap, d[i]); +	    GROWBUF_ADD_CHAR(gb, d[i]);  	}  	if (n_pad || *wp == '\0' || *wp == '?')  	    break;      } +last: +    growbuf_reserve(gb, gb->length + 1); +    gb->ptr[gb->length] = '\0';      *ww = wp; -    return ap; +    return;  }  Str  decodeU(char **ww)  { +    struct growbuf gb; + +    growbuf_init(&gb); +    decodeU_to_growbuf(&gb, ww); +    return growbuf_to_Str(&gb); +} + +void +decodeU_to_growbuf(struct growbuf *gb, char **ww) +{      unsigned char c1, c2;      char *w = *ww;      int n, i; -    Str a;      if (*w <= 0x20 || *w >= 0x60) -	return Strnew_size(0); +	return;      n = *w - 0x20; -    a = Strnew_size(n); +    growbuf_reserve(gb, n + 1);      for (w++, i = 2; *w != '\0' && n; n--) {  	c1 = (w[0] - 0x20) % 0x40;  	c2 = (w[1] - 0x20) % 0x40; -	Strcat_char(a, (c1 << i) | (c2 >> (6 - i))); +	gb->ptr[gb->length++] = (c1 << i) | (c2 >> (6 - i));  	if (i == 6) {  	    w += 2;  	    i = 2; @@ -135,7 +156,8 @@ decodeU(char **ww)  	    i += 2;  	}      } -    return a; +    gb->ptr[gb->length] = '\0'; +    return;  }  /* RFC2047 (4.2. The "Q" encoding) */ @@ -165,9 +187,19 @@ decodeQ(char **ww)  Str  decodeQP(char **ww)  { +    struct growbuf gb; + +    growbuf_init(&gb); +    decodeQP_to_growbuf(&gb, ww); +    return growbuf_to_Str(&gb); +} + +void +decodeQP_to_growbuf(struct growbuf *gb, char **ww) +{      char *w = *ww; -    Str a = Strnew_size(strlen(w)); +    growbuf_reserve(gb, strlen(w) + 1);      for (; *w != '\0'; w++) {  	if (*w == '=') {  	    w++; @@ -180,15 +212,16 @@ decodeQP(char **ww)  	    else {  		if (*w == '\0' || *(w + 1) == '\0')  		    break; -		Strcat_char(a, ha2d(*w, *(w + 1))); +		gb->ptr[gb->length++] = ha2d(*w, *(w + 1));  		w++;  	    }  	}  	else -	    Strcat_char(a, *w); +	    gb->ptr[gb->length++] = *w;      } +    gb->ptr[gb->length] = '\0';      *ww = w; -    return a; +    return;  }  #ifdef USE_M17N @@ -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を使う)" @@ -11,6 +11,8 @@ extern void pushEvent(int cmd, void *data);  extern MySignalHandler intTrap(SIGNAL_ARG);  extern void pgFore(void);  extern void pgBack(void); +extern void hpgFore(void); +extern void hpgBack(void);  extern void lup1(void);  extern void ldown1(void);  extern void ctrCsrV(void); @@ -61,6 +63,7 @@ extern void submitForm(void);  extern void followForm(void);  extern void topA(void);  extern void lastA(void); +extern void nthA(void);  extern void onA(void);  extern void nextA(void); @@ -162,6 +165,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 +201,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 +227,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 +271,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 +528,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); @@ -586,9 +607,12 @@ extern char *getAnchorText(Buffer *buf, AnchorList *al, Anchor *a);  extern Buffer *link_list_panel(Buffer *buf);  extern Str decodeB(char **ww); +extern void decodeB_to_growbuf(struct growbuf *gb, char **ww);  extern Str decodeQ(char **ww);  extern Str decodeQP(char **ww); +extern void decodeQP_to_growbuf(struct growbuf *gb, char **ww);  extern Str decodeU(char **ww); +extern void decodeU_to_growbuf(struct growbuf *gb, char **ww);  #ifdef USE_M17N  extern Str decodeWord(char **ow, wc_ces * charset);  extern Str decodeMIME(Str orgstr, wc_ces * charset); @@ -611,6 +635,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 +708,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 +749,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 @@ -786,5 +814,3 @@ extern void dispVer(void);  void srand48(long);  long lrand48(void);  #endif - -#include "indep.h" @@ -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; +} diff --git a/scripts/w3mman/w3mman2html.cgi.in b/scripts/w3mman/w3mman2html.cgi.in index f430307..2e3576c 100644 --- a/scripts/w3mman/w3mman2html.cgi.in +++ b/scripts/w3mman/w3mman2html.cgi.in @@ -126,12 +126,14 @@ while(<F>) {    s/\&/\&/g;    s/\</\</g;    s/\>/\>/g; +  # non ASCII UTF-8 codepoint +  my $utf8="[\300-\337][\200-\277]|[\340-\357][\200-\277]{2}|[\360-\367][\200-\277]{3}|[\370-\373][\200-\277]{4}|[\374\375][\200-\277]{5}"; -  s@([\200-\377].)(\010{1,2}\1)+@<b>$1</b>@g; +  s@($utf8)(\010\1)+@<b>$1</b>@g;    s@(\&\w+;|.)(\010\1)+@<b>$1</b>@g; -  s@__\010{1,2}((\<b\>)?[\200-\377].(\</b\>)?)@<u>$1</u>@g; +  s@_\010((\<b\>)?($utf8)(\</b\>)?)@<u>$1</u>@g;    s@_\010((\<b\>)?(\&\w+\;|.)(\</b\>)?)@<u>$1</u>@g; -  s@((\<b\>)?[\200-\377].(\</b\>)?)\010{1,2}__@<u>$1</u>@g; +  s@((\<b\>)?($utf8)(\</b\>)?)\010_@<u>$1</u>@g;    s@((\<b\>)?(\&\w+\;|.)(\</b\>)?)\010_@<u>$1</u>@g;    s@.\010(.)@$1@g; @@ -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) @@ -17,7 +17,7 @@  #define MAX_TABLE_N 20		/* maximum number of table in same level */  #define MAXROW 50 -#define MAXCOL 50 +#define MAXCOL 256  #define MAX_WIDTH 80 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 @@ -222,6 +222,7 @@ static void  check_cygwin_console(void)  {      char *term = getenv("TERM"); +    char *ctype;      HANDLE hWnd;      if (term == NULL) @@ -236,7 +237,9 @@ check_cygwin_console(void)  		isLocalConsole = 1;  	    }  	} -	if (strncmp(getenv("LANG"), "ja", 2) == 0) { +	if (((ctype = getenv("LC_ALL")) || +	     (ctype = getenv("LC_CTYPE")) || +	     (ctype = getenv("LANG"))) && strncmp(ctype, "ja", 2) == 0) {  	    isWinConsole = TERM_CYGWIN_RESERVE_IME;  	}  #ifdef SUPPORT_WIN9X_CONSOLE_MBCS @@ -2027,8 +2030,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();} @@ -121,6 +121,7 @@ static struct table2 DefaultGuess[] = {  };  static void add_index_file(ParsedURL *pu, URLFile *uf); +static char * schemeNumToName(int scheme);  /* #define HTTP_DEFAULT_FILE    "/index.html" */ @@ -337,7 +338,15 @@ openSSLHandle(int sock, char *hostname, char **p_cert)  	    if (strchr(ssl_forbid_method, 'T'))  		option |= SSL_OP_NO_TLSv1;  	} +#ifdef SSL_OP_NO_COMPRESSION +	option |= SSL_OP_NO_COMPRESSION; +#endif  	SSL_CTX_set_options(ssl_ctx, option); + +#ifdef SSL_MODE_RELEASE_BUFFERS +	SSL_CTX_set_mode (ssl_ctx, SSL_MODE_RELEASE_BUFFERS); +#endif +  #ifdef USE_SSL_VERIFY  	/* derived from openssl-0.9.5/apps/s_{client,cb}.c */  #if 1				/* use SSL_get_verify_result() to verify cert */ @@ -444,6 +453,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 +649,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 +674,7 @@ copyPath(char *orgpath, int length, int option)  	    }  	}  	else -	    Strcat_char(tmp, *orgpath); +	    Strcat_char(tmp, ch);  	orgpath++;  	length--;      } @@ -668,22 +684,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 +702,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 +810,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 +838,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 +966,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; @@ -1280,9 +1294,23 @@ getURLScheme(char **url)  }  static char * +schemeNumToName(int scheme) +{ +    int i; + +    for (i = 0; schemetable[i].cmdname != NULL; i++) { +	if (schemetable[i].cmd == scheme) +	    return schemetable[i].cmdname; +    } +    return NULL; +} + +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 +1334,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 +1347,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; @@ -1603,7 +1637,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,  	    pu->host != NULL && !check_no_proxy(pu->host)) {  	    hr->flag |= HR_FLAG_PROXY;  	    sock = openSocket(FTP_proxy_parsed.host, -			      schemetable[FTP_proxy_parsed.scheme].cmdname, +			      schemeNumToName(FTP_proxy_parsed.scheme),  			      FTP_proxy_parsed.port);  	    if (sock < 0)  		return uf; @@ -1645,15 +1679,15 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,  	    }  	    else if (pu->scheme == SCM_HTTPS) {  		sock = openSocket(HTTPS_proxy_parsed.host, -				  schemetable[HTTPS_proxy_parsed.scheme]. -				  cmdname, HTTPS_proxy_parsed.port); +				  schemeNumToName(HTTPS_proxy_parsed.scheme), +				  HTTPS_proxy_parsed.port);  		sslh = NULL;  	    }  	    else {  #endif				/* USE_SSL */  		sock = openSocket(HTTP_proxy_parsed.host, -				  schemetable[HTTP_proxy_parsed.scheme]. -				  cmdname, HTTP_proxy_parsed.port); +				  schemeNumToName(HTTP_proxy_parsed.scheme), +				  HTTP_proxy_parsed.port);  #ifdef USE_SSL  		sslh = NULL;  	    } @@ -1685,8 +1719,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,  	    }  	}  	else { -	    sock = openSocket(pu->host, -			      schemetable[pu->scheme].cmdname, pu->port); +	    sock = openSocket(pu->host, schemeNumToName(pu->scheme), pu->port);  	    if (sock < 0) {  		*status = HTST_MISSING;  		return uf; @@ -1750,7 +1783,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,  	    pu->host != NULL && !check_no_proxy(pu->host)) {  	    hr->flag |= HR_FLAG_PROXY;  	    sock = openSocket(GOPHER_proxy_parsed.host, -			      schemetable[GOPHER_proxy_parsed.scheme].cmdname, +			      schemeNumToName(GOPHER_proxy_parsed.scheme),  			      GOPHER_proxy_parsed.port);  	    if (sock < 0)  		return uf; @@ -1758,8 +1791,7 @@ openURL(char *url, ParsedURL *pu, ParsedURL *current,  	    tmp = HTTPrequest(pu, current, hr, extra_header);  	}  	else { -	    sock = openSocket(pu->host, -			      schemetable[pu->scheme].cmdname, pu->port); +	    sock = openSocket(pu->host, schemeNumToName(pu->scheme), pu->port);  	    if (sock < 0)  		return uf;  	    if (pu->file == NULL) @@ -2234,3 +2266,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..b9245a0 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-12+"  #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..8e2ad73 100644 --- a/w3mimg/Makefile.in +++ b/w3mimg/Makefile.in @@ -16,9 +16,9 @@ IMGCFLAGS=@IMGX11CFLAGS@ @IMGFBCFLAGS@ @IMGWINCFLAGS@  IMGOBJS=@IMGOBJS@  .PHONY: $(SUBDIRS) -all: @IMGTARGETS@ w3mimg.a +all: w3mimg.a -w3mimg.a: $(IMGOBJS) +w3mimg.a: w3mimg.o @IMGTARGETS@  	$(AR) rv $@ $(IMGOBJS)  	$(RANLIB) $@ | 
