Disable edit-actions and remote-toggle in config file by default
authorRoland Rosenfeld <roland@spinnaker.de>
Sat, 25 May 2002 19:17:36 +0000 (19:17 +0000)
committerRoland Rosenfeld <roland@spinnaker.de>
Sat, 25 May 2002 19:17:36 +0000 (19:17 +0000)
(Closes: #148125).

360 files changed:
.gitignore
AUTHORS [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
GNUmakefile.in [new file with mode: 0644]
Junkbuster Status.URL [deleted file]
LICENSE [new file with mode: 0644]
Makefile [new file with mode: 0644]
Makefile.in [deleted file]
PACKAGERS [new file with mode: 0644]
README [new file with mode: 0644]
acconfig.h
aclfile [deleted file]
actionlist.h [new file with mode: 0644]
actions.c [new file with mode: 0644]
actions.h [new file with mode: 0644]
amiga.c
amiga.h
blocklist [deleted file]
cgi.c [new file with mode: 0644]
cgi.h [new file with mode: 0644]
cgiedit.c [new file with mode: 0644]
cgiedit.h [new file with mode: 0644]
cgisimple.c [new file with mode: 0644]
cgisimple.h [new file with mode: 0644]
config
config.guess [new file with mode: 0755]
config.h [deleted file]
config.h.in [deleted file]
config.sub [new file with mode: 0755]
configure.in
contrib.sh [new file with mode: 0755]
cookiefile [deleted file]
cygwin.h
deanimate.c [new file with mode: 0644]
deanimate.h [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/dirs [new file with mode: 0644]
debian/doc-base.developer [new file with mode: 0644]
debian/doc-base.faq [new file with mode: 0644]
debian/doc-base.user [new file with mode: 0644]
debian/docs [new file with mode: 0644]
debian/init.d [new file with mode: 0644]
debian/logrotate [new file with mode: 0644]
debian/manpages [new file with mode: 0644]
debian/postinst [new file with mode: 0644]
debian/postrm [new file with mode: 0644]
debian/rules [new file with mode: 0755]
default.action [new file with mode: 0644]
default.filter [new file with mode: 0644]
doc/.gitignore [new file with mode: 0644]
doc/changes.txt [deleted file]
doc/gpl.html
doc/ijbfaq.html [deleted file]
doc/ijbman.html [deleted file]
doc/obsolete/fb.gif [new file with mode: 0755]
doc/obsolete/ijbfaq.html [new file with mode: 0644]
doc/obsolete/ijbman.html [new file with mode: 0644]
doc/obsolete/top.gif [new file with mode: 0755]
doc/pcrs.3 [new file with mode: 0644]
doc/pdf/.gitignore [new file with mode: 0644]
doc/pdf/privoxy-developer-manual.pdf [new file with mode: 0644]
doc/pdf/privoxy-faq.pdf [new file with mode: 0644]
doc/pdf/privoxy-user-manual.pdf [new file with mode: 0644]
doc/source/.gitignore [new file with mode: 0644]
doc/source/announce.sgml [new file with mode: 0644]
doc/source/authors.sgml [new file with mode: 0644]
doc/source/buildsource.sgml [new file with mode: 0644]
doc/source/contacting.sgml [new file with mode: 0644]
doc/source/copyright.sgml [new file with mode: 0644]
doc/source/developer-manual.sgml [new file with mode: 0644]
doc/source/faq.sgml [new file with mode: 0644]
doc/source/history.sgml [new file with mode: 0644]
doc/source/ldp.dsl.in [new file with mode: 0644]
doc/source/license.sgml [new file with mode: 0644]
doc/source/newfeatures.sgml [new file with mode: 0644]
doc/source/p-authors.sgml [new file with mode: 0644]
doc/source/privoxy-man-page.sgml [new file with mode: 0644]
doc/source/privoxy.sgml [new file with mode: 0644]
doc/source/readme.sgml [new file with mode: 0644]
doc/source/seealso.sgml [new file with mode: 0644]
doc/source/supported.sgml [new file with mode: 0644]
doc/source/user-manual.sgml [new file with mode: 0644]
doc/source/webserver/index.sgml [new file with mode: 0644]
doc/text/developer-manual.txt [new file with mode: 0644]
doc/text/faq.txt [new file with mode: 0644]
doc/text/user-manual.txt [new file with mode: 0644]
doc/webserver/.gitignore [moved from doc/USER_DOC_IS_WIDELY_OBSOLETED with 100% similarity]
doc/webserver/.htaccess [new file with mode: 0644]
doc/webserver/README.txt [new file with mode: 0644]
doc/webserver/actions/index.php [new file with mode: 0755]
doc/webserver/actions/results/.htaccess [new file with mode: 0644]
doc/webserver/actions/results/actions-feedback.txt [new file with mode: 0644]
doc/webserver/actions/step2.php [new file with mode: 0644]
doc/webserver/actions/step3.php [new file with mode: 0644]
doc/webserver/actions/testdrive.action [new file with mode: 0644]
doc/webserver/config/.htaccess [new file with mode: 0644]
doc/webserver/config/index.php [new file with mode: 0644]
doc/webserver/default_page.php [new file with mode: 0644]
doc/webserver/developer-manual/coding.html [new file with mode: 0644]
doc/webserver/developer-manual/contact.html [new file with mode: 0644]
doc/webserver/developer-manual/copyright.html [new file with mode: 0644]
doc/webserver/developer-manual/cvs.html [new file with mode: 0644]
doc/webserver/developer-manual/documentation.html [new file with mode: 0644]
doc/webserver/developer-manual/index.html [new file with mode: 0644]
doc/webserver/developer-manual/introduction.html [new file with mode: 0644]
doc/webserver/developer-manual/newrelease.html [new file with mode: 0644]
doc/webserver/developer-manual/quickstart.html [new file with mode: 0644]
doc/webserver/developer-manual/seealso.html [new file with mode: 0644]
doc/webserver/developer-manual/testing.html [new file with mode: 0644]
doc/webserver/developer-manual/webserver-update.html [new file with mode: 0644]
doc/webserver/faq/configuration.html [new file with mode: 0644]
doc/webserver/faq/contact.html [new file with mode: 0644]
doc/webserver/faq/copyright.html [new file with mode: 0644]
doc/webserver/faq/general.html [new file with mode: 0644]
doc/webserver/faq/index.html [new file with mode: 0644]
doc/webserver/faq/installation.html [new file with mode: 0644]
doc/webserver/faq/misc.html [new file with mode: 0644]
doc/webserver/faq/trouble.html [new file with mode: 0644]
doc/webserver/images/files-in-use.jpg [new file with mode: 0644]
doc/webserver/images/proxy_setup.jpg [new file with mode: 0644]
doc/webserver/index.html [new file with mode: 0644]
doc/webserver/man-page/privoxy-man-page.html [new file with mode: 0644]
doc/webserver/p_doc.css [new file with mode: 0644]
doc/webserver/p_feedback.css [new file with mode: 0644]
doc/webserver/p_web.css [new file with mode: 0644]
doc/webserver/privoxy.css [new file with mode: 0644]
doc/webserver/redirect.php [new file with mode: 0755]
doc/webserver/robots.txt [new file with mode: 0644]
doc/webserver/submit/confirmad.php [new file with mode: 0644]
doc/webserver/submit/index.php [new file with mode: 0644]
doc/webserver/team/01stefanw.jpg [new file with mode: 0644]
doc/webserver/team/01stefanw_t.jpg [new file with mode: 0644]
doc/webserver/team/02jon.jpg [new file with mode: 0644]
doc/webserver/team/02jon_t.jpg [new file with mode: 0644]
doc/webserver/team/03andreas.jpg [new file with mode: 0644]
doc/webserver/team/03andreas_t.jpg [new file with mode: 0644]
doc/webserver/team/04rodney.jpg [new file with mode: 0644]
doc/webserver/team/04rodney_t.jpg [new file with mode: 0644]
doc/webserver/team/05david.jpg [new file with mode: 0644]
doc/webserver/team/05david_t.jpg [new file with mode: 0644]
doc/webserver/team/05member.jpg [new file with mode: 0644]
doc/webserver/team/05member_t.jpg [new file with mode: 0644]
doc/webserver/team/06member.jpg [new file with mode: 0644]
doc/webserver/team/06member_t.jpg [new file with mode: 0644]
doc/webserver/team/07member.jpg [new file with mode: 0644]
doc/webserver/team/07member_t.jpg [new file with mode: 0644]
doc/webserver/team/08member.jpg [new file with mode: 0644]
doc/webserver/team/08member_t.jpg [new file with mode: 0644]
doc/webserver/team/09member.jpg [new file with mode: 0644]
doc/webserver/team/09member_t.jpg [new file with mode: 0644]
doc/webserver/team/10member.jpg [new file with mode: 0644]
doc/webserver/team/10member_t.jpg [new file with mode: 0644]
doc/webserver/team/11member.jpg [new file with mode: 0644]
doc/webserver/team/11member_t.jpg [new file with mode: 0644]
doc/webserver/team/12member.jpg [new file with mode: 0644]
doc/webserver/team/12member_t.jpg [new file with mode: 0644]
doc/webserver/team/13member.jpg [new file with mode: 0644]
doc/webserver/team/13member_t.jpg [new file with mode: 0644]
doc/webserver/team/14member.jpg [new file with mode: 0644]
doc/webserver/team/14member_t.jpg [new file with mode: 0644]
doc/webserver/team/15member.jpg [new file with mode: 0644]
doc/webserver/team/15member_t.jpg [new file with mode: 0644]
doc/webserver/team/16member.jpg [new file with mode: 0644]
doc/webserver/team/16member_t.jpg [new file with mode: 0644]
doc/webserver/team/17member.jpg [new file with mode: 0644]
doc/webserver/team/17member_t.jpg [new file with mode: 0644]
doc/webserver/team/18member.jpg [new file with mode: 0644]
doc/webserver/team/18member_t.jpg [new file with mode: 0644]
doc/webserver/team/19member.jpg [new file with mode: 0644]
doc/webserver/team/19member_t.jpg [new file with mode: 0644]
doc/webserver/team/20member.jpg [new file with mode: 0644]
doc/webserver/team/20member_t.jpg [new file with mode: 0644]
doc/webserver/team/index.html [new file with mode: 0644]
doc/webserver/user-manual/actions-file.html [new file with mode: 0644]
doc/webserver/user-manual/appendix.html [new file with mode: 0644]
doc/webserver/user-manual/config.html [new file with mode: 0644]
doc/webserver/user-manual/configuration.html [new file with mode: 0644]
doc/webserver/user-manual/contact.html [new file with mode: 0644]
doc/webserver/user-manual/copyright.html [new file with mode: 0644]
doc/webserver/user-manual/filter-file.html [new file with mode: 0644]
doc/webserver/user-manual/index.html [new file with mode: 0644]
doc/webserver/user-manual/installation.html [new file with mode: 0644]
doc/webserver/user-manual/introduction.html [new file with mode: 0644]
doc/webserver/user-manual/quickstart.html [new file with mode: 0644]
doc/webserver/user-manual/seealso.html [new file with mode: 0644]
doc/webserver/user-manual/startup.html [new file with mode: 0644]
doc/webserver/user-manual/templates.html [new file with mode: 0644]
doc/webserver/user-manual/upgradersnote.html [new file with mode: 0644]
encode.c
encode.h
errlog.c
errlog.h
filters.c
filters.h
forward [deleted file]
gateway.c
gateway.h
genclspec.sh [new file with mode: 0755]
icons/denyrule.ico [deleted file]
icons/icon1.ico [deleted file]
icons/idle.ico
icons/os2.ico [new file with mode: 0644]
icons/os20.ico [new file with mode: 0644]
icons/os21.ico [new file with mode: 0644]
icons/os22.ico [new file with mode: 0644]
icons/os23.ico [new file with mode: 0644]
icons/os24.ico [new file with mode: 0644]
icons/os25.ico [new file with mode: 0644]
icons/os26.ico [new file with mode: 0644]
icons/os27.ico [new file with mode: 0644]
icons/os28.ico [new file with mode: 0644]
icons/privoxy.ico [moved from icons/junkbust.ico with 59% similarity]
imagelist [deleted file]
install-sh [new file with mode: 0755]
jbsockets.c
jbsockets.h
jcc.c
jcc.h
junkbstr.txt [deleted file]
junkbuster.1 [deleted file]
junkbuster.init [deleted file]
junkbuster.logrotate [deleted file]
junkbuster.monthly [deleted file]
junkbuster.weekly [deleted file]
killpopup.c
killpopup.h
list.c [new file with mode: 0644]
list.h [new file with mode: 0644]
loadcfg.c
loadcfg.h
loaders.c
loaders.h
miscutil.c
miscutil.h
parsers.c
parsers.h
pcre/.gitignore [new file with mode: 0644]
pcre/Makefile.in [new file with mode: 0644]
pcre/RunTest.in [new file with mode: 0644]
pcre/chartables.c [deleted file]
pcre/config.guess [new file with mode: 0644]
pcre/config.h
pcre/config.in [new file with mode: 0644]
pcre/config.sub [new file with mode: 0644]
pcre/configure [moved from configure with 74% similarity, mode: 0644]
pcre/configure.in [new file with mode: 0644]
pcre/dftables.c [new file with mode: 0644]
pcre/dll.mk [new file with mode: 0644]
pcre/doc/ChangeLog [new file with mode: 0644]
pcre/doc/NON-UNIX-USE [new file with mode: 0644]
pcre/doc/Tech.Notes [new file with mode: 0644]
pcre/doc/authors [new file with mode: 0644]
pcre/doc/copying [new file with mode: 0644]
pcre/doc/news [new file with mode: 0644]
pcre/doc/pcre.3 [new file with mode: 0644]
pcre/doc/pcre.html [new file with mode: 0644]
pcre/doc/pcre.txt [new file with mode: 0644]
pcre/doc/pcregrep.1 [new file with mode: 0644]
pcre/doc/pcregrep.html [new file with mode: 0644]
pcre/doc/pcregrep.txt [new file with mode: 0644]
pcre/doc/pcreposix.3 [new file with mode: 0644]
pcre/doc/pcreposix.html [new file with mode: 0644]
pcre/doc/pcreposix.txt [new file with mode: 0644]
pcre/doc/pcretest.txt [new file with mode: 0644]
pcre/doc/perltest.txt [new file with mode: 0644]
pcre/doc/readme [new file with mode: 0644]
pcre/get.c [new file with mode: 0644]
pcre/install [new file with mode: 0644]
pcre/install-sh [new file with mode: 0644]
pcre/internal.h [new file with mode: 0644]
pcre/licence [new file with mode: 0644]
pcre/ltconfig [new file with mode: 0644]
pcre/ltmain.sh
pcre/maketables.c [new file with mode: 0644]
pcre/pcre-config [new file with mode: 0644]
pcre/pcre-config.in [new file with mode: 0644]
pcre/pcre.def [new file with mode: 0644]
pcre/pcre.h
pcre/pcre.in
pcre/pcregrep.c [new file with mode: 0644]
pcre/pcreposix.c
pcre/pcreposix.h [new file with mode: 0644]
pcre/pcretest.c [new file with mode: 0644]
pcre/study.c [new file with mode: 0644]
pcre/vc_dftables.dsp [new file with mode: 0755]
pcrs.c
pcrs.h
popup [deleted file]
privoxy-rh.spec [new file with mode: 0644]
privoxy-suse.spec [new file with mode: 0644]
privoxy.1 [new file with mode: 0644]
privoxy.init [new file with mode: 0644]
privoxy.init.suse [new file with mode: 0644]
privoxy.logrotate [new file with mode: 0644]
privoxy.monthly [new file with mode: 0644]
privoxy.weekly [new file with mode: 0644]
project.h
re_filterfile [deleted file]
showargs.c [deleted file]
showargs.h [deleted file]
ssplit.c
ssplit.h
standard.action [new file with mode: 0644]
templates/blocked [new file with mode: 0644]
templates/cgi-error-404 [new file with mode: 0644]
templates/cgi-error-bad-param [new file with mode: 0644]
templates/cgi-error-disabled [new file with mode: 0644]
templates/cgi-error-file [new file with mode: 0644]
templates/cgi-error-file-read-only [new file with mode: 0644]
templates/cgi-error-modified [new file with mode: 0644]
templates/cgi-error-parse [new file with mode: 0644]
templates/cgi-style.css [new file with mode: 0644]
templates/connect-failed [new file with mode: 0644]
templates/default [new file with mode: 0644]
templates/edit-actions-add-url-form [new file with mode: 0644]
templates/edit-actions-for-url [new file with mode: 0644]
templates/edit-actions-for-url-filter [new file with mode: 0644]
templates/edit-actions-list [new file with mode: 0644]
templates/edit-actions-list-button [new file with mode: 0644]
templates/edit-actions-list-section [new file with mode: 0644]
templates/edit-actions-list-url [new file with mode: 0644]
templates/edit-actions-remove-url-form [new file with mode: 0644]
templates/edit-actions-url-form [new file with mode: 0644]
templates/mod-local-help [new file with mode: 0644]
templates/mod-support-and-service [new file with mode: 0644]
templates/mod-title [new file with mode: 0644]
templates/mod-unstable-warning [new file with mode: 0644]
templates/no-such-domain [new file with mode: 0644]
templates/show-request [new file with mode: 0644]
templates/show-status [new file with mode: 0644]
templates/show-status-file [new file with mode: 0644]
templates/show-url-info [new file with mode: 0644]
templates/show-version [new file with mode: 0644]
templates/toggle [new file with mode: 0644]
templates/toggle-mini [new file with mode: 0644]
templates/untrusted [new file with mode: 0644]
testdrive.status [new file with mode: 0644]
trust
urlmatch.c [new file with mode: 0644]
urlmatch.h [new file with mode: 0644]
user.action [new file with mode: 0644]
vc_config_pthreads.h [new file with mode: 0644]
vc_config_winthreads.h [new file with mode: 0644]
vc_console.dsp [new file with mode: 0644]
vc_junkbuster.dsw [deleted file]
vc_privoxy.dsp [moved from vc_junkbuster.dsp with 57% similarity]
vc_privoxy.dsw [new file with mode: 0644]
w32.aps [deleted file]
w32.rc
w32log.c
w32log.h
w32res.h
w32rulesdlg.c [deleted file]
w32rulesdlg.h [deleted file]
w32taskbar.c
w32taskbar.h
win32.c
win32.h

index 40caffa..d81f13a 100644 (file)
@@ -26,3 +26,29 @@ _$*
 *.ln
 core
 # CVS default ignores end
+*.txt
+GNUmakefile
+Makefile
+configure
+config.cache
+config.h
+config.h.in
+config.log
+config.status
+jarfile
+logfile
+privoxy
+privoxy.exe
+privoxy-cl.spec
+vc_debug
+vc_debug_winthr
+vc_console.ncb
+vc_console.opt
+vc_console.plg
+vc_privoxy.ncb
+vc_privoxy.opt
+vc_privoxy.plg
+vc_release
+vc_release_winthr
+w32.aps
+w32.res
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..f670006
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,49 @@
+              Authors of Privoxy v2.9.x and 3.x
+===========================================================================
+
+Current Project Developers:
+
+ Jon Foster
+ Andreas Oesterhelt
+ Stefan Waldherr
+ Thomas Steudten
+ Rodney Stromlund
+
+Current Project Contributors:
+
+ Rodrigo Barbosa (RPM specfiles)
+ Hal Burgiss (docs)
+ Alexander Lazic
+ Gábor Lipták
+ Guy
+ Haroon Rafique
+ David Schmidt (OS/2, Mac OSX ports)
+ Joerg Strohmayer
+ Sarantis Paskalis
+
+Originally developed by:
+
+ Junkbusters Corp.
+ Anonymous Coders
+
+Thanks to the many people who have tested Privoxy, reported bugs, or made
+suggestions. These include (in alphabetical order):
+
+ Ken Arromdee
+ Reiner Buehl
+ Andrew J. Caines
+ Clifford Caoile
+ Peter E
+ Aaron Hamid
+ Magnus Holmgren
+ Paul Lieverse
+ Roberto Ragusa
+ Bart Schelstraete
+ Darren Wiebe
+
+If we've missed you off this list, please let us know!
+
+ Privoxy team. http://www.privoxy.org/
+ <ijbswa-developers@lists.sourceforge.net>
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..54d4e7d
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,227 @@
+--------------------------------------------------------------------
+ChangeLog for Privoxy
+--------------------------------------------------------------------
+*** Version 2.9.15 (current CVS) *** 
+
+- Impose buffer limits while reading client and server headers.
+- Better memory and CPU optimization.
+- Add Conectiva Linux package.
+- Actions files are changed to: default.action, standard.action, and 
+  user.action. user.action is for personal/local configuration.
+- Major overhaul of the CGI editor (ongoing).
+- Multiple actions files can now be specified in config.
+- The usual many small and miscellaneous fixes.
+
+*** Version 2.9.14 Beta *** 
+
+- Fix Solaris compile problem (gateway.h and filters.h)
+- Makefile fixes for Solaris, FreeBSD (?)
+- Fix build failure where certain features were disabled.
+- 'blocked-compact' template is removed. Various CGI improvements,
+  including an adaptive 'blocked' template.
+- Various tweaks for actions file to get ready for stable 3.0
+- Included a 'Bookmarklet' and PHP scripts for reporting actions file
+  problems via web interface at privoxy.org. Accessed via internal CGIs.
+- Include cgi-style.css for templates.
+- #include mechansim for common text in templates
+- Various other minor fixes.
+
+*** Version 2.9.13 Beta *** 
+
+- *NEWS*: The project has been renamed to Privoxy! The new name is 
+  reflected throughout (file locations, etc).
+- ijb.action is now default.action. re_filterfile is now 
+  default.filter.
+- http://i.j.b/ is now http://p.p/
+- The 'logo' option for replacing ad iamges is removed now. 'Pattern' 
+  (checkerboard) is now the default.
+- RPM spec file make over.
+
+
+*** Version 2.9.12 Beta *** 
+
+- **READ**: The default listening PORT is NOW 8118!!! Changed from 
+  8000 due to conflict with NAS (Network Audio Server, whatever that 
+  is.)
+- More CGI actions editor fixes and improvements.
+- Win32 command line fix ups.
+- re_filterfile now has modular sections that can be activated on a 
+  per site basis. Some new goodies there too.
+- +filter now takes arguments to match FILTER sections in re_filterfile
+  for even more flexibility. 
+- Added a new image blocker option: +image-blocker{pattern}, which 
+  displays a checkerboard patthern and scales better than the logo.
+- PNG images will be used in place of GIF for JB built-in images
+  if configured with --enable-no-gif.
+- Clean up compiler warnings (mostly).
+- Improved handling of failed DNS lookups & diagnostics for failed bind
+  to listen socket
+- Made --no-daemon mode log to tty instead of logfile.
+- Various spec file and init script cleanups and improvements (Redhat and
+  SuSE).
+- CGI Editor works on OS/2 now.
+- Fix restart failure where sockets were in TIME_WAIT.
+- Fixes for actions cgi editor, make sure we have right file.
+- A --pidfile command line option now, in addition to --help, 
+  --version, --no-daemon, --user and configfile. --no-daemon replaces
+  the former -d option and _DEBUG define. --user will drop privileges 
+  to the specified user.
+- Signal handling cleanups (*nix).
+- CGI actions editor improvements and fixes.
+- Error handling improvements, especially out of memory.
+- Default re_filterfile fix that caused spurious IJB logos 
+  (instead of 'blank').
+- configure.in threading fixes for Solaris.
+- Various other minor fixes.
+
+
+*** Version 2.9.11 Beta Changes ***
+
+- Add "session" cookie concept where cookies exist for the life 
+of that browser session only (ie never goes to disk). 
+- Checks for correct header length.
+- Fix user:pass@host.domain.com auth bug.
+- Better signal handling on *nix.
+- Fix CFLAGS hard-coded in configure.in
+- Fix threading bug re: gethostbyname() that caused random 
+URLs to fail in some cases.
+
+
+*** Version 2.9.11 Alpha Changes ***
+
+- A web-based editor for the actions file is included (go to http://i.j.b/).
+- Web-based toggle IJB on/off support.
+- Cookie handling has changed - the new +no-cookies-keep feature is now the
+default.
+- actionsfile is renamed to ijb.action.
+- junkbstr.txt is now config.txt on Win32.
+- Support for running IJB as a UNIX daemon process has improved.
+- Unix daemon now returns error code on failed start.
+- Timestamps in logfile and jarfile now.
+- Fix for the Netscape bug reintroduced in 2.9.9.
+- make should now abort if gmake (GNU make) not present.
+- Many other minor bugfixes
+- Start a ChangeLog :)
+
+
+
+*** Version 2.9.3 pre-Alpha Changes ***
+
+- Amiga support (completely untested by me - I don't have an Amiga)
+- "tinygif 3" support (redirects blocked images to a specified URL, so
+the browser doesn't have to load and cache many copies of the same
+image).
+- one case where there were both local and global "referrer" variables
+(yuck!) clarified by renaming the local one to "refer".
+- Fixed some places where close() was used instead of close_socket().
+Thanks to Jörg Strohmayer (joergs at users.sourceforge.net) for these.
+- Temporary hack to get FORCE_LOAD to work with IE.  I just lowercased the
+FORCE_LOAD_PREFIX.  Needs fixing properly.
+- Most URLs hardcoded into Junkbuster were changed to go through a script
+e.g. http://ijbswa.sourceforge.net/redirect.php?v=2.9.3&to=faq
+The only other URLs left are the GNU GPL:
+  http://www.fsf.org/copyleft/gpl.html
+and the home page:
+  http://ijbswa.sourceforge.net/
+... and various URLs which will be intercepted by Junkbuster anyway.
+TODO: Still need to do something with the URLs in Junkbuster Corp's 
+copyright/trademark notice on the bottom of the show-proxy-args page.
+- PCRE or GNU Regex is now a #define option.
+
+
+*** Version 2.9.2 pre-Alpha Changes ***
+
+- Andreas applied the latest version of the FORCE patch.
+
+
+*** Version 2.9.1 pre-Alpha Changes ***
+
+- in parsers.c, fixed two #ifdef FORCE to #ifdef FORCE_LOAD
+(BTW: I think FORCE is precise enough, since loading remote
+data is the whole purpose of a proxy..)
+- Set the FORCE_PREFIX (back) to 'IJB-FORCE-LOAD-'. While 'noijb.'
+is more elegant and looks like a hostname in the URL, it doesn't
+make clear to the inexperienced user that the proxy is bypassed. It
+also has a higher name collision risk.
+- Filled in the function header templates for my functions in
+parsers.c (again). They obviously got lost in our current
+patch war ;-)
+- Cut the credit for the Â§-referrer-option from the config file,
+that Stefan had placed there.
+- Improved the re_filterfile 
+
+
+*** Version 2.9.0 pre-Alpha Changes ***
+
+-  Now use PCRE, not GNU REGEX.  I have not yet had chance to check the
+syntax of the block/image/cookie file to ensure that they match what
+is expected - however they seem to work.
+-  Replaced "configure" script with one generated by "autoconf".  Also 
+use a header "config.h" (was ijbconfig.h in my previous release) for 
+the #defines.  "config.h" is now generated with "autoheader" from 
+"acconfig.h" and "configure.in".  (Note that to install you do not
+need autoconf or autoheader - just run "./configure".)
+To see command-line options, run "./configure --help".
+This is my first ever autoconf script, so it has some rough edges
+(how PCRE is handled is the roughest).
+-  Error logging code replaced with new module errlog.c, based on the
+one from JunkbusterMT (but with the threading code removed).
+-  Most of Rodney's 0.21 and 0.21A patches applied. (Marked *).  I did not
+apply all of these, since I had already independently done conditional
+popup file, conditional image file, and integration of popup code.
+- ACL, Jar and trust files conditionally compiled.
+- New source file headers.
+- Various cosmetic changes.  (But I have not consistently ordered the 
+config files - I think that's worthwhile, but it's 1am and I want to
+get this released!)
+- RCS tags on .h files.
+-  RCS tags are const char[] rather than const char *.  (Saves 4 bytes
+per tag ;-)
+- VC++ project files renamed to vc_junkbuster.*.
+- show-proxy-args now shows status of all conditionals, not just REGEX
+- Various functions moved around.  Most notably all the system-specific
+sockets code which was spread between jcc.c, bind.c, and connect.c,
+has been moved to "jbsockets.c".  The non-system-specific code from
+connect.c and socks4.c has been movet to "gateway.c".  Also, the
+config file loader and the global variables it writes to have been
+moved to "loadcfg.c".  (Maybe this should go into loaders.c?)
+And candidate for the "worst filename ever" award is "miscutil.c",
+which contains, well, miscellaneous utility functions like zalloc.
+(Suggestions for a better name for this file are welcome!)
+- Loaders now use a common function to read a line and skip comments,
+and this function also stores the proxy_args.
+- Added ./junkbuster --help     (Not for Win32 GUI)
+- Added ./junkbuster --version  (Not for Win32 GUI)
+- Win32 resources are now all marked as "U.S. English", rather than
+being a mix of "U.S. English", "U.K. English" and "Irish English".
+- Version number changes to 2.9.0
+
+
+
+----------------------------------------------------------------------
+Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+               Privoxy team. http://www.privoxy.org/
+
+               Based on the Internet Junkbuster originally written
+               by and Copyright (C) 1997 Anonymous Coders and 
+               Junkbusters Corporation.  http://www.junkbusters.com
+
+               This program is free software; you can redistribute it 
+               and/or modify it under the terms of the GNU General
+               Public License as published by the Free Software
+               Foundation; either version 2 of the License, or (at
+               your option) any later version.
+
+               This program is distributed in the hope that it will
+               be useful, but WITHOUT ANY WARRANTY; without even the
+               implied warranty of MERCHANTABILITY or FITNESS FOR A
+               PARTICULAR PURPOSE.  See the GNU General Public
+               License for more details.
+
+               The GNU General Public License should be included with
+               this file.  If not, you can view it at
+               http://www.gnu.org/copyleft/gpl.html
+               or write to the Free Software Foundation, Inc., 59
+               Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+
diff --git a/GNUmakefile.in b/GNUmakefile.in
new file mode 100644 (file)
index 0000000..2429ec1
--- /dev/null
@@ -0,0 +1,1408 @@
+# Note:  Makefile is built automatically from Makefile.in
+#
+# $Id: GNUmakefile.in,v 1.103 2002/05/23 23:19:00 oes Exp $
+#
+# Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Based on the Internet Junkbuster originally written
+# by and Copyright (C) 1997 Anonymous Coders and 
+# Junkbusters Corporation.  http://www.junkbusters.com
+#
+# This program is free software; you can redistribute it 
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.  See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file.  If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+#############################################################################
+# Set make command correctly
+#############################################################################
+@SET_MAKE@
+
+#############################################################################
+# Version number (for RPM)
+#############################################################################
+
+VERSION_MAJOR = @VERSION_MAJOR@
+VERSION_MINOR = @VERSION_MINOR@
+VERSION_POINT = @VERSION_POINT@
+CODE_STATUS   = @CODE_STATUS@
+VERSION       = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_POINT)
+RPM_VERSION   = $(VERSION)
+
+
+#############################################################################
+# Directories for "make install"
+#############################################################################
+
+DEST        = @prefix@
+CONFDEST    = @prefix@@sysconfdir@
+SBIN_DEST   = @prefix@@sbindir@
+MAN_DEST    = @prefix@@mandir@
+DOK_WEB_USEM=doc/webserver/user-manual
+
+#############################################################################
+# Build tools
+#############################################################################
+
+PROGRAM    = privoxy@EXEEXT@
+CC         = @CC@
+ECHO       = echo
+GZIP_PROG  = gzip
+#INSTALL    = cp -f
+INSTALL    = @INSTALL@
+INSTALL_P  = -m 0750 -g @GROUP@ -o @USER@ -b
+INSTALL_T  = -m 0640 -g @GROUP@ -o @USER@ -b
+INSTALL_D  = -m 0750 -g @GROUP@ -o @USER@ -d
+LD         = @CC@
+RM         = rm -f
+STRIP_PROG = strip
+SED       = sed
+CAT        = cat
+RPM        = rpm
+MV        = mv
+TAR        = tar
+LN         = ln
+WDUMP      = @WDUMP@ -dump
+JADECAT    = @JADECAT@
+JADEBIN    = @JADEBIN@
+DB         = $(JADEBIN) $(JADECAT) -ihtml -t sgml  -D.. -d ldp.dsl\#html
+DB2HTML    = @DB2HTML@
+MAN2HTML   = @MAN2HTML@
+G2H_CMD    = groff -mandoc -Thtml
+TARGET_OS  = @host@
+PERL       = perl
+DOC_DIR         = doc/source
+DOC_TMP    = $(DOC_DIR)/tmp
+
+
+#User Group paras
+USER       = @USER@
+GROUP     = @GROUP@
+
+# Program to do LF->CRLF
+#
+# The sed version should be the most portable, but it doesn't for for me,
+# the other two do.  FIXME.
+#   - Jon
+#DOSFILTER  = $(SED) -e $$'s,$$,\r,'
+#DOSFILTER  = gawk -v ORS='\r\n' '{print $0;}'
+DOSFILTER  = $(PERL) -p -e 's/\n/\r\n/'
+
+#############################################################################
+# Setup for make distribution rh and suse for now 
+#############################################################################
+
+TAR_ARCH = /tmp/privoxy-$(RPM_VERSION).tar.gz
+RPM_BASE = @RPM_BASE@
+
+#############################################################################
+# We include these files in our distributions
+#############################################################################
+# take care that no CVS .cvsignore or other crappy files
+# are included here
+# and escape every '#' in the find. doh.
+CONFIG_FILES = config trust \
+               default.action \
+               basic.action intermediate.action advanced.action \
+               default.filter \
+               `find templates/ -type f | grep -v "CVS" | grep -v "\.\#" | grep -v ".*~" | grep -v ".cvsignore" | grep -v "TAGS"`
+
+DOC_FILES = AUTHORS LICENSE README ChangeLog \
+               `find doc/text/ -type f | grep -v "CVS" | grep -v "\.\#" | grep -v ".*~" | grep -v ".cvsignore" | grep -v "TAGS"` \
+               `find doc/webserver/ -name "*.html"` \
+               `find doc/webserver/ -name "*.css"` \
+                privoxy.1
+
+#############################################################################
+# Filenames and libraries
+#############################################################################
+
+C_SRC  = actions.c cgi.c cgiedit.c cgisimple.c deanimate.c encode.c \
+         errlog.c filters.c gateway.c jbsockets.c jcc.c killpopup.c \
+         list.c loadcfg.c loaders.c miscutil.c parsers.c ssplit.c \
+         urlmatch.c
+
+C_OBJS = $(C_SRC:.c=.@OBJEXT@)
+C_HDRS = $(C_SRC:.c=.h) project.h actionlist.h
+
+W32_SRC   = @WIN_ONLY@w32log.c w32taskbar.c win32.c
+W32_FILES = @WIN_ONLY@w32.res
+W32_OBJS  = @WIN_ONLY@$(W32_SRC:.c=.@OBJEXT@) $(W32_FILES)
+W32_HDRS  = @WIN_ONLY@w32log.h w32taskbar.h win32.h w32res.h
+W32_LIB   = @WIN_ONLY@-lwsock32 -lcomctl32
+W32_INIS  = @WIN_ONLY@config.txt trust.txt
+
+PCRS_SRC     = @STATIC_PCRS_ONLY@pcrs.c
+PCRS_OBJS    = @STATIC_PCRS_ONLY@$(PCRS_SRC:.c=.@OBJEXT@)
+PCRS_HDRS    = @STATIC_PCRS_ONLY@$(PCRS_SRC:.c=.h)
+
+PCRE_SRC     = @STATIC_PCRE_ONLY@pcre/get.c pcre/maketables.c pcre/study.c pcre/pcre.c
+PCRE_OBJS    = @STATIC_PCRE_ONLY@$(PCRE_SRC:.c=.@OBJEXT@)
+PCRE_HDRS    = @STATIC_PCRE_ONLY@pcre/config.h pcre/chartables.c pcre/internal.h pcre/pcre.h
+
+# No REGEX (maybe because dynamically linked pcreposix):
+REGEX_SRC    =
+@STATIC_PCRE_ONLY@REGEX_SRC = pcre/pcreposix.c
+
+REGEX_OBJS   = $(REGEX_SRC:.c=.@OBJEXT@)
+REGEX_HDRS   = $(REGEX_SRC:.c=.h)
+
+# Dependencies introduced by #include "project.h".
+PROJECT_H_DEPS = project.h $(REGEX_HDRS) $(PCRS_HDRS) @STATIC_PCRE_ONLY@pcre/pcre.h
+
+# Socket libraries for platforms that need them explicitly defined
+SOCKET_LIB   = @SOCKET_LIB@
+
+# PThreads library, if needed.
+PTHREAD_LIB  = @PTHREAD_ONLY@@PTHREAD_LIB@
+
+SRCS         = $(C_SRC)  $(W32_SRC)  $(PCRS_SRC)  $(PCRE_SRC)  $(REGEX_SRC)
+OBJS         = $(C_OBJS) $(W32_OBJS) $(PCRS_OBJS) $(PCRE_OBJS) $(REGEX_OBJS)
+HDRS         = $(C_HDRS) $(W32_HDRS) $(PCRS_HDRS) $(PCRE_OBJS) $(REGEX_HDRS)
+LIBS         = @LIBS@ $(W32_LIB) $(SOCKET_LIB) $(PTHREAD_LIB)
+
+
+#############################################################################
+# Compiler switches
+#############################################################################
+
+# The flag "-mno-win32" can be used by Cygwin to emulate a un?x type build.
+# The flag "-mwindows -mno-cygwin" will cause Cygwin to use MingW32 for a
+# Win32 GUI build.
+# The flag "-pthread" is required if using Pthreads under Linux (and
+# possibly other OSs).
+SPECIAL_CFLAGS = @SPECIAL_CFLAGS@
+
+# Add your flags here 
+OTHER_CFLAGS =   
+
+CFLAGS = @CFLAGS@ @CPPFLAGS@ $(OTHER_CFLAGS) $(SPECIAL_CFLAGS) -Wall \
+         @STATIC_PCRE_ONLY@ -Ipcre 
+
+LDFLAGS = $(DEBUG_CFLAGS) $(SPECIAL_CFLAGS)
+
+
+#############################################################################
+# Build section.
+#
+# There should NOT be any targets above this line.
+#############################################################################
+all: $(PROGRAM)
+
+
+#############################################################################
+# Phony targets
+#############################################################################
+.PHONY: all inifiles redhat-dist redhat-upload solaris-dist suse-dist \
+suse-upload win-dist tarball-dist dok redhat-dok webserver clean clobber tags \
+install conectiva-spec conectiva-dist conectiva-upload
+
+
+#############################################################################
+# Define this explicitly because Solaris is broken!
+#############################################################################
+%.o: %.c
+       $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
+
+
+#############################################################################
+# Win32 config files
+#############################################################################
+
+inifiles: $(W32_INIS)
+
+config.txt: config
+       $(SED) -e 's!\trustfile trust!trustfile trust.txt!' \
+              -e 's!\jarfile jarfile!jarfile jar.log!' \
+              -e 's!\logfile logfile!logfile privoxy.log!' \
+              -e 's!#Win32-only: !!' \
+              < $< | \
+              $(DOSFILTER) > $@
+       # LF to CRLF in default.action
+       $(DOSFILTER) <default.action >default.action.txt && mv default.action.txt default.action
+       # LF to CRLF in default.filter
+       $(DOSFILTER) <default.filter >default.filter.txt && mv default.filter.txt default.filter
+
+trust.txt: trust
+       $(DOSFILTER) < $< > $@ 
+
+re_filterfile.txt: re_filterfile
+       $(DOSFILTER) < $< > $@ 
+
+
+#############################################################################
+# Pre-dist check:
+#############################################################################
+dist-check:
+       @if [ -d CVS ]; then \
+           $(ECHO) "***************************************************"; \
+           $(ECHO) "***                                             ***"; \
+           $(ECHO) "***                  WARNING                    ***"; \
+           $(ECHO) "***                                             ***"; \
+           $(ECHO) "*** The presence of a CVS subdirectory suggests ***"; \
+           $(ECHO) "*** that you are trying to build a distribution ***"; \
+           $(ECHO) "*** package based on a checked out, not an      ***"; \
+           $(ECHO) "*** exported copy of the source tree. Please    ***"; \
+           $(ECHO) "*** see \"Releasing a new version\" in the        ***"; \
+           $(ECHO) "*** developer manual.                           ***"; \
+           $(ECHO) "***                                             ***"; \
+           $(ECHO) "***************************************************"; \
+           $(ECHO) "Type \"yes i am sure\" if you are sure that you"; \
+           $(ECHO) -n "really want to proceed: "; \
+           read answer; \
+           if [ "$$answer" != "yes i am sure" ]; then exit 1; fi \
+         fi;
+
+
+#############################################################################
+# RPM specifice stuff (SuSE or Redhat, ..)
+#############################################################################
+rpm-stuff: dist-check clean clobber 
+       for dir in RPMS SRPMS BUILD SOURCES SPECS; do \
+               if [ ! -w $(RPM_BASE)/$$dir ]; then \
+                       $(ECHO) "$(RPM_BASE)/$$dir is not writable for you. Maybe try as root."; \
+                       $(ECHO) "Or add a suitable path to .rpmmacros like."; \
+                       $(ECHO) "%_topdir /home/foo/rpm-build"; \
+                       exit 1; \
+               fi; \
+       done; \
+
+check-release:
+       @if [ "$(RPM_PACKAGEV)" = "" ]; then \
+               echo ; \
+               echo "  ERROR: NO RPM_PACKAGEV VALUE"; \
+               echo "  No value given for RPM_PACKAGEV. Please use:"; \
+               echo "  make dist-upload RPM_PACKAGEV=release"; \
+               echo "  where \"release\" is the release number you want to and"; \
+               echo "  where \"dist\" is the name of the distro (redhat or suse)"; \
+               echo ; \
+               echo "  Ex: make redhat-upload RPM_PACKAGEV=1"; \
+               echo ""; \
+               echo "ATTENTION: If your distribution use a specific tag on the"; \
+               echo "           release field (like \"cl\" for Conectiva, and"; \
+               echo "           \"mdk\" for Mandrake), DO NOT put it on the value"; \
+               echo "           given to RPM_PACKAGEV. It will be added automaticaly."; \
+               echo "           Do it like you would do for a redhat package,"; \
+               echo "           (i.e. just the number)."; \
+               echo ; \
+               exit 1; \
+       fi
+
+
+#############################################################################
+# Create Conectiva specfile from RedHat specfile
+#############################################################################
+conectiva-spec:
+       $(RM) privoxy-cl.spec
+       chmod a+x genclspec.sh
+       ./genclspec.sh
+
+#############################################################################
+# Conectiva distribution for x86
+#############################################################################
+conectiva-dist: rpm-stuff conectiva-spec
+
+       $(TAR) --exclude ".cvsignore" --exclude "CVS" --exclude "privoxy-suse.spec" --exclude "privoxy-rh.spec" --exclude "PACKAGERS" -czf $(TAR_ARCH) .
+       $(RPM) --clean -ta  $(TAR_ARCH)
+       if [ -f $(TAR_ARCH) ]; then  $(RM) $(TAR_ARCH); fi
+
+conectiva-upload: check-release
+       make redhat-upload RPM_PACKAGEV=$(RPM_PACKAGEV)cl
+
+#############################################################################
+# redhat distribution alpha and x86
+#############################################################################
+redhat-dist: rpm-stuff
+
+       $(TAR) --exclude ".cvsignore" --exclude "CVS" --exclude "privoxy-suse.spec" --exclude "privoxy-cl.spec" --exclude "PACKAGERS" -czf $(TAR_ARCH) .
+       $(RPM) --clean -ta  $(TAR_ARCH)
+       if [ -f $(TAR_ARCH) ]; then  $(RM) $(TAR_ARCH); fi
+
+# anonymously ncftps the rpms to sourceforge
+redhat-upload: check-release
+       ncftpput -u anonymous -p ijbswa-developers@lists.sourceforge.net upload.sourceforge.net /incoming $(RPM_BASE)/SRPMS/privoxy-$(RPM_VERSION)-$(RPM_PACKAGEV).src.rpm
+# better should use `arch` here instead of ix86 to support other platforms too
+       ncftpput -u anonymous -p ijbswa-developers@lists.sourceforge.net upload.sourceforge.net /incoming $(RPM_BASE)/RPMS/*/privoxy-$(RPM_VERSION)-$(RPM_PACKAGEV).*.rpm
+       @$(ECHO) -------------------------------------------------------
+       @$(ECHO) Now goto
+       @$(ECHO) http://sourceforge.net/project/admin/editpackages.php?group_id=11118
+       @$(ECHO) ... and release the files.
+       @$(ECHO) -------------------------------------------------------
+     # w3m http://sourceforge.net/project/admin/editpackages.php?group_id=11118
+
+#############################################################################
+# suse distribution. works fine. no need to be root. 
+#############################################################################
+suse-dist: rpm-stuff
+#      TMPFILE=$$(mktemp -q /tmp/$(PROGRAM).XXXXXX); \
+#      if $(SED) -e 's/^\(Version:\).*/\1 $(RPM_VERSION)/g' \
+#              -e 's/^\(Release:\).*/\1 $(RPM_PACKAGEV)/g' \
+#               privoxy-suse.spec > $$TMPFILE ; then \
+#      $(MV) -f $$TMPFILE privoxy-suse.spec; \
+#      else \
+#              $(ECHO) "Could not set version info in specfile."; \
+#      exit 1;\
+#      fi
+
+       $(TAR) --exclude ".cvsignore" --exclude "CVS" --exclude "privoxy-rh.spec" --exclude "privoxy-cl.spec" --exclude "PACKAGERS" -czf $(TAR_ARCH) .
+       $(RPM) --clean -ta  $(TAR_ARCH)
+       if [ -f $(TAR_ARCH) ]; then  $(RM) $(TAR_ARCH); fi
+
+# anonymously ncftps the rpms to sourceforge
+suse-upload: check-release
+       ncftpput -u anonymous -p ijbswa-developers@lists.sourceforge.net upload.sourceforge.net /incoming $(RPM_BASE)/SRPMS/privoxy-suse-$(RPM_VERSION)-$(RPM_PACKAGEV).src.rpm
+# better should use `arch` here instead of ix86 to support other platforms too
+       ncftpput -u anonymous -p ijbswa-developers@lists.sourceforge.net upload.sourceforge.net /incoming $(RPM_BASE)/RPMS/*/privoxy-suse-$(RPM_VERSION)-$(RPM_PACKAGEV).*.rpm
+       @$(ECHO) -------------------------------------------------------
+       @$(ECHO) Now goto
+       @$(ECHO) http://sourceforge.net/project/admin/editpackages.php?group_id=11118
+       @$(ECHO) ... and release the files.
+       @$(ECHO) -------------------------------------------------------
+
+# handle with care. use with root.
+suse-clean:
+       $(RPM) -e junkbuster-suse || true
+       $(RM) -r /etc/junkbuster
+       $(RM) -r /etc/rc.d/junkbuster*
+       $(RM) -r /var/run/junkbuster.pid 
+       $(RM) -r /var/log/junkbuster
+       $(RM) /etc/init.d/junkbuster
+       $(RM) /usr/sbin/junkbuster
+       $(RM) /usr/sbin/rcjunkbuster
+       $(RM) /usr/share/man/man1/junkbuster.1.gz
+       $(RPM) -e privoxy-suse || true
+       $(RM) -r /etc/privoxy
+       $(RM) -r /etc/rc.d/privoxy*
+       $(RM) -r /var/run/privoxy.pid 
+       $(RM) -r /var/log/privoxy
+       $(RM) /etc/init.d/privoxy
+       $(RM) /usr/sbin/privoxy
+       $(RM) /usr/sbin/rcprivoxy
+       $(RM) /usr/share/man/man1/privoxy.1.gz
+
+#############################################################################
+# generic distribution
+#############################################################################
+gen-dist: dist-check
+       @$(ECHO) ""
+       @$(ECHO) "You have run autoconf && autoheader && ./configure right?"
+       @$(ECHO) ""
+       $(MAKE) $(PROGRAM)
+       $(STRIP_PROG) $(PROGRAM)
+       $(LN) -s current ../privoxy-$(VERSION)-$(CODE_STATUS)
+# add program
+       (cd .. && $(TAR) -cvhf --exclude "PACKAGERS" privoxy-$(TARGET_OS)-$(VERSION)-$(CODE_STATUS)-src.tar privoxy-$(VERSION)-$(CODE_STATUS)/$(PROGRAM))
+# add config files
+       for foo in $(CONFIG_FILES); do \
+               (cd .. && $(TAR) -uvhf --exclude "PACKAGERS" privoxy-$(TARGET_OS)-$(VERSION)-$(CODE_STATUS)-src.tar privoxy-$(VERSION)-$(CODE_STATUS)/$$foo;) \
+       done; 
+# add documentation
+       for foo in $(DOC_FILES); do \
+               (cd .. && $(TAR) -uvhf --exclude "PACKAGERS" privoxy-$(TARGET_OS)-$(VERSION)-$(CODE_STATUS)-src.tar privoxy-$(VERSION)-$(CODE_STATUS)/$$foo;) \
+       done;
+# and zip the archive
+       $(RM) ../privoxy-$(VERSION)-$(CODE_STATUS)
+       $(GZIP_PROG) ../privoxy-$(TARGET_OS)-$(VERSION)-$(CODE_STATUS)-src.tar
+       @$(ECHO) Distribution with binary created.
+
+# anonymously ncftps the package to sourceforge
+gen-upload:
+       ncftpput -u anonymous -p ijbswa-developers@lists.sourceforge.net upload.sourceforge.net /incoming ../privoxy-$(TARGET_OS)-$(VERSION)-$(CODE_STATUS)-src.tar.gz
+       @$(ECHO) -------------------------------------------------------
+       @$(ECHO) Now goto
+       @$(ECHO) http://sourceforge.net/project/admin/editpackages.php?group_id=11118
+       @$(ECHO) ... and release the files.
+       @$(ECHO) -------------------------------------------------------
+
+# use with care
+gen-clean:
+       $(RM) privoxy-$(TARGET_OS)-$(VERSION)-$(CODE_STATUS)-src.tar*
+
+#############################################################################
+# solaris distribution. verified on SF machines by swa.
+#############################################################################
+solaris-dist: gen-dist
+       @$(ECHO) Done.
+# anonymously ncftps the package to sourceforge
+solaris-upload: gen-upload
+       @$(ECHO) Done.
+# use with care
+solaris-clean: gen-clean
+       @$(ECHO) Done.
+
+#############################################################################
+# hpux distribution
+#############################################################################
+hpux-dist:
+       @$(ECHO) coming soon. 
+hpux-upload:
+       @$(ECHO) coming soon. 
+
+#############################################################################
+# debian distribution
+#############################################################################
+debian-dist:
+       @$(ECHO) coming soon. 
+debian-upload:
+       @$(ECHO) coming soon. 
+
+#############################################################################
+# macosx distribution
+#############################################################################
+macosx-dist:
+       @$(ECHO) coming soon. 
+macosx-upload:
+       @$(ECHO) coming soon. 
+
+#############################################################################
+# amiga distribution
+#############################################################################
+amiga-dist:
+       @$(ECHO) coming soon. 
+amiga-upload:
+       @$(ECHO) coming soon. 
+
+#############################################################################
+# freebsd distribution. verified on SF machines by swa.
+#############################################################################
+freebsd-dist: gen-dist
+       @$(ECHO) Done.
+# anonymously ncftps the package to sourceforge
+freebsd-upload: gen-upload
+       @$(ECHO) Done.
+# use with care
+freebsd-clean: gen-clean
+       @$(ECHO) Done.
+
+#############################################################################
+# Windows distribution
+#############################################################################
+win-dist:
+       $(ECHO) Not implemented.
+
+
+#############################################################################
+# Tarball distribution: No CVS dirs, dotfiles, debian build dir,
+# (FIXME:) only parts of the static / generated docs mix in doc/webserver
+#############################################################################
+
+tarball-dist: dist-check clean clobber
+       $(LN) -s current ../privoxy-$(VERSION)-$(CODE_STATUS)
+
+       for i in `find . -type f -a -not \( -path "*/CVS*" -o -name ".*" \
+       -o -path "*/debian/*" -o -path "*/actions/*" -o -name "*.php" -o -name "PACKAGERS" \)`; do \
+          files="$$files privoxy-$(VERSION)-$(CODE_STATUS)/$$i"; \
+       done &&  \
+       cd .. && $(TAR) -cvhf privoxy-$(VERSION)-$(CODE_STATUS)-src.tar $$files ; \
+
+# and zip the archive
+       $(RM) ../privoxy-$(VERSION)-$(CODE_STATUS) 
+       $(GZIP_PROG) ../privoxy-$(VERSION)-$(CODE_STATUS)-src.tar
+       @$(ECHO) Tarball distribution created.
+
+# anonymously ncftps the tarball to sourceforge
+tarball-upload:
+       ncftpput -u anonymous -p ijbswa-developers@lists.sourceforge.net upload.sourceforge.net /incoming ../privoxy-$(VERSION)-$(CODE_STATUS)-src.tar.gz
+       @$(ECHO) -------------------------------------------------------
+       @$(ECHO) Now goto
+       @$(ECHO) http://sourceforge.net/project/admin/editpackages.php?group_id=11118
+       @$(ECHO) ... and release the files.
+       @$(ECHO) -------------------------------------------------------
+
+tarball-clean:
+       $(RM) ../privoxy-$(VERSION)-$(CODE_STATUS)-src.tar.gz
+
+#############################################################################
+#
+# Documentation
+#
+# converts doc/source/*.sgml into html, text and man pages
+#
+#############################################################################
+
+# developer manual
+dok-devel: 
+       $(RM) doc/webserver/developer-manual/*.html
+       $(RM) -r doc/source/developer-manual
+       mkdir -p doc/text doc/source/developer-manual
+       cd doc/source/developer-manual && $(DB) ../developer-manual.sgml && cd .. && cp developer-manual/*.html ../webserver/developer-manual/
+       cd doc/source && $(DB) -V nochunks developer-manual.sgml > tmp.html && $(WDUMP) tmp.html > ../text/developer-manual.txt && $(RM) -r tmp.html developer-manual
+
+# user manual
+dok-user: 
+       $(RM) doc/webserver/user-manual/*.html
+       $(RM) -r doc/source/user-manual/
+       mkdir -p doc/text doc/source/user-manual
+       cd doc/source/user-manual && $(DB) ../user-manual.sgml && cd .. && cp user-manual/*.html ../webserver/user-manual/
+       cd doc/source && $(DB) -V nochunks user-manual.sgml > tmp.html && $(WDUMP) tmp.html > ../text/user-manual.txt && $(RM) -r tmp.html user-manual
+
+# faq
+dok-faq: 
+       $(RM) doc/webserver/faq/*.html
+       $(RM) -r doc/source/faq
+       mkdir -p doc/text doc/source/faq
+       cd doc/source/faq && $(DB) ../faq.sgml && cd .. && cp faq/*.html ../webserver/faq/
+       cd doc/source && $(DB) -V nochunks faq.sgml > tmp.html && $(WDUMP) tmp.html > ../text/faq.txt && $(RM) -r tmp.html faq
+
+# man page
+dok-man: 
+       $(RM) doc/man/* doc/webserver/man-page/*.html
+ifneq ($(MAN2HTML),false)
+       $(ECHO) "<html><head><title>Privoxy Man page</title><link rel=\"stylesheet\" type=\"text/css\" href=\"../p_web.css\"></head><body><H2>NAME</H2>" > doc/webserver/man-page/privoxy-man-page.html
+       man ./privoxy.1 | $(MAN2HTML) -bare >> doc/webserver/man-page/privoxy-man-page.html
+       $(ECHO) "</body></html>" >> doc/webserver/man-page/privoxy-man-page.html
+else
+       $(MAKE) groff2html
+endif
+
+# readme page
+dok-readme:
+       cd doc/source && $(DB) -V nochunks readme.sgml > tmp.html &&\
+       $(WDUMP) tmp.html > ../../README && $(RM) -r tmp.html
+
+# webserver files
+dok-webserver: 
+       cd doc/source/webserver && $(DB)-notoc -V nochunks index.sgml > ../../webserver/index.html
+       $(PERL) -pi.bak -e 's/..\/p_doc.css/p_doc.css/;\
+     s/<\/HEAD/\n<meta name=\"description\" content=\"Privoxy helps consumers reduce unwanted junk email and protect their privacy from direct marketing companies.\"><\/HEAD/;\
+       s/<\/HEAD/\n<meta name="MSSmartTagsPreventParsing" content="TRUE"><\/HEAD/;\
+       s/\.\d\. //'\
+     doc/webserver/index.html && $(RM) doc/source/webserver/*.bak
+
+# Main documentation target.
+dok: dok-release dok-devel dok-user dok-faq dok-readme dok-webserver dok-authors
+       @$(ECHO) Documentation created.
+
+#
+# an alternative to the above dok. disabled man page creation for the moment
+#
+redhat-dok: dok-release dok-devel dok-user dok-faq redhat-readme dok-webserver dok-authors
+       @$(ECHO) Documentation created.
+
+# For those with man2html ala RH7's.
+man2html:
+       mkdir -p doc/webserver/man-page
+ifneq ($(MAN2HTML),false)
+       $(MAN2HTML) privoxy.1 |grep -v "^Content-type" > tmp.html
+       $(PERL) -pi.bak -e 's/<A .*Contents<\/A>//; s/<A .*man2html<\/A>/man2html/' tmp.html
+       $(PERL) -pi.bak -e 's/(<\/HEAD>)/<LINK REL=\"STYLESHEET\" TYPE=\"text\/css\" HREF=\"..\/p_doc.css\"><\/HEAD>/' tmp.html
+# Get rid of spurious \a from conversion. (How to do this with perl?)
+       $(SED) -e 's/\a//g' tmp.html > doc/webserver/man-page/privoxy-man-page.html && $(RM) tmp.*
+else
+       $(MAKE) groff2html
+endif
+
+# Otherwise we get plain groff conversion.
+groff2html:
+       $(G2H_CMD) ./privoxy.1 | $(SED) -e 's@</head>@<link REL="STYLESHEET" TYPE="text/css" HREF="../p_doc.css"></head>@' > doc/webserver/man-page/privoxy-man-page.html
+
+## Make README
+redhat-readme: 
+       cd doc/source && $(DB) -V nochunks readme.sgml > tmp.html && $(WDUMP) \
+         tmp.html > ../../README && $(RM) -r tmp.html
+
+## Make AUTHORS file
+dok-authors: 
+       cd doc/source && $(DB) -V nochunks authors.sgml > tmp.html && $(WDUMP) \
+         tmp.html > ../../AUTHORS && $(RM) tmp.html
+
+# make a man page, and then (lousy) HTML version.
+# Requires docbook2man (short perl script), see comments 
+# in privoxy-man-page.sgml. This target is not invoked from other dok targets.
+# It is built separately due to dependencies on perl scripts.
+man: 
+       mkdir -p doc/source/man
+       cd doc/source/man && docbook2man ../privoxy-man-page.sgml &&\
+       perl -pi.bak -e 's/ <URL:.*>//; s/\[ /\[/g' privoxy.1
+       cd doc/source/man && $(DB) ../privoxy-man-page.sgml &&\
+       mv -f index.html privoxy-man-page.html
+     # This html is not used. See make man2html.
+       mv -f doc/source/man/privoxy.1 privoxy.1
+       $(MAKE) man2html
+
+# Set doc entities for VERSION and CODE_STATUS in sgml docs. Toggle content
+# exceptions accordingly. This needs to go before any doc building (doh).
+dok-release:
+       @$(ECHO) Setting doc version and status to $(VERSION), $(CODE_STATUS)
+       @$(PERL) -pi.bak -e 's/<!entity +p-version.*>/<!entity p-version "$(VERSION)">/;\
+     s/<!entity +p-status.*>/<!entity p-status "$(CODE_STATUS)">/' \
+     doc/source/*sgml doc/source/*/*sgml
+       $(RM) -r doc/source/*bak doc/source/*/*bak
+ifeq ($(CODE_STATUS),stable)
+       @$(ECHO) Setting docs to stable $(VERSION)
+       @$(PERL) -pi.bak -e 's/<!entity +% +p-stable.*>/<!entity % p-stable "INCLUDE">/;\
+     s/<!entity +% +p-not-stable.*>/<!entity % p-not-stable "IGNORE">/' \
+     doc/source/*sgml doc/source/*/*sgml
+       $(RM) -r doc/source/*bak doc/source/*/*bak
+else
+       @$(ECHO) Setting docs to not stable $(VERSION)
+       @$(PERL) -pi.bak -e 's/<!entity +% +p-stable.*>/<!entity % p-stable "IGNORE">/;\
+     s/<!entity +% +p-not-stable.*>/<!entity % p-not-stable "INCLUDE">/' \
+     doc/source/*sgml doc/source/*/*sgml
+       $(RM) -r doc/source/*bak doc/source/*/*bak
+endif
+
+dok-pdf: dok-release 
+       $(RM) doc/pdf/*.pdf
+       cp -f doc/source/*.sgml doc/pdf
+       cp -f doc/source/*.dsl doc/pdf
+       cd doc/pdf && db2pdf --pdf -s ldp.dsl user-manual.sgml && mv user-manual.pdf privoxy-user-manual.pdf > /dev/null 2>&1
+       cd doc/pdf && db2pdf --pdf -s ldp.dsl developer-manual.sgml && mv developer-manual.pdf privoxy-developer-manual.pdf > /dev/null 2>&1
+       cd doc/pdf && db2pdf --pdf -s ldp.dsl faq.sgml && mv faq.pdf privoxy-faq.pdf > /dev/null 2>&1
+       $(RM) doc/pdf/*.sgml doc/pdf/*.dsl doc/pdf/*.out doc/pdf/*.tex doc/pdf/*.log doc/pdf/*.aux
+
+# the layout and style with db2pdf sucks, here is an alternative
+dok-pdf2: dok-release 
+       mkdir -p doc/source/temp # this directory not in cvs
+       cd doc/source && $(DB) -V nochunks user-manual.sgml > temp/privoxy-user-manual.html
+       cd doc/source && $(DB) -V nochunks developer-manual.sgml > temp/privoxy-developer-manual.html
+       cd doc/source && $(DB) -V nochunks faq.sgml > temp/privoxy-faq.html
+# one could use html2ps and ps2pdf. well, that does not work. htmlps produces incorrect output.
+
+# Create release announcement in text and html, with short and long versions.
+# This is a standalone target, and must be invoked directly.
+announce: dok-release
+       mkdir -p $(DOC_TMP)
+       cd $(DOC_TMP) && cp -f ../announce.sgml . && $(DB) -iannounce-big announce.sgml &&\
+       mv -f index.html announce.html && $(WDUMP) announce.html > announce.txt
+       cd $(DOC_TMP) && $(DB) announce.sgml &&\
+       mv -f index.html announce-mini.html && $(WDUMP) announce-mini.html > announce-mini.txt &&\
+       mv -f *html *txt ../../.. 
+       rm -fr $(DOC_TMP)
+
+#############################################################################
+#
+# Webserver
+#
+# moves dokumentation to webserver
+#
+#############################################################################
+webserver: tidy
+       @$(ECHO) -------------------------------------------------------
+       @$(ECHO) You have run make dok/redhat-dok before, right?
+       @$(ECHO) Note that this command scps all stuff to the webserver,
+       @$(ECHO) it will not remove obsolete documents.
+       @$(ECHO) -------------------------------------------------------
+
+       @$(ECHO) Uploading 
+       @cd doc/webserver; \
+          upload=`find . -type f -a -not \( -path "*/CVS*" -o -path "*/results*" \)`; \
+          $(TAR) c $$upload | ssh ijbswa.sourceforge.net 'cd /home/groups/i/ij/ijbswa/htdocs/; tar xvm 2>&1 | grep -v timestamp'
+
+       @$(ECHO) Fixing permissions
+       @ssh ijbswa.sourceforge.net 'chmod -R 775 /home/groups/i/ij/ijbswa/htdocs 2>/dev/null; true'
+       @ssh ijbswa.sourceforge.net 'find /home/groups/i/ij/ijbswa/htdocs/ -type f | xargs chmod 664 2>/dev/null; true'
+       @ssh ijbswa.sourceforge.net 'chmod 666 /home/groups/i/ij/ijbswa/htdocs/actions/results/actions-feedback.txt 2>/dev/null; true'
+
+
+web-actions: tidy
+       @$(ECHO) Uploading 
+       @cd doc/webserver/actions; \
+          upload=`find . -type f -a -not \( -path "*/CVS*" -o -path "*/results*" \)`; \
+          $(TAR) c $$upload | ssh ijbswa.sourceforge.net 'cd /home/groups/i/ij/ijbswa/htdocs/actions; tar xvm'
+
+       @$(ECHO) Fixing permissions
+       @ssh ijbswa.sourceforge.net 'find /home/groups/i/ij/ijbswa/htdocs/actions/ -type f | xargs chmod 664 2>/dev/null'
+       @ssh ijbswa.sourceforge.net 'chmod 666 /home/groups/i/ij/ijbswa/htdocs/actions/results/actions-feedback.txt 2>/dev/null'
+
+#############################################################################
+# Source file dependencies
+#############################################################################
+
+actions.@OBJEXT@:   actions.c   actions.h   config.h $(PROJECT_H_DEPS) errlog.h jcc.h list.h loaders.h miscutil.h actionlist.h
+cgi.@OBJEXT@:       cgi.c       cgi.h       config.h $(PROJECT_H_DEPS) cgiedit.h cgisimple.h list.h pcrs.h encode.h ssplit.h jcc.h filters.h actions.h errlog.h miscutil.h
+cgiedit.@OBJEXT@:   cgiedit.c   cgiedit.h   config.h $(PROJECT_H_DEPS) cgi.h list.h pcrs.h encode.h ssplit.h jcc.h filters.h actions.h errlog.h miscutil.h
+cgisimple.@OBJEXT@: cgisimple.c cgisimple.h config.h $(PROJECT_H_DEPS) cgi.h list.h pcrs.h encode.h ssplit.h jcc.h filters.h actions.h errlog.h miscutil.h
+deanimate.@OBJEXT@: deanimate.c deanimate.h config.h $(PROJECT_H_DEPS)
+encode.@OBJEXT@:    encode.c    encode.h    config.h
+errlog.@OBJEXT@:    errlog.c    errlog.h    config.h $(PROJECT_H_DEPS) @WIN_ONLY@w32log.h
+filters.@OBJEXT@:   filters.c   filters.h   config.h $(PROJECT_H_DEPS) errlog.h encode.h gateway.h jbsockets.h jcc.h loadcfg.h parsers.h ssplit.h cgi.h deanimate.h @WIN_ONLY@win32.h 
+gateway.@OBJEXT@:   gateway.c   gateway.h   config.h $(PROJECT_H_DEPS) errlog.h jbsockets.h jcc.h loadcfg.h
+jbsockets.@OBJEXT@: jbsockets.c jbsockets.h config.h $(PROJECT_H_DEPS) filters.h
+jcc.@OBJEXT@:       jcc.c       jcc.h       config.h $(PROJECT_H_DEPS) errlog.h filters.h gateway.h jbsockets.h killpopup.h loadcfg.h loaders.h miscutil.h parsers.h @WIN_ONLY@w32log.h win32.h cgi.h
+killpopup.@OBJEXT@: killpopup.c killpopup.h config.h $(PROJECT_H_DEPS) jcc.h loadcfg.h
+list.@OBJEXT@:      list.c      list.h      config.h $(PROJECT_H_DEPS) list.h miscutil.h
+loadcfg.@OBJEXT@:   loadcfg.c   loadcfg.h   config.h $(PROJECT_H_DEPS) errlog.h filters.h gateway.h jbsockets.h jcc.h killpopup.h loaders.h miscutil.h parsers.h @WIN_ONLY@w32log.h win32.h
+loaders.@OBJEXT@:   loaders.c   loaders.h   config.h $(PROJECT_H_DEPS) errlog.h encode.h filters.h gateway.h jcc.h loadcfg.h miscutil.h parsers.h ssplit.h
+miscutil.@OBJEXT@:  miscutil.c  miscutil.h  config.h
+parsers.@OBJEXT@:   parsers.c   parsers.h   config.h $(PROJECT_H_DEPS) errlog.h encode.h filters.h jbsockets.h jcc.h loadcfg.h loaders.h miscutil.h ssplit.h
+ssplit.@OBJEXT@:    ssplit.c    ssplit.h    config.h miscutil.h
+urlmatch.@OBJEXT@:  urlmatch.c  urlmatch.h  config.h $(PROJECT_H_DEPS) errlog.h miscutil.h ssplit.h
+
+# GNU regex
+gnu_regex.@OBJEXT@: gnu_regex.c gnu_regex.h config.h
+
+# PCRS
+pcrs.@OBJEXT@: pcrs.c pcre/pcre.h pcrs.h
+
+# PCRE
+pcre/get.@OBJEXT@:        pcre/get.c        pcre/config.h pcre/internal.h pcre/pcre.h
+pcre/maketables.@OBJEXT@: pcre/maketables.c pcre/config.h pcre/internal.h pcre/pcre.h
+pcre/pcre.@OBJEXT@:       pcre/pcre.c       pcre/config.h pcre/internal.h pcre/pcre.h pcre/chartables.c 
+pcre/pcreposix.@OBJEXT@:  pcre/pcreposix.c  pcre/config.h pcre/internal.h pcre/pcre.h pcre/pcreposix.h
+pcre/study.@OBJEXT@:      pcre/study.c      pcre/config.h pcre/internal.h pcre/pcre.h
+
+# An auxiliary program makes the PCRE default character table source
+
+pcre/chartables.c:   pcre/dftables@EXEEXT@
+               pcre/dftables@EXEEXT@ >pcre/chartables.c
+
+pcre/dftables@EXEEXT@:       pcre/dftables.c pcre/maketables.c pcre/pcre.h pcre/internal.h pcre/config.h
+               $(CC) -o pcre/dftables@EXEEXT@ $(CFLAGS) pcre/dftables.c
+
+# Win32
+w32log.@OBJEXT@: w32log.c errlog.h config.h jcc.h loadcfg.h miscutil.h pcre/pcre.h pcre/pcreposix.h pcrs.h project.h w32log.h w32taskbar.h win32.h
+w32taskbar.@OBJEXT@: w32taskbar.c config.h w32log.h w32taskbar.h
+win32.@OBJEXT@: win32.c config.h jcc.h loadcfg.h pcre/pcre.h pcre/pcreposix.h pcrs.h project.h w32log.h win32.h
+
+w32.res: w32.rc w32res.h icons/ico00001.ico icons/ico00002.ico icons/ico00003.ico icons/ico00004.ico icons/ico00005.ico icons/ico00006.ico icons/ico00007.ico icons/ico00008.ico icons/idle.ico icons/privoxy.ico config.h
+       windres -D__MINGW32__=0.2 -O coff -i $< -o $@
+
+# AmigaOS
+@AMIGAOS_ONLY@OBJS += amiga.o
+@AMIGAOS_ONLY@CFLAGS += -D__AMIGAVERSION__=\"$(VERSION_MAJOR).$(VERSION_MINOR)$(VERSION_POINT)\" -D__AMIGADATE__=\"`date +%d.%m.%Y`\" -W -m68020 -noixemul -fbaserel -msmall-code
+@AMIGAOS_ONLY@LDFLAGS += -m68020 -noixemul -fbaserel
+@AMIGAOS_ONLY@LIBS = -lm /gg/lib/libb/libm020/libnix/swapstack.o
+@AMIGAOS_ONLY@amiga.o: amiga.c amiga.h config.h
+
+
+$(PROGRAM): $(OBJS) $(W32_FILES)
+       $(LD) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS)
+
+clean:
+       $(RM) a.out $(OBJS) $(W32_FILES) $(W32_INIS) $(PROGRAM) `find . -name TAGS -o -name tags` 
+
+tidy:
+       $(RM) `find . -name "*~"`
+#      $(RM) `find . -name "#*#"` # what is this for??
+       $(RM) `find . -name ".\#*"`
+
+clobber: tidy
+       $(RM) GNUmakefile configure config.h.in config.h config.cache config.status config.log logfile \
+              privoxy.log core *.tar.gz *.tar privoxy-cl.spec doc/source/ldp.dsl
+
+#
+# FIXME: What is all this? 
+#
+       $(RM) cscope.*  *.pdb *.lib *.exp 
+
+distclean: clobber
+
+tags: $(SRCS) $(HDRS)
+       etags $(SRCS) $(HDRS)
+
+install: all
+       #
+       # FIXME: This is a dirty hack to have an install target
+       #        that works at least for some setups. This needs
+       #        to be fixed!
+       #
+       $(STRIP_PROG) $(PROGRAM)
+       $(INSTALL) $(INSTALL_D) $(SBIN_DEST)
+       $(INSTALL) $(INSTALL_D) $(DEST)/user-manual
+       $(INSTALL) $(INSTALL_D) $(CONFDEST)/templates
+       $(INSTALL) $(INSTALL_D) $(DEST)/$(DOK_WEB_USEM)
+       $(INSTALL) $(INSTALL_P) $(PROGRAM) $(SBIN_DEST)
+       if [ -d "$(DOK_WEB_USEM)" ]; then $(INSTALL) $(INSTALL_T) $(DOK_WEB_USEM)/[a-z]* $(DEST)/$(DOK_WEB_USEM); fi
+       $(INSTALL) $(INSTALL_T) templates/[a-z]* $(CONFDEST)/templates
+       $(INSTALL) $(INSTALL_T) config default.action default.filter trust $(CONFDEST)
+       # FIXME $(ECHO) privoxy.logrotate privoxy.monthly privoxy.weekly
+       # FIXME: Need new manual! $(GZIP_PROG) -c privoxy.1 > $(MAN_DEST)/privoxy.1.gz
+       $(INSTALL) $(INSTALL_P) privoxy.init /etc/init.d/privoxy
+
+coffee:
+        @perl -e 'print pack "C*", (31,139,8,8,153,63,226,60,2,3,99,111,102,102,101,101,0,109,143,205,13,192,32,8,133,\
+                  239,78,241,110,234,1,28,160,171,152,208,53,26,117,247,22,165,73,137,125,9,1,62,126,2,128,169,5,243,143,\
+                  13,139,49,164,65,100,149,152,102,73,141,88,73,178,116,205,100,69,253,36,102,81,49,83,236,19,225,171,131,\
+                  214,172,163,73,4,168,123,115,71,126,247,122,94,128,178,227,95,154,12,86,215,122,197,249,146,187,54,220,125,\
+                  193,51,228,11,1,0,0);'|zcat
+
+#############################################################################
+
+## Local Variables:
+## tab-width: 3
+## end:
+
+# $Log: GNUmakefile.in,v $
+# Revision 1.103  2002/05/23 23:19:00  oes
+# Use dsl without TOC for the homepage
+#
+# Revision 1.102  2002/05/16 01:20:17  hal9
+# make announce target added.
+#
+# Revision 1.101  2002/05/15 12:28:46  oes
+# Trying to keep Hal happy :)
+#
+# Revision 1.100  2002/05/08 13:48:18  hal9
+# Ooops, that trashed JB v2.0.2 comment. Fixed.
+#
+# Revision 1.99  2002/05/08 13:42:07  hal9
+# This fixes the numbering problem on index.html in contact info section (.1.). Using
+# perl, since its way too convoluted to try to fix proper with docbook.
+#
+# Revision 1.98  2002/05/03 14:33:06  oes
+# Replaced ldp(OK).dsl handling with generation via autoconf; handle all file exeptions to src tarball via find
+#
+# Revision 1.97  2002/04/27 20:27:43  swa
+# no longer needed due to new
+# PACKAGE_VERSION process
+#
+# Revision 1.96  2002/04/27 17:44:32  morcego
+# - Correcting typo in my name (Rodrigo, not Rodgrigo) :-)
+# - Using the RM macro everywhere rm is called (either we use, or don't)
+# - Same for RPM
+#
+# Revision 1.95  2002/04/27 15:37:25  swa
+# replacing directory in document creation process
+# no longer necessary.
+#
+# Revision 1.94  2002/04/27 08:23:29  swa
+# pdf process reviewed and cleaned up
+#
+# Revision 1.93  2002/04/27 04:55:53  morcego
+# privoxy-cl.spec now gets removed by clobber target
+#
+# Revision 1.92  2002/04/27 04:53:40  morcego
+# Adding --exclude "PACKAGERS" to every tar command that applies (not for
+#   webserver target)
+#
+# Revision 1.91  2002/04/27 04:44:51  morcego
+# GNUmakefile.in: The tarball created on redhat-dist and suse-dist now ignore
+#   the PACKAGERS file, as well privoxy-cl.spec (in case it was created)
+# GNUmakefile.in: New targets -> conectiva-spec, conectiva-dist and
+#   conectiva-upload
+# genclspec.sh  : New file to generate, from privoxy-rh.spec, a specfile
+#   for Conectiva Linux
+#
+# Revision 1.90  2002/04/26 17:46:53  swa
+# be consistent
+#
+# Revision 1.89  2002/04/26 17:20:54  swa
+# just produce single html files to proces them later with Destiller or somesuch. looks prettier.
+#
+# Revision 1.88  2002/04/25 19:13:57  morcego
+# Removed RPM release number declaration on configure.in
+# Changed makefile to use given value for RPM_PACKAGEV when on uploading
+# targets (will produce an error, explaining who to do it, if no value
+# if provided).
+#
+# Revision 1.87  2002/04/23 14:10:59  swa
+# now create pdf documents
+#
+# Revision 1.86  2002/04/15 04:30:27  hal9
+# Missed two -pi.bak's on perl/cygwin problem.
+#
+# Revision 1.85  2002/04/14 01:05:34  hal9
+# Revert dok-webserver change for SF logo.
+#
+# Revision 1.84  2002/04/13 22:43:25  hal9
+# -Fix dok-webserver for SF logo (more perl).
+# -Change all perl -pi to perl -pi.bak for Cygwin problem.
+#
+# Revision 1.83  2002/04/12 09:39:25  oes
+# Excluding yet more files from tarball; making dist warning yet more scary
+#
+# Revision 1.82  2002/04/11 21:07:11  oes
+# Excluding more files from tarball build
+#
+# Revision 1.81  2002/04/11 14:40:27  oes
+# Fixed typo -- Thanks, Moritz!
+#
+# Revision 1.80  2002/04/11 12:50:00  oes
+# Fixed tarball-dist target
+#
+# Revision 1.79  2002/04/11 06:49:28  oes
+# webserver target: silenced timestamp warnings resulting from uploading westwards, made permissions fixing independant of screwed local dir permissions, suppress (false alarm) make error if not owner of feedback log
+#
+# Revision 1.78  2002/04/09 13:37:11  sarantis
+# fix tar options typo
+#
+# Revision 1.77  2002/04/09 13:28:53  swa
+# build suse and gen-dist with html docs
+#
+# Revision 1.76  2002/04/08 22:43:41  oes
+# Fix: Include dotfiles in fixing webserver permissions
+#
+# Revision 1.75  2002/04/08 22:14:59  oes
+# Silencing tar warnings in the web* targets
+#
+# Revision 1.74  2002/04/08 15:22:44  hal9
+# This has finishing touches for dok building. Should be ready to go.
+# -The main doc build is now 'make dok', should work on Redhat too.
+# -Removed man page from main doc build. It is built separately due to
+#  perl scripts that most aren't likely to have.
+#
+# Revision 1.73  2002/04/08 14:03:24  oes
+# oes for al: Fix install target
+#
+# Revision 1.72  2002/04/08 13:42:11  oes
+# Added safety check to *-dist targets; fixed permissions for feedback logfile
+#
+# Revision 1.71  2002/04/07 20:32:03  hal9
+# -Add meta data kludge for make dok-webserver via $(PERL).
+# -Add subdirs for 'make dok-release'.
+#
+# Revision 1.70  2002/04/07 08:59:40  swa
+# generated files. do NOT edit.
+# fixed directory bug in makefile.
+#
+# Revision 1.69  2002/04/07 08:10:47  swa
+# create some of the webserver docs
+# automatically (in particular if
+# those docs recycle other documentation
+# fragments). Now committed webserver's
+# index file.
+#
+# Revision 1.68  2002/04/07 07:58:11  swa
+# create some of the webserver docs
+# automatically (in particular if
+# those docs recycle other documentation
+# fragments)
+#
+# Revision 1.67  2002/04/07 05:31:42  hal9
+# Add 'dok-release' target:
+# -Set doc entities to VERSION and CODE_STATUS during make.
+# -Set doc conditional content flags (stable vs non-stable).
+# A separate target for the time being but needs to be incorporated into
+# dok build at some point.
+# -Filter out a spurious ^G from new man page > html converion in man2html.
+#
+# Revision 1.66  2002/04/06 20:28:21  jongfoster
+# Prettifying groff2html.
+# Using GNU Make's conditional makefile feature rather than shell "if"s.
+# (The shell "if"s were hiding errors)
+# "perl" -> "$(PERL)"
+# Spaces->tabs in a couple of places.
+#
+# Revision 1.65  2002/04/06 05:16:39  hal9
+# -Add 'authors' and 'man' targets for AUTHORS and man-page (WIP).
+# -Both of these will soon be generated files.
+#
+# Revision 1.64  2002/04/04 22:14:51  oes
+# No longer rely on find honoring -iname
+#
+# Revision 1.63  2002/04/04 21:06:22  swa
+# cosmetics.
+#
+# Revision 1.62  2002/04/04 20:49:50  swa
+# attempt to consolidate the
+# different dokbook versions.
+#
+# Revision 1.61  2002/04/04 19:18:21  swa
+# readme was leftover directory. use w3m instead
+# of lynx to be consistent among developers. use
+# consistent target naming.
+#
+# Revision 1.60  2002/04/04 12:25:41  oes
+# Tidy webserver upload w/o *~ files, CVS dirs and logfiles and with proper dir and file permissions
+#
+# Revision 1.59  2002/04/04 08:32:45  swa
+# wrong name for tarball-dist target. further fixed content of tarball dist
+#
+# Revision 1.58  2002/04/04 06:32:58  hal9
+# New dok targets for make readme.
+#
+# Revision 1.57  2002/04/04 00:36:36  gliptak
+# always use pcre for matching
+#
+# Revision 1.56  2002/04/03 22:28:03  gliptak
+# Removed references to gnu_regex
+#
+# Revision 1.55  2002/04/03 19:54:29  swa
+# freebsd tested to work. attempt to move tarball dist target forward
+#
+# Revision 1.54  2002/04/03 14:54:07  oes
+# Standard clean and clobber semantics II
+#
+# Revision 1.53  2002/04/03 14:19:16  oes
+# Standard clean and clobber semantics
+#
+# Revision 1.52  2002/04/03 02:56:18  hal9
+# Revert previous FAQ numbering kludge.
+#
+# Revision 1.51  2002/04/02 13:03:56  oes
+# Added fix for webserver permissions
+#
+# Revision 1.50  2002/04/02 03:46:24  hal9
+# Rewrite ldpOK.dsl so that sections are NOT numbered on FAQ, in an effort
+# to make the Table of Contents not so 'busy' looking. SuSE needs testing :)
+#
+# Revision 1.49  2002/03/30 22:20:12  swa
+# cd didn't work. neither did find.
+#
+# Revision 1.48  2002/03/30 19:04:06  swa
+# people release differently. no good.
+# I want to make parts of the docs only.
+#
+# Revision 1.47  2002/03/30 09:05:21  swa
+# better packaging. better rpm building.
+# tar failed on sun (no exclude there).
+#
+# Revision 1.46  2002/03/29 20:09:01  swa
+# al's patch
+#
+# Revision 1.45  2002/03/29 19:45:45  swa
+# for lazy swa
+#
+# Revision 1.44  2002/03/29 17:42:44  gliptak
+# Correcting for Solaris tar limitations
+#
+# Revision 1.43  2002/03/29 07:40:03  swa
+# fixed make webserver. doh
+#
+# Revision 1.42  2002/03/29 06:59:04  swa
+# other users could not modify files on webserver
+#
+# Revision 1.41  2002/03/28 20:43:00  swa
+# set make correctly
+#
+# Revision 1.40  2002/03/28 04:22:44  hal9
+# More on man2html stuff.
+#
+# Revision 1.39  2002/03/28 01:04:14  hal9
+# More man2html stuff for docs.
+#
+# Revision 1.38  2002/03/27 16:02:30  swa
+# have a generic target
+#
+# Revision 1.37  2002/03/27 15:30:26  swa
+# have a consistent appearance
+#
+# Revision 1.36  2002/03/27 14:58:08  swa
+# can be used by mutilple targets
+#
+# Revision 1.35  2002/03/27 14:53:19  swa
+# added solaris-dist
+#
+# Revision 1.34  2002/03/27 10:30:11  swa
+# we want a html man file on the webserver
+#
+# Revision 1.33  2002/03/27 03:05:35  hal9
+# Added man2html target for docs (redhat-dok only for now)
+#
+# Revision 1.32  2002/03/26 22:29:54  swa
+# we have a new homepage!
+#
+# Revision 1.31  2002/03/26 14:00:18  swa
+# fixed make tarball, tarball-dist, tarball-clean
+#
+# Revision 1.30  2002/03/25 12:52:25  swa
+# new targets
+#
+# Revision 1.29  2002/03/24 17:03:55  jongfoster
+# Name change
+#
+# Revision 1.28  2002/03/24 16:19:48  swa
+# configure needs to be generated.
+#
+# Revision 1.27  2002/03/24 16:13:57  swa
+# generated files are a nono in cvs
+#
+# Revision 1.26  2002/03/24 15:36:02  swa
+# did not build.
+#
+# Revision 1.25  2002/03/24 14:31:08  swa
+# remove more crappy files. set RPM
+# release version correctly.
+#
+# Revision 1.24  2002/03/24 14:19:55  swa
+# set rpm package release in configure.in. nowhere else.
+#
+# Revision 1.23  2002/03/24 13:06:49  swa
+# suse-clean now runs fine
+#
+# Revision 1.22  2002/03/24 12:56:21  swa
+# name change related issues.
+#
+# Revision 1.21  2002/03/24 12:43:57  swa
+# name change
+#
+# Revision 1.20  2002/03/24 11:39:17  jongfoster
+# Renaming config files
+#
+# Revision 1.19  2002/03/22 20:53:03  morcego
+# - Ongoing process to change name to JunkbusterNG
+# - configure/configure.in: no change needed
+# - GNUmakefile.in:
+#         - TAR_ARCH = /tmp/JunkbusterNG-$(RPM_VERSION).tar.gz
+#         - PROGRAM    = jbng@EXEEXT@
+#         - rh-spec now references as junkbusterng-rh.spec
+#         - redhat-upload: references changed to junkbusterng-* (package names)
+#         - tarball-dist: references changed to JunkbusterNG-distribution-*
+#         - tarball-src: now JunkbusterNG-*
+#         - install: initscript now junkbusterng.init and junkbusterng (when
+#                    installed)
+# - junkbuster-rh.spec: renamed to junkbusterng-rh.spec
+# - junkbusterng.spec:
+#         - References to the expression ijb where changed where possible
+#         - New package name: junkbusterng (all in lower case, acording to
+#           the LSB recomendation)
+#         - Version changed to: 2.9.13
+#         - Release: 1
+#         - Added: junkbuster to obsoletes and conflicts (Not sure this is
+#           right. If it obsoletes, why conflict ? Have to check it later)
+#         - Summary changed: Stefan, please check and aprove it
+#         - Changes description to use the new name
+#         - Sed string was NOT changed. Have to wait to the manpage to
+#           change first
+#         - Keeping the user junkbuster for now. It will require some aditional
+#           changes on the script (scheduled for the next specfile release)
+#         - Added post entry to move the old logfile to the new log directory
+#         - Removing "chkconfig --add" entry (not good to have it automaticaly
+#           added to the startup list).
+#         - Added preun section to stop the service with the old name, as well
+#           as remove it from the startup list
+#         - Removed the chkconfig --del entry from the conditional block on
+#           the preun scriptlet (now handled on the %files section)
+# - junkbuster.init: renamed to junkbusterng.init
+# - junkbusterng.init:
+#         - Changed JB_BIN to jbng
+#         - Created JB_OBIN with the old value of JB_BIN (junkbuster), to
+#           be used where necessary (config dir)
+#
+# Aditional notes:
+# - The config directory is /etc/junkbuster yet. Have to change it on the
+# specfile, after it is changes on the code
+# - The only files that got renamed on the cvs tree were the rh specfile and
+# the init file. Some file references got changes on the makefile and on the
+# rh-spec (as listed above)
+#
+# Revision 1.18  2002/03/21 23:00:00  swa
+# want to autogenerate stuff.
+#
+# Revision 1.17  2002/03/19 19:30:04  morcego
+# - Fixing stylesheet checking on configure. If it is found, no further checks
+#   should be done
+#
+# - configure will now check for db2html or docbook2html (should work now
+#   on SuSe without the docbktls package)
+#
+# Revision 1.16  2002/03/14 22:32:32  hal9
+# Bumped the RPM version.
+#
+# Revision 1.15  2002/03/08 20:00:28  swa
+# some leftovers.
+#
+# Revision 1.14  2002/03/07 18:25:56  swa
+# synced redhat and suse build process
+#
+# Revision 1.13  2002/03/07 17:17:56  oes
+# (Hopefully) fixed for older make versions
+#
+# Revision 1.12  2002/03/07 15:28:27  swa
+# more informative
+#
+# Revision 1.11  2002/03/06 14:33:18  sarantis
+# Use proper temp file, not "abc".
+#
+# Revision 1.10  2002/03/06 14:19:35  sarantis
+# Cleanup PID_FILE_PATH from redhat-dist target
+#
+# Revision 1.9  2002/03/05 17:31:11  morcego
+# Search for docbook.dsl. Should solve portability problems for SuSe.
+#
+# Revision 1.8  2002/03/05 14:07:42  morcego
+# configure now detects rpm topdir, and change GNUmakefile acordingly
+#    (based on sugestion by Sarantis Paskalis)
+#
+# Revision 1.7  2002/03/05 13:43:28  morcego
+# Checking for text browser, so redhat-dok can work.
+#
+# Revision 1.6  2002/03/05 13:10:51  morcego
+# Changes to implement redhat-dok (Hal Burgiss)
+# Changes to make it work on other distros and out-of-the-shelf configurations
+#
+# Revision 1.5  2002/02/27 15:30:39  hal9
+# Reset $(RPM_PACKAGEV) to 1 (was 2)
+#
+# Revision 1.4  2002/01/17 21:44:04  jongfoster
+# Adding urlmatch.[ch]
+#
+# Revision 1.3  2002/01/04 15:26:08  oes
+# Added tarball-src target
+#
+# Revision 1.2  2001/12/30 14:07:31  steudten
+# - Add signal handling (unix)
+# - Add SIGHUP handler (unix)
+# - Add creation of pidfile (unix)
+# - Add action 'top' in rc file (RH)
+# - Add entry 'SIGNALS' to manpage
+# - Add exit message to logfile (unix)
+#
+# Revision 1.1  2001/12/01 11:22:57  jongfoster
+# Renaming Makefile.in to GNUmakefile.in so that non-GNU versions of
+# make break in a more obvious way.
+# Adding .PHONY section.
+#
+# Revision 1.40  2001/12/01 00:24:11  jongfoster
+# Renaming various config files
+# Fixing CR->CRLF under Win32 (I hope)
+#
+# Revision 1.39  2001/11/06 12:07:30  steudten
+# Add --clean for building rpm in target redhat-dist.
+#
+# Revision 1.38  2001/11/05 21:35:23  steudten
+# Complete rewrite for the 'redhat-dist' target.
+# Checks for writeable RPM build directories for calling user.
+# So you must not be root, just set the modes to 1777 to
+# build a RH package.
+# Fix the upload-target to be arch independant.
+# Add target for 'solaris-dist' - coming soon.
+#
+# Revision 1.37  2001/11/01 00:52:04  hal9
+# Redhat-upload stuff per Stefan.
+#
+# Revision 1.36  2001/10/31 19:26:13  swa
+# automate process of uploading new releases
+# to sf.
+#
+# Revision 1.35  2001/10/15 22:14:59  joergs
+# Removed -O2 and -Wall from AmigaOS-only CFLAGS since they are now in
+#  the general CFLAGS already.
+#
+# Revision 1.34  2001/10/15 18:28:06  steudten
+# remove config.cache for target clobber.
+# Cleanup make dist for RH and S.u.S.E.
+#
+# Revision 1.33  2001/10/10 12:43:33  oes
+# Added ugly hack to make install target work at least for some setups.
+#
+# Revision 1.32  2001/10/09 22:38:19  jongfoster
+# Correcting actionsfile filename for Win32 INI build
+#
+# Revision 1.31  2001/09/23 10:13:48  swa
+# upload process established. run make webserver and
+# the documentation is moved to the webserver. documents
+# are now linked correctly.
+#
+# Revision 1.30  2001/09/19 17:55:49  oes
+# Fixed CFLAGS
+#
+# Revision 1.29  2001/09/16 17:34:27  jongfoster
+# Removing showargs.[ch], adding cgi(simple|edit).[ch]
+# Replacing $(OBJEXT) with @OBJEXT@ - this seems to be a common source
+# of build problems.
+#
+# Revision 1.28  2001/09/13 15:19:08  swa
+# we want text files as well.
+#
+# Revision 1.27  2001/09/13 13:11:37  steudten
+#
+# Replace DEBUG_CFLAGS with OTHER_CFLAGS
+#
+# Revision 1.26  2001/09/12 23:44:54  david__schmidt
+# Mac OSX (Darwin) support added.
+#
+# Revision 1.25  2001/09/12 22:55:45  joergs
+# AmigaOS support added.
+#
+# Revision 1.24  2001/09/12 17:28:59  david__schmidt
+#
+# OS/2 port: update autoconf'd support for the platform.
+#
+# Revision 1.23  2001/09/12 16:28:42  swa
+# added "make dok" section to generate html pages from
+# the sgml source documents. note that the we do not want
+# generated stuff in cvs.
+#
+# Revision 1.22  2001/09/10 16:31:23  swa
+# buildroot definition in the specfile fucks up the build
+# process under suse. hence I moved it to the "rpm -ta"
+# command
+#
+# Revision 1.21  2001/09/10 11:12:49  oes
+# Turning on -Wall
+#
+# Revision 1.20  2001/08/02 22:04:29  jongfoster
+# Removing some remaining references to obsolete w32rulesdlg.[ch]
+#
+# Revision 1.19  2001/07/30 22:14:03  jongfoster
+# Removing obsolete w32rulesdlg.c and w32rulesdlg.h
+#
+# Revision 1.18  2001/07/29 17:09:17  jongfoster
+# Major changes to build system in order to fix these bugs:
+# - pthreads under Linux was broken - changed -lpthread to -pthread
+# - Compiling in MinGW32 mode under CygWin now correctly detects
+#   which shared libraries are available
+# - Solaris support (?) (Not tested under Solaris yet)
+#
+# Revision 1.17  2001/07/28 16:44:54  oes
+# Fixed sed LF->CRLF conversion and removed deprecated files
+#
+# Revision 1.16  2001/07/15 19:45:33  jongfoster
+# Added support for linking with POSIX threads library
+#
+# Revision 1.15  2001/07/13 13:48:07  oes
+#  - Moved STATIC #define for pcre to (ac)config.h
+#  - Made -Ipcre depandant on static pcre compilation to
+#    avoid version conflicts
+#  - Included compilation and depandancies for new deanimate.c
+#  - Made changes to the pcre/pcreposix/pcrs build process
+#    as required by the new library autodetection in
+#    configure.in
+#
+# Revision 1.14  2001/07/01 16:27:44  oes
+# Fixed misplaced dependancy
+#
+# Revision 1.13  2001/06/29 13:18:36  oes
+# - added depandancy of filters.o on cgi.h
+#
+# Revision 1.12  2001/06/12 17:15:56  swa
+# fixes, because a clean build on rh6.1 was impossible.
+# GZIP confuses make, %configure confuses rpm, etc.
+#
+# Revision 1.11  2001/06/11 11:26:35  sarantis
+# RPM version should be the same as ijbswa version.  The rpm release is
+# specified in the specfile.
+#
+# Revision 1.10  2001/06/07 17:27:45  swa
+# added suse build section
+#
+# Revision 1.9  2001/06/04 18:31:58  swa
+# files are now prefixed with either `confdir' or `logdir'.
+# `make redhat-dist' replaces both entries confdir and logdir
+# with redhat values
+#
+# Revision 1.8  2001/06/04 10:44:57  swa
+# `make redhatr-dist' now works. Except for the paths
+# in the config file.
+#
+# Revision 1.7  2001/06/03 17:09:09  swa
+# swa for oes: reversed my earlier change
+#
+# Revision 1.6  2001/06/03 17:07:27  swa
+# swa for oes
+#
+# Revision 1.5  2001/06/03 13:57:26  swa
+# compile cgi.c (for andreas' GUI)
+#
+# Revision 1.4  2001/05/31 21:18:45  jongfoster
+# Added files actions.[ch], actionlist.h, list.[ch] to Makefile
+#
+# Revision 1.3  2001/05/29 20:02:48  joergs
+# Changes for AmigaOS added.
+#
+# Revision 1.2  2001/05/17 22:23:23  oes
+#  - Added auto-generation of CRLFs for Win32 config files
+#  - Added comment-prefix to all Win32-only options in the config file
+#    and provided auto stripping of this prefix for the Win32 platform by make
+#
+# Revision 1.1.1.1  2001/05/15 13:59:00  oes
+# Initial import of version 2.9.3 source tree
+#
+#
diff --git a/Junkbuster Status.URL b/Junkbuster Status.URL
deleted file mode 100644 (file)
index 6c95de6..0000000
Binary files a/Junkbuster Status.URL and /dev/null differ
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..09aa295
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,346 @@
+   Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>, 
+   and licensed under the GNU General Public License.
+
+
+              GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..5529111
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,70 @@
+# $Id: Makefile,v 1.4 2002/04/09 16:38:10 oes Exp $
+#
+# Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Based on the Internet Junkbuster originally written
+# by and Copyright (C) 1997 Anonymous Coders and 
+# Junkbusters Corporation.  http://www.junkbusters.com
+#
+# This program is free software; you can redistribute it 
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.  See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file.  If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# $Log: Makefile,v $
+# Revision 1.4  2002/04/09 16:38:10  oes
+# Added option to run the whole build process
+#
+# Revision 1.3  2002/03/26 22:29:54  swa
+# we have a new homepage!
+#
+# Revision 1.2  2002/03/24 13:25:42  swa
+# name change related issues
+#
+# Revision 1.1  2001/12/01 11:24:29  jongfoster
+# Will display a warning if non-GNU make is used
+#
+#
+
+#############################################################################
+
+error:
+       @if [ -f GNUmakefile ]; then \
+           echo "***"; \
+           echo "*** You are not using the GNU version of Make - maybe it's called gmake"; \
+           echo "*** or it's in a different directory?"; \
+           echo "***"; \
+           exit 1; \
+        else \
+           echo "***"; \
+           echo "*** To build this program, you must run"; \
+           echo "*** autoheader && autoconf && ./configure and then run GNU make."; \
+           echo "***"; \
+           echo -n "*** Shall I do this for you now? (y/n) "; \
+           read answer; \
+           if [ $$answer = "y" ]; then \
+              autoheader && autoconf && ./configure && make;\
+           fi; \
+        fi
+
+.PHONY: error
+
+#############################################################################
+
+## Local Variables:
+## tab-width: 3
+## end:
diff --git a/Makefile.in b/Makefile.in
deleted file mode 100644 (file)
index 8c670b8..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-# Note:  Makefile is built automatically from Makefile.in
-#
-# $Id: Makefile.in,v 1.2 2001/05/13 22:04:51 administrator Exp $
-#
-# Written by and Copyright (C) 2001 the SourceForge
-# IJBSWA team.  http://ijbswa.sourceforge.net
-#
-# Based on the Internet Junkbuster originally written
-# by and Copyright (C) 1997 Anonymous Coders and 
-# Junkbusters Corporation.  http://www.junkbusters.com
-#
-# This program is free software; you can redistribute it 
-# and/or modify it under the terms of the GNU General
-# Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# This program is distributed in the hope that it will
-# be useful, but WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.  See the GNU General Public
-# License for more details.
-#
-# The GNU General Public License should be included with
-# this file.  If not, you can view it at
-# http://www.gnu.org/copyleft/gpl.html
-# or write to the Free Software Foundation, Inc., 59
-# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# $Log: Makefile.in,v $
-#
-
-
-# define version (will be wired into the rpm.)
-VERSION_MAJOR = @VERSION_MAJOR@
-VERSION_MINOR = @VERSION_MINOR@
-VERSION_POINT = @VERSION_POINT@
-VERSION       = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_POINT)
-RPM_VERSION   = $(VERSION)
-
-# The version is currently specified in config.h, which is
-# written by "configure".
-#
-#VERSION_CFLAGS = -DVERSION_MAJOR=$(VERSION_MAJOR) \
-#                 -DVERSION_MINOR=$(VERSION_MINOR) \
-#                 -DVERSION_POINT=$(VERSION_POINT) \
-#                 -DVERSION="$(VERSION)"
-
-# Directories for "make install"
-DEST        = /etc/junkbuster
-SBIN_DEST   = @sbindir@
-MAN_DEST    = @mandir@
-
-# The flag "-mno-win32" can be used by Cygwin to emulate a un?x type install.
-# The flag "-mwindows -mno-cygwin" will cause Cygwin to use MingW32 for Win32 install.
-CYGWIN_FLAGS = @CYGWIN_FLAGS@
-
-# Need to define this in order to link PCRE statically under Win32
-# Also define under UNIX to use system PCRE headers.
-PCRE_WIN_FLAGS = @STATIC_PCRE_ONLY@-DSTATIC
-
-# Either/Or of these next two lines
-#DEBUG_CFLAGS = -g
-DEBUG_CFLAGS  = -O3
-
-# Solaris needs a special define:
-# FIXME: This is always commented out
-SOLARIS_FLAGS = @SOLARIS_ONLY@-D__EXTENSIONS__=1
-
-#  -DSTDC_HEADERS Now in config.h
-# Do we need  -DHAVE_STRING  ???
-CFLAGS = @CFLAGS@ @CPPFLAGS@ \
-         -D__MT__=1 -D__STDC__=1 $(SOLARIS_FLAGS) -DHAVE_STRING $(DEBUG_CFLAGS) \
-         -Ipcre $(CYGWIN_FLAGS) $(PCRE_WIN_FLAGS)
-
-PROGRAM = junkbuster@EXEEXT@
-CC      = gcc
-ECHO    = echo
-GZIP    = gzip
-INSTALL = cp -f
-LD      = gcc
-OBJEXT  = @OBJEXT@
-RM      = rm -f
-STRIP   = strip
-
-C_SRC  = encode.c errlog.c filters.c gateway.c jbsockets.c jcc.c \
-         killpopup.c loadcfg.c loaders.c miscutil.c parsers.c \
-         showargs.c ssplit.c
-         
-C_OBJS = $(C_SRC:.c=.$(OBJEXT))
-C_HDRS = $(C_SRC:.c=.h) project.h
-
-W32_SRC   = @WIN_ONLY@w32log.c w32rulesdlg.c w32taskbar.c win32.c
-W32_FILES = @WIN_ONLY@w32.res
-W32_OBJS  = @WIN_ONLY@$(W32_SRC:.c=.$(OBJEXT)) $(W32_FILES)
-W32_HDRS  = @WIN_ONLY@w32log.h w32res.h w32rulesdlg.h w32taskbar.h
-W32_LIB   = @WIN_ONLY@-lwsock32 -lcomctl32
-W32_INIS  = @WIN_ONLY@junkbstr.txt saclfile.txt sblock.txt scookie.txt  \
-            @WIN_ONLY@sforward.txt simage.txt spopup.txt strust.txt sregexp.txt
-
-PCRS_SRC     = @PCRS_ONLY@pcrs.c
-PCRS_OBJS    = $(PCRS_SRC:.c=.$(OBJEXT))
-PCRS_HDRS    = $(PCRS_SRC:.c=.h)
-
-PCRE_SRC     = @STATIC_PCRE_ONLY@pcre/get.c pcre/maketables.c pcre/study.c pcre/pcre.c
-PCRE_OBJS    = @STATIC_PCRE_ONLY@$(PCRE_SRC:.c=.$(OBJEXT))
-PCRE_HDRS    = @STATIC_PCRE_ONLY@pcre/config.h pcre/chartables.c pcre/internal.h pcre/pcre.h
-PCRE_LIB     = @LIBRARY_PCRE_ONLY@-lpcre
-
-# No REGEX:
-@NO_REGEX_ONLY@REGEX_SRC    =
-# Without PCRE:
-@GNU_REGEX_ONLY@REGEX_SRC    = gnu_regex.c
-# With PCRE:
-@PCRE_REGEX_ONLY@REGEX_SRC    = @STATIC_PCRE_ONLY@pcre/pcreposix.c
-
-REGEX_OBJS   = $(REGEX_SRC:.c=.$(OBJEXT))
-REGEX_HDRS   = $(REGEX_SRC:.c=.h)
-
-# Dependencies introduced by #include "project.h".
-PROJECT_H_DEPS = project.h $(REGEX_HDRS) $(PCRS_HDRS) @STATIC_PCRE_ONLY@pcre/pcre.h
-
-# Only need this on Solaris
-# FIXME: This is always commented out
-SOCKET_LIB   = @SOLARIS_ONLY@-lsocket -lnsl
-
-LIBS         = $(PCRE_LIB) $(W32_LIB) $(SOCKET_LIB)
-
-SRCS         = $(C_SRC)  $(W32_SRC)  $(PCRS_SRC)  $(PCRE_SRC)  $(REGEX_SRC)
-OBJS         = $(C_OBJS) $(W32_OBJS) $(PCRS_OBJS) $(PCRE_OBJS) $(REGEX_OBJS)
-HDRS         = $(C_HDRS) $(W32_HDRS) $(PCRS_HDRS) $(PCRE_OBJS) $(REGEX_HDRS)
-
-
-# -------------------------------------------------------------------------
-# Do not change anything below this line
-# And there should NOT be any targets above this line.
-# -------------------------------------------------------------------------
-LDFLAGS = $(DEBUG_CFLAGS) $(CYGWIN_FLAGS)
-
-
-all: $(PROGRAM)
-
-
-SUFFIX     = .txt:o
-.SUFFIXES  : .txt
-
-%.txt:
-       sed -e 's/$$//' < $< > $@
-
-inifiles: $(W32_INIS)
-
-junkbstr.txt: config
-       sed     -e 's!\(/etc/junkbuster\|.\)/blocklist!sblock.txt!' \
-                       -e 's!\(/etc/junkbuster\|.\)/popup!spopup.txt!' \
-                       -e 's!\(/etc/junkbuster\|.\)/cookiefile!scookie.txt!' \
-                       -e 's!\(/etc/junkbuster\|.\)/forward!sforward.txt!' \
-                       -e 's!\(/etc/junkbuster\|.\)/trust!strust.txt!' \
-                       -e 's!\(/etc/junkbuster\|.\)/aclfile!sacl.txt!' \
-                       -e 's!\(/var/log/junkbuster\|.\)/jarfile!jar.log!' \
-                       -e 's!\(/var/log/junkbuster\|.\)/junkbuster\.log!junkbstr.log!' \
-                       -e 's!\(/etc/junkbuster\|.\)/imagelist!simage.txt!' \
-                       -e 's!\(/etc/junkbuster\|.\)/re_filterfile!sregexp.txt!' \
-                       -e 's!$$!!' \
-       < $< > $@
-
-saclfile.txt: aclfile
-sblock.txt: blocklist
-scookie.txt: cookiefile
-sforward.txt: forward
-simage.txt: imagelist
-spopup.txt: popup
-strust.txt: trust
-sregexp.txt: re_filterfile
-
-
-# -------------------------------------------------------------------------
-#
-# -------------------------------------------------------------------------
-rpm-dist:
-       @make clean
-# verify that i'm root needs to be done
-       cd .. && tar --exclude "ijb/CVS" -cvzf ijb.tar.gz ijb/
-# verify all version strings, FLAGS, etc. in the spec file
-       cat ../../SPECS/junkbuster.spec | sed 's/^Version:.*/Version: $(RPM_VERSION)/g' | sed 's/^Release:.*/Release: $(VERSION_POINT)/g' > /tmp/abc && cp -f /tmp/abc ../../SPECS/junkbuster.spec
-       cd ../../ && rpm -ba SPECS/junkbuster.spec
-       chmod -R a+r ../../RPMS
-       chmod -R a+r ../../SRPMS
-
-# -------------------------------------------------------------------------
-#
-# -------------------------------------------------------------------------
-win-dist:
-       $(ECHO) Not implemented.
-
-# -------------------------------------------------------------------------
-#
-# -------------------------------------------------------------------------
-tarball-dist:
-       @make clean
-       make $(PROGRAM) 
-#      remove all objects and create the tarball with the binary
-       cd .. && $(RM) ijb/a.out ijb/core ijb/*.$(OBJEXT) && tar --exclude "ijb/CVS" -cvzf ../ijb-distribution-$(VERSION).tar.gz ijb/
-       chmod a+r ../../ijb-distribution-$(VERSION).tar.gz
-       @$(ECHO) Tarball with binary created.
-
-# -------------------------------------------------------------------------
-#
-# -------------------------------------------------------------------------
-
-encode.@OBJEXT@:    encode.c    encode.h    config.h
-errlog.@OBJEXT@:    errlog.c    errlog.h    config.h $(PROJECT_H_DEPS) @WIN_ONLY@w32log.h
-filters.@OBJEXT@:   filters.c   filters.h   config.h $(PROJECT_H_DEPS) errlog.h encode.h gateway.h jbsockets.h jcc.h loadcfg.h parsers.h showargs.h ssplit.h @WIN_ONLY@win32.h 
-gateway.@OBJEXT@:   gateway.c   gateway.h   config.h $(PROJECT_H_DEPS) errlog.h jbsockets.h jcc.h loadcfg.h
-jbsockets.@OBJEXT@: jbsockets.c jbsockets.h config.h $(PROJECT_H_DEPS) filters.h
-jcc.@OBJEXT@:       jcc.c       jcc.h       config.h $(PROJECT_H_DEPS) errlog.h filters.h gateway.h jbsockets.h killpopup.h loadcfg.h loaders.h miscutil.h parsers.h showargs.h @WIN_ONLY@w32log.h win32.h
-killpopup.@OBJEXT@: killpopup.c killpopup.h config.h $(PROJECT_H_DEPS) jcc.h loadcfg.h
-loadcfg.@OBJEXT@:   loadcfg.c   loadcfg.h   config.h $(PROJECT_H_DEPS) errlog.h filters.h gateway.h jbsockets.h jcc.h killpopup.h loaders.h miscutil.h parsers.h showargs.h @WIN_ONLY@w32log.h win32.h
-loaders.@OBJEXT@:   loaders.c   loaders.h   config.h $(PROJECT_H_DEPS) errlog.h encode.h filters.h gateway.h jcc.h loadcfg.h miscutil.h parsers.h ssplit.h
-miscutil.@OBJEXT@:  miscutil.c  miscutil.h  config.h
-parsers.@OBJEXT@:   parsers.c   parsers.h   config.h $(PROJECT_H_DEPS) errlog.h encode.h filters.h jbsockets.h jcc.h loadcfg.h loaders.h miscutil.h showargs.h ssplit.h
-showargs.@OBJEXT@:  showargs.c  showargs.h  config.h $(PROJECT_H_DEPS) errlog.h encode.h gateway.h jcc.h loadcfg.h miscutil.h parsers.h
-ssplit.@OBJEXT@:    ssplit.c    ssplit.h    config.h miscutil.h
-
-# GNU regex
-gnu_regex.@OBJEXT@: gnu_regex.c gnu_regex.h config.h
-
-# PCRS
-pcrs.@OBJEXT@: pcrs.c pcre/pcre.h pcrs.h
-
-# PCRE
-pcre/get.@OBJEXT@:        pcre/get.c        pcre/config.h pcre/internal.h pcre/pcre.h
-pcre/maketables.@OBJEXT@: pcre/maketables.c pcre/config.h pcre/internal.h pcre/pcre.h
-pcre/pcre.@OBJEXT@:       pcre/pcre.c       pcre/config.h pcre/internal.h pcre/pcre.h pcre/chartables.c 
-pcre/pcreposix.@OBJEXT@:  pcre/pcreposix.c  pcre/config.h pcre/internal.h pcre/pcre.h pcre/pcreposix.h
-pcre/study.@OBJEXT@:      pcre/study.c      pcre/config.h pcre/internal.h pcre/pcre.h
-
-# An auxiliary program makes the PCRE default character table source
-
-pcre/chartables.c:   pcre/dftables
-               pcre/dftables >pcre/chartables.c
-
-pcre/dftables:       pcre/dftables.c pcre/maketables.c pcre/pcre.h pcre/internal.h pcre/config.h
-               $(CC) -o pcre/dftables $(CFLAGS) pcre/dftables.c
-
-# Win32
-w32log.@OBJEXT@: w32log.c errlog.h config.h jcc.h loadcfg.h miscutil.h pcre/pcre.h pcre/pcreposix.h pcrs.h project.h w32log.h w32rulesdlg.h w32taskbar.h win32.h
-w32rulesdlg.@OBJEXT@: w32rulesdlg.c config.h w32rulesdlg.h win32.h
-w32taskbar.@OBJEXT@: w32taskbar.c config.h w32log.h w32taskbar.h
-win32.@OBJEXT@: win32.c config.h jcc.h loadcfg.h pcre/pcre.h pcre/pcreposix.h pcrs.h project.h w32log.h win32.h
-
-w32.res: w32.rc w32res.h icons/denyrule.ico icons/ico00001.ico icons/ico00002.ico icons/ico00003.ico icons/ico00004.ico icons/ico00005.ico icons/ico00006.ico icons/ico00007.ico icons/ico00008.ico icons/icon1.ico icons/idle.ico icons/junkbust.ico config.h
-       windres -D__MINGW32__=0.2 -O coff -i $< -o $@
-
-
-$(PROGRAM): $(OBJS) $(W32_FILES)
-       $(LD) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS)
-
-clean:
-       $(RM) a.out core $(OBJS) $(W32_FILES) $(W32_INIS)
-
-clobber: clean
-       $(RM) $(PROGRAM) *.pdb *.lib *.exp TAGS junkbuster.log
-
-tags: $(SRCS) $(HDRS)
-       etags $(SRCS) $(HDRS)
-
-install: all
-       $(STRIP) $(PROGRAM)
-       $(INSTALL) $(PROGRAM) $(SBIN_DEST)
-       $(INSTALL) README README.TOO README.WIN README.re_filter README.cygwin $(DEST)
-       $(INSTALL) aclfile blocklist config cookiefile forward imagelist \
-               popup re_filterfile trust $(DEST)
-       # FIXME: On SuSE, these are not found.  Where do they go?
-       $(ECHO) junkbuster.logrotate junkbuster.monthly junkbuster.weekly
-       $(GZIP) -c junkbuster.1 > $(MAN_DEST)/junkbuster.1.gz
-       $(INSTALL) junkbuster.init /sbin/init.d/junkbuster
-
-
-## Local Variables:
-## tab-width: 3
-## end:
diff --git a/PACKAGERS b/PACKAGERS
new file mode 100644 (file)
index 0000000..8f2beac
--- /dev/null
+++ b/PACKAGERS
@@ -0,0 +1,28 @@
+
+       DO NOT INCLUDE THIS FILE IN ANY DISTRO !!!!
+
+       (or users may contact these people directly,
+        which would like to avoid. Users should
+        always use the support forum or user
+        mailinglist).
+
+Responsible persons for releasing packages are ...
+
+Amiga .......: Jörg Strohmayer   <joergs@users.sf.net>         (joergs)
+Conectiva ...: Rodrigo Barbosa   <privoxy@darkover.org>        (morcego)
+Debian ......: Roland Rosenfeld  <roro@users.sf.net>           (roro)
+FreeBSD .....: ? 
+HP-UX .......: Schelstraete Bart <bart1803@users.sf.net>       (bart1803)
+Mac OSX .....: David Schmidt     <david__schmidt@users.sf.net> (david__schmidt)
+NetBSD ......: ? 
+OS/2 ........: David Schmidt     <david__schmidt@users.sf.net> (david__schmidt)
+RedHat ......: Rodrigo Barbosa   <privoxy@darkover.org>        (morcego)
+               Karsten Hopp      <Karsten.Hopp@redhat.de>      (kick_)
+               Hal Burgiss       <hal@foobox.net>              (hal9)
+RedHat 6.x ..: Karsten Hopp      <Karsten.Hopp@redhat.de>      (kick_)
+Solaris .....: Schelstraete Bart <bart1803@users.sf.net>       (bart1803)
+SuSE ........: Stephan Waldherr  <stefan@waldherr.org>         (swa)
+Windows .....: Jon Foster        <jon@jon-foster.co.uk>        (jongfoster)
+               Gábor Lipták      <gliptak@users.sf.net>        (gliptak)
+
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..705c989
--- /dev/null
+++ b/README
@@ -0,0 +1,244 @@
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/doc/source/readme.sgml,v $
+ *
+ * Purpose     :  README file to give a short intro.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *********************************************************************/
+
+This README is included with the development version of Privoxy 2.9.15, which
+will eventually become Privoxy v3.0 (and soon we hope!). See http://
+www.privoxy.org/ for more information. The current code level is beta, and
+seems stable to us :).
+
+-------------------------------------------------------------------------------
+
+Table of Contents
+1. IMPORTANT CHANGES
+2. INSTALL
+3. RUN
+4. CONFIGURATION
+5. DOCUMENTATION
+6. CONTACTING THE DEVELOPERS, BUG REPORTING AND FEATURE REQUESTS
+   
+    6.1. Get Support
+    6.2. Report bugs
+    6.3. Request new features
+    6.4. Report ads or other filter problems
+    6.5. Other
+   
+Privoxy is a web proxy with advanced filtering capabilities for protecting
+privacy, filtering web page content, managing cookies, controlling access, and
+removing ads, banners, pop-ups and other obnoxious Internet junk. Privoxy has a
+very flexible configuration and can be customized to suit individual needs and
+tastes. Privoxy has application for both stand-alone systems and multi-user
+networks.
+
+Privoxy is based on Internet Junkbuster (tm).
+
+-------------------------------------------------------------------------------
+
+1. IMPORTANT CHANGES
+
+NEWS! As of 03/24/02, the name of this project has been changed from ijbswa/
+Junkbuster to Privoxy. This is reflected in many of the included files.
+
+WARNING! If upgrading from earlier versions of this project via RPM packages,
+the new package will delete any previously installed 'Junkbuster' packages.
+
+IMPORTANT! READ! Configuration Change as of 17 Mar 2002: The default listening
+port is now 8118 due to conflicts with port 8000 assignment. You will need to
+change your browser if upgrading!!! And maybe firewall, etc.
+
+-------------------------------------------------------------------------------
+
+2. INSTALL
+
+To build Privoxy from source, autoconf, GNU make (gmake), and, of course, a C
+compiler like gcc are required.
+
+When building from a source tarball (either release version or nightly CVS
+tarball), first unpack the source:
+
+ tar xzvf privoxy-2.9.15-beta-src* [.tgz or .tar.gz]                           
+ cd privoxy-2.9.15-beta                                                        
+
+For retrieving the current CVS sources, you'll need CVS installed. Note that
+sources from CVS are development quality, and may not be stable, or well
+tested. To download CVS source:
+
+  cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login          
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co current 
+  cd current                                                                         
+
+This will create a directory named current/, which will contain the source
+tree.
+
+Then, in either case, to build from unpacked tarball or CVS source:
+
+ autoheader                                                                    
+ autoconf                                                                      
+ ./configure      # (--help to see options)                                    
+ make             # (the make from gnu, gmake for *BSD)                        
+ su                                                                            
+ make -n install  # (to see where all the files will go)                       
+ make install     # (to really install)                                        
+
+If you have gnu make, you can have the first four steps automatically done for
+you by just typing:
+
+  make                                                                         
+
+in the freshly downloaded or unpacked source directory.
+
+For more detailed instructions on how to build Redhat and SuSE RPMs, Windows
+self-extracting installers, building on platforms with special requirements
+etc, please consult the developer manual.
+
+For binary RPM installation, and other platforms, see the user-manual as well.
+
+-------------------------------------------------------------------------------
+
+3. RUN
+
+privoxy [--help] [--version] [--no-daemon] [--pidfile PIDFILE] [--user USER
+[.GROUP]] [config_file]
+
+See the man page or user-manual for a brief explanation of each option.
+
+If no config_file is specified on the command line, Privoxy will look for a
+file named 'config' in the current directory (except Win32 which will look for
+'config.txt'). If no config_file is found, Privoxy will fail to start.
+
+Or for Red Hat: /etc/rc.d/init.d/privoxy start
+
+Or for SuSE: /etc/rc.d/privoxy start
+
+-------------------------------------------------------------------------------
+
+4. CONFIGURATION
+
+See: 'config', 'default.action', 'user.action', and 'default.filter'.
+'user.action' is for personal configuration. These are all well commented. Most
+of the magic is in '*.action' files. 'user.action' should be used for any
+actions customizations. On Unix-like systems, these files are installed in /etc
+/privoxy. On Windows, then wherever the executable itself is installed. There
+are many significant changes and advances since Junkbuster v2.0.x. The
+user-manual has a run down of configuration options, and examples: http://
+www.privoxy.org/user-manual/.
+
+Be sure to set your browser(s) for HTTP/HTTPS Proxy at <IP>:<Port>, or whatever
+you specify in the config file under 'listen-address'. DEFAULT is localhost:
+8118.
+
+The actions list can be configured via the web interface accessed via http://
+p.p/, as well other options.
+
+All configuration files are subject to unannounced changes during the
+development process.
+
+-------------------------------------------------------------------------------
+
+5. DOCUMENTATION
+
+There should be documentation in the 'doc' subdirectory, but it is not
+completed at this point. In particular, see the user-manual there, the faq, and
+those interested in Privoxy development, should look at developer-manual.
+
+The most up to date source of information on the current development version,
+may still be either comments in the source code, or the included configuration
+files. The source and configuration files are all well commented. The main
+configuration files are: 'config', 'default.action', and 'default.filter' in
+the toplevel source directory.
+
+Included documentation may vary according to platform and packager.
+
+-------------------------------------------------------------------------------
+
+6. CONTACTING THE DEVELOPERS, BUG REPORTING AND FEATURE REQUESTS
+
+We value your feedback. However, to provide you with the best support, please
+note the following sections.
+
+-------------------------------------------------------------------------------
+
+6.1. Get Support
+
+To get support, use the Sourceforge Support Forum:
+
+    http://sourceforge.net/tracker/?group_id=11118&atid=211118
+
+-------------------------------------------------------------------------------
+
+6.2. Report bugs
+
+To submit bugs, use the Sourceforge Bug Forum:
+
+    http://sourceforge.net/tracker/?group_id=11118&atid=111118. 
+
+Make sure that the bug has not already been submitted. Please try to verify
+that it is a Privoxy bug, and not a browser or site bug first. If you are using
+your own custom configuration, please try the stock configs to see if the
+problem is a configuration related bug. And if not using the latest development
+snapshot, please try the latest one. Or even better, CVS sources. Please be
+sure to include the Privoxy version, platform, browser, any pertinent log data,
+any other relevant details (please be specific) and, if possible, some way to
+reproduce the bug.
+
+-------------------------------------------------------------------------------
+
+6.3. Request new features
+
+To submit ideas on new features, use the Sourceforge feature request forum:
+
+    http://sourceforge.net/tracker/?atid=361118&group_id=11118&func=browse.
+
+-------------------------------------------------------------------------------
+
+6.4. Report ads or other filter problems
+
+You can also send feedback on websites that Privoxy has problems with. Please
+bookmark the following link: "Privoxy - Submit Filter Feedback". Once you surf
+to a page with problems, use the bookmark to send us feedback. We will look
+into the issue as soon as possible.
+
+New, improved default.action files will occasionally be made available based on
+your feedback. These will be announced on the ijbswa-announce list.
+
+-------------------------------------------------------------------------------
+
+6.5. Other
+
+For any other issues, feel free to use the mailing lists:
+    http://sourceforge.net/mail/?group_id=11118.
+
+Anyone interested in actively participating in development and related
+discussions can also join the appropriate mailing list. Archives are available,
+too. See the page on Sourceforge.
+
index edf5c08..fa6706b 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef _CONFIG_H
-#define _CONFIG_H
+#ifndef CONFIG_H_INCLUDED
+#define CONFIG_H_INCLUDED
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/acconfig.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/acconfig.h,v $
  *
  * Purpose     :  This file should be the first thing included in every
  *                .c file.  (Before even system headers).  It contains 
@@ -11,7 +11,7 @@
  *                getting ludicrously long with feature defines.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: acconfig.h,v $
+ *    Revision 1.26  2002/04/11 11:00:21  oes
+ *    Applied Moritz' fix for socklen_t on Solaris
+ *
+ *    Revision 1.25  2002/04/06 20:38:01  jongfoster
+ *    Renaming VC++ versions of config.h
+ *
+ *    Revision 1.24  2002/04/04 00:36:36  gliptak
+ *    always use pcre for matching
+ *
+ *    Revision 1.23  2002/04/03 22:28:03  gliptak
+ *    Removed references to gnu_regex
+ *
+ *    Revision 1.22  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.21  2002/03/24 14:31:08  swa
+ *    remove more crappy files. set RPM
+ *    release version correctly.
+ *
+ *    Revision 1.20  2002/03/24 13:46:44  swa
+ *    name change related issue.
+ *
+ *    Revision 1.19  2002/03/24 13:25:42  swa
+ *    name change related issues
+ *
+ *    Revision 1.18  2002/03/08 16:40:28  oes
+ *    Added FEATURE_NO_GIFS
+ *
+ *    Revision 1.17  2002/03/04 17:52:44  oes
+ *    Deleted PID_FILE_PATH
+ *
+ *    Revision 1.16  2002/01/10 12:36:18  oes
+ *    Moved HAVE_*_R to acconfig.h, where they belong.
+ *
+ *    Revision 1.15  2001/12/30 14:07:31  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.14  2001/10/23 21:24:09  jongfoster
+ *    Support for FEATURE_CGI_EDIT_ACTIONS
+ *
+ *    Revision 1.13  2001/10/07 15:30:41  oes
+ *    Removed FEATURE_DENY_GZIP
+ *
+ *    Revision 1.12  2001/09/13 19:56:37  jongfoster
+ *    Reverting to revision 1.10 - previous checking was majorly broken.
+ *
+ *    Revision 1.10  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.9  2001/07/29 19:08:52  jongfoster
+ *    Changing _CONFIG_H to CONFIG_H_INCLUDED.
+ *    Also added protection against using a MinGW32 or CygWin version of
+ *    config.h from within MS Visual C++
+ *
+ *    Revision 1.8  2001/07/29 17:09:17  jongfoster
+ *    Major changes to build system in order to fix these bugs:
+ *    - pthreads under Linux was broken - changed -lpthread to -pthread
+ *    - Compiling in MinGW32 mode under CygWin now correctly detects
+ *      which shared libraries are available
+ *    - Solaris support (?) (Not tested under Solaris yet)
+ *
+ *    Revision 1.7  2001/07/25 22:53:59  jongfoster
+ *    Will #error if pthreads is enabled under BeOs
+ *
+ *    Revision 1.6  2001/07/15 17:54:29  jongfoster
+ *    Renaming #define STATIC to STATIC_PCRE
+ *    Adding new #define FEATURE_PTHREAD that will be used to enable
+ *    POSIX threads support.
+ *
+ *    Revision 1.5  2001/07/13 13:48:37  oes
+ *     - (Fix:) Copied CODE_STATUS #define from config.h.in
+ *     - split REGEX #define into REGEX_GNU and REGEX_PCRE
+ *       and removed PCRE.
+ *       (REGEX = REGEX_GNU || REGEX_PCRE per project.h)
+ *     - Moved STATIC (for pcre) here from Makefile.in
+ *     - Introduced STATIC_PCRS #define to allow for dynaimc linking with
+ *       libpcrs
+ *     - Removed PCRS #define, since pcrs is now needed for CGI anyway
+ *
+ *    Revision 1.4  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.3  2001/05/26 01:26:34  jongfoster
+ *    New #define, WIN_GUI_EDIT, enables the (embryonic) Win32 GUI editor.
+ *    This #define cannot be set from ./configure - there's no point, it
+ *    doesn't work yet.  See feature request # 425722
+ *
+ *    Revision 1.2  2001/05/22 17:43:35  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Many minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:45  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 #undef VERSION
 
 /*
- * Regular expression matching for URLs.  (Highly recommended).  If this is 
- * not defined then you can ony use prefix matching.
+ * Status of the code: "alpha", "beta" or "stable".
  */
-#undef REGEX
+#undef CODE_STATUS
 
-/*
- * Allow JunkBuster to be "disabled" so it is just a normal non-blocking
- * non-anonymizing proxy.  This is useful if you're trying to access a
- * blocked or broken site - just change the setting in the config file
- * and send a SIGHUP (UN*X), or use the handy "Disable" menu option (Windows
- * GUI).
+/* 
+ * Should pcre be statically built in instead of linkling with libpcre?
+ * (This is determined by configure depending on the availiability of
+ * libpcre and user preferences). The name is ugly, but pcre needs it.
+ * Don't bother to change this here! Use configure instead.
  */
-#undef TOGGLE
+#undef STATIC_PCRE
 
-/*
- * Enables arbitrary content modification regexps
+/* 
+ * Should pcrs be statically built in instead of linkling with libpcrs?
+ * (This is determined by configure depending on the availiability of
+ * libpcrs and user preferences).
+ * Don't bother to change this here! Use configure instead.
  */
-#undef PCRS
+#undef STATIC_PCRS
 
 /*
- * If a stream is compressed via gzip (Netscape specific I think), then
- * it cannot be modified with Perl regexps.  This forces it to be 
- * uncompressed.
+ * Allows the use of an ACL to control access to the proxy by IP address.
  */
-#undef DENY_GZIP
+#undef FEATURE_ACL
 
 /*
- * Enables statistics function.
+ * Enables the web-based configuration (actionsfile) editor.  If you
+ * have a shared proxy, you might want to turn this off.
  */
-#undef STATISTICS
+#undef FEATURE_CGI_EDIT_ACTIONS
 
 /*
- * Bypass filtering for 1 page only
+ * Allows the use of jar files to capture cookies.
  */
-#undef FORCE_LOAD
+#undef FEATURE_COOKIE_JAR
 
 /*
- * Split the show-proxy-args page into a page for each config file.
+ * Locally redirect remote script-redirect URLs
  */
-#undef SPLIT_PROXY_ARGS
+#undef FEATURE_FAST_REDIRECTS
 
 /*
- * Kills JavaScript popups - window.open, onunload, etc.
+ * Bypass filtering for 1 page only
  */
-#undef KILLPOPUPS
+#undef FEATURE_FORCE_LOAD
 
 /*
- * Support for webDAV - e.g. so Microsoft Outlook can access HotMail e-mail
+ * Allow blocking using images as well as HTML.
+ * If you do not define this then everything is blocked as HTML.
+ *
+ * Note that this is required if you want to use FEATURE_IMAGE_DETECT_MSIE.
  */
-#undef WEBDAV
+#undef FEATURE_IMAGE_BLOCKING
 
 /*
  * Detect image requests automatically for MSIE.  Will fall back to
- * other image-detection methods (i.e. USE_IMAGE_LIST) for other
+ * other image-detection methods (i.e. "+image" permission) for other
  * browsers.
  *
+ * You must also define FEATURE_IMAGE_BLOCKING to use this feature.
+ *
  * It detects the following header pair as an image request:
  *
  * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
  * These limitations are due to IE making inconsistent choices
  * about which "Accept:" header to send.
  */
-#undef DETECT_MSIE_IMAGES
+#undef FEATURE_IMAGE_DETECT_MSIE
 
 /*
- * Use image list to detect images.
- * If you do not define this then everything is treated as HTML.
- *
- * Whatever the setting of this value, DETECT_MSIE_IMAGES will 
- * override it for people using Internet Explorer.
+ * Kills JavaScript popups - window.open, onunload, etc.
  */
-#undef USE_IMAGE_LIST
+#undef FEATURE_KILL_POPUPS
 
 /*
- * Allows the use of ACL files to control access to the proxy by IP address.
+ * Use PNG instead of GIF for built-in images
+ */
+#undef FEATURE_NO_GIFS
+
+/*
+ * Use POSIX threads instead of native threads.
+ */
+#undef FEATURE_PTHREAD
+
+/*
+ * Enables statistics function.
  */
-#undef ACL_FILES
+#undef FEATURE_STATISTICS
+
+/*
+ * Allow Privoxy to be "disabled" so it is just a normal non-blocking
+ * non-anonymizing proxy.  This is useful if you're trying to access a
+ * blocked or broken site - just change the setting in the config file,
+ * or use the handy "Disable" menu option in the Windows GUI.
+ */
+#undef FEATURE_TOGGLE
 
 /*
  * Allows the use of trust files.
  */
-#undef TRUST_FILES
+#undef FEATURE_TRUST
 
 /*
- * Allows the use of jar files to capture cookies.
+ * Defined on Solaris only.  Makes the system libraries thread safe.
  */
-#undef JAR_FILES
+#undef _REENTRANT
 
 /*
- * Use PCRE rather than GNU Regex
+ * Defined on Solaris only.  Without this, many important functions are not
+ * defined in the system headers.
+ */
+#undef __EXTENSIONS__
+
+/*
+ * Defined always.
+ * FIXME: Don't know what it does or why we need it.
+ * (presumably something to do with MultiThreading?)
+ */
+#undef __MT__
+
+/* If the (nonstandard and thread-safe) function gethostbyname_r
+ * is available, select which signature to use
  */
-#undef PCRE
+#undef HAVE_GETHOSTBYNAME_R_6_ARGS
+#undef HAVE_GETHOSTBYNAME_R_5_ARGS
+#undef HAVE_GETHOSTBYNAME_R_3_ARGS
+
+/* If the (nonstandard and thread-safe) function gethostbyaddr_r
+ * is available, select which signature to use
+ */
+#undef HAVE_GETHOSTBYADDR_R_8_ARGS
+#undef HAVE_GETHOSTBYADDR_R_7_ARGS
+#undef HAVE_GETHOSTBYADDR_R_5_ARGS
+
+/* Define if you have gmtime_r and localtime_r with a signature
+ * of (struct time *, struct tm *)
+ */
+#undef HAVE_GMTIME_R
+#undef HAVE_LOCALTIME_R
+
+/* Define to 'int' if <sys/socket.h> doesn't have it. 
+ */
+#undef socklen_t
+
 
 @BOTTOM@
 
-#endif /* _CONFIG_H */
+/*
+ * Defined always.
+ * FIXME: Don't know what it does or why we need it.
+ * (presumably something to do with ANSI Standard C?)
+ */
+#ifndef __STDC__
+#define __STDC__ 1
+#endif /* ndef __STDC__ */
+
+/*
+ * Need to set up this define only for the Pthreads library for
+ * Win32, available from http://sources.redhat.com/pthreads-win32/
+ */
+#if defined(FEATURE_PTHREAD) && defined(_WIN32)
+#define __CLEANUP_C
+#endif /* defined(FEATURE_PTHREAD) && defined(_WIN32) */
+
+/*
+ * BEOS does not currently support POSIX threads.
+ * This *should* be detected by ./configure, but let's be sure.
+ */
+#if defined(FEATURE_PTHREAD) && defined(__BEOS__)
+#error BEOS does not support pthread - please run ./configure again with "--disable-pthread"
+
+#endif /* defined(FEATURE_PTHREAD) && defined(__BEOS__) */
+
+
+/*
+ * It's too easy to accidentally use a Cygwin or MinGW32 version of config.h
+ * under VC++, and it usually gives many wierd error messages.  Let's make
+ * the error messages understandable, by bailing out now.
+ */
+#ifdef _MSC_VER
+#error For MS VC++, please use vc_config_winthreads.h or vc_config_pthreads.h.  You can usually do this by selecting the "Build", "Clean" menu option.
+#endif /* def _MSC_VER */
+
+#endif /* CONFIG_H_INCLUDED */
diff --git a/aclfile b/aclfile
deleted file mode 100644 (file)
index 6a265a8..0000000
--- a/aclfile
+++ /dev/null
@@ -1,102 +0,0 @@
-#  Access Control List for the Internet Junkbuster 2.0
-#
-# Copyright 1997-8 Junkbusters Corp.  For distribution, modification and use
-# under the GNU General Public License. These files come with NO WARRANTY.
-# See http://www.junkbusters.com/ht/en/gpl.html or README file for details.
-#
-# Access controls are included at the request of some ISPs and systems
-# administrators, and are not usually needed by individual users.
-# Please note the warnings in the FAQ that this proxy is not
-# intended to be a substitute for a firewall or to encourage anyone
-# to defer addressing basic security weaknesses.
-# For details see http://www.junkbusters.com/ht/en/ijbman.html#aclfile
-
-# For this file to have any effect, the line beginning "aclfile"
-# must be commented in, with the name of this file following the word "aclfile"
-
-# If no access file is specified, the proxy talks to anyone that connects.
-# If an access file is specified, the proxy talks only to IP addresses
-# permitted somewhere in this file and not denied later in this file.
-#
-# Summary -- if using an ACL:
-#
-#  Client must have permission to receive service
-#  LAST match in ACL file wins
-#  Default behavior is to deny service
-#
-# Syntax for an entry in an Access Control List is:
-#
-# ACTION    SRC_ADDR[/SRC_MASKLEN]    [ DST_ADDR[/DST_MASKLEN] ]
-#
-# where the fields are
-#
-# ACTION      = "permit" | "deny"
-#
-# SRC_ADDR    = client hostname or dotted IP address
-# SRC_MASKLEN = number of bits in the subnet mask for the source
-#
-# DST_ADDR    = server or forwarder hostname or dotted IP address
-# DST_MASKLEN = number of bits in the subnet mask for the target
-#
-# field separator (FS) is whitespace (space or tab)
-#
-# IMPORTANT NOTE
-# ==============
-# If the junkbuster is using a forwarder or a gateway for a particular 
-# destination URL, the DST_ADDRR that is examined is the address of
-# the forwarder or the gateway and NOT the address of the ultimate target.
-# This is necessary because it may be impossible for the local
-# junkbuster to determine the address of the ultimate target
-# (that's often what gateways are used for).
-#
-# Here are a few examples to show how the ACL works:
-
-# localhost is OK --  no DST_ADDR implies that ALL destination addresses are OK
-# permit localhost
-
-# a silly example to illustrate:
-#
-# permit any host on the class-C subnet with junkbusters to go anywhere
-#
-# permit www.junkbusters.com/24
-#
-# except deny one particular IP address from using it at all
-#
-# deny      ident.junkbusters.com
-
-# another example
-#
-# You can specify an explicit network address and subnet mask.
-# Explicit addresses do not have to be resolved to be used.
-#
-# permit 207.153.200.0/24
-
-# a subnet mask of 0 matches anything, so the next line permits everyone.
-#
-# permit 0.0.0.0/0
-
-# Note:  you cannot say
-#
-# permit .org
-#
-# to allow all .org domains; every IP-address listed must resolve fully.
-
-# An ISP may want to provide a junkbuster that is accessible by "the world"
-# and yet restrict use of some of their private content to hosts on its
-# internal network (i.e. its own subscribers).  Say, for instance the
-# ISP owns the Class-B IP address block 123.124.0.0 (a 16 bit netmask).
-# This is how they could do it:
-
-# permit 0.0.0.0/0   0.0.0.0/0   # other clients can go anywhere 
-#                with the following exceptions:
-#
-# deny   0.0.0.0/0   123.124.0.0/16 # block all external requests for
-#                                         sites on the ISP's network
-#
-# permit 0.0.0.0/0   www.my_isp.com # except for the ISP's main web site
-#
-# permit 123.124.0.0/16 0.0.0.0/0   # the ISP's clients can go anywhere
-
-# Note that some hostnames may be listed with multiple IP addresses;
-# the primary value returned by gethostbyname() is used.
-#
diff --git a/actionlist.h b/actionlist.h
new file mode 100644 (file)
index 0000000..34b824b
--- /dev/null
@@ -0,0 +1,170 @@
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/actionlist.h,v $
+ *
+ * Purpose     :  Master list of supported actions.
+ *                Not really a header, since it generates code.
+ *                This is included (3 times!) from actions.c
+ *                Each time, the following macros are defined to
+ *                suitable values beforehand:
+ *                    DEFINE_ACTION_MULTI()
+ *                    DEFINE_ACTION_STRING()
+ *                    DEFINE_ACTION_BOOL()
+ *                    DEFINE_ACTION_ALIAS
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: actionlist.h,v $
+ *    Revision 1.16  2002/04/24 02:15:18  oes
+ *    Renamed actions as discussed, Aliased old action names to new ones.
+ *
+ *    Revision 1.15  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.14  2002/03/24 16:32:08  jongfoster
+ *    Removing logo option
+ *
+ *    Revision 1.13  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.12  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.11  2002/03/12 01:42:49  oes
+ *    Introduced modular filters
+ *
+ *    Revision 1.10  2002/03/08 18:19:14  jongfoster
+ *    Adding +image-blocker{pattern} option to edit interface
+ *
+ *    Revision 1.9  2001/11/22 21:58:41  jongfoster
+ *    Adding action +no-cookies-keep
+ *
+ *    Revision 1.8  2001/10/10 16:42:52  oes
+ *    Fixed a bug, Added +limit-connect string action
+ *
+ *    Revision 1.7  2001/10/07 15:33:59  oes
+ *    Introduced a +no-compression action
+ *    Introduced a +downgrade action
+ *
+ *    Revision 1.6  2001/09/16 15:47:37  jongfoster
+ *    First version of CGI-based edit interface.  This is very much a
+ *    work-in-progress, and you can't actually use it to edit anything
+ *    yet.  You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
+ *    to have any effect.
+ *
+ *    Revision 1.5  2001/07/18 12:27:03  oes
+ *    Changed deanimate-gifs to string action
+ *
+ *    Revision 1.4  2001/07/13 13:52:12  oes
+ *     - Formatting
+ *     - Introduced new action ACTION_DEANIMATE
+ *
+ *    Revision 1.3  2001/06/07 23:03:56  jongfoster
+ *    Added standard comment at top of file.
+ *
+ *
+ *********************************************************************/
+\f
+
+#if !(defined(DEFINE_ACTION_BOOL) && defined(DEFINE_ACTION_MULTI) && defined(DEFINE_ACTION_STRING))
+#error Please define lots of macros before including "actionlist.h".
+#endif /* !defined(all the DEFINE_ACTION_xxx macros) */
+
+#ifndef DEFINE_CGI_PARAM_RADIO
+#define DEFINE_CGI_PARAM_RADIO(name, bit, index, value, is_default)
+#define DEFINE_CGI_PARAM_CUSTOM(name, bit, index, default_val)
+#define DEFINE_CGI_PARAM_NO_RADIO(name, bit, index, default_val)
+#endif /* ndef DEFINE_CGI_PARAM_RADIO */
+
+DEFINE_ACTION_MULTI      ("add-header",                 ACTION_MULTI_ADD_HEADER)
+DEFINE_ACTION_BOOL       ("block",                      ACTION_BLOCK)
+DEFINE_ACTION_BOOL       ("crunch-incoming-cookies",    ACTION_NO_COOKIE_SET)
+DEFINE_ACTION_BOOL       ("crunch-outgoing-cookies",    ACTION_NO_COOKIE_READ)
+DEFINE_ACTION_STRING     ("deanimate-gifs",             ACTION_DEANIMATE,       ACTION_STRING_DEANIMATE)
+DEFINE_CGI_PARAM_RADIO   ("deanimate-gifs",             ACTION_DEANIMATE,       ACTION_STRING_DEANIMATE,     "first", 0)
+DEFINE_CGI_PARAM_RADIO   ("deanimate-gifs",             ACTION_DEANIMATE,       ACTION_STRING_DEANIMATE,     "last",  1)
+DEFINE_ACTION_BOOL       ("downgrade-http-version",     ACTION_DOWNGRADE)
+DEFINE_ACTION_BOOL       ("fast-redirects",             ACTION_FAST_REDIRECTS)
+DEFINE_ACTION_MULTI      ("filter",                     ACTION_MULTI_FILTER)
+DEFINE_ACTION_BOOL       ("handle-as-image",            ACTION_IMAGE)
+DEFINE_ACTION_BOOL       ("hide-forwarded-for-headers", ACTION_HIDE_FORWARDED)
+DEFINE_ACTION_STRING     ("hide-from-header",           ACTION_HIDE_FROM,       ACTION_STRING_FROM)
+DEFINE_CGI_PARAM_RADIO   ("hide-from-header",           ACTION_HIDE_FROM,       ACTION_STRING_FROM,          "block", 1)
+DEFINE_CGI_PARAM_CUSTOM  ("hide-from-header",           ACTION_HIDE_FROM,       ACTION_STRING_FROM,          "spam_me_senseless@sittingduck.xyz")
+DEFINE_ACTION_STRING     ("hide-referer",               ACTION_HIDE_REFERER,    ACTION_STRING_REFERER)
+DEFINE_CGI_PARAM_RADIO   ("hide-referer",               ACTION_HIDE_REFERER,    ACTION_STRING_REFERER,       "forge", 1)
+DEFINE_CGI_PARAM_RADIO   ("hide-referer",               ACTION_HIDE_REFERER,    ACTION_STRING_REFERER,       "block", 0)
+DEFINE_CGI_PARAM_CUSTOM  ("hide-referer",               ACTION_HIDE_REFERER,    ACTION_STRING_REFERER,       "http://www.google.com/")
+DEFINE_ACTION_STRING     ("hide-user-agent",            ACTION_HIDE_USER_AGENT, ACTION_STRING_USER_AGENT)
+DEFINE_CGI_PARAM_NO_RADIO("hide-user-agent",            ACTION_HIDE_USER_AGENT, ACTION_STRING_USER_AGENT,    "Privoxy/3.0 (Anonymous)")
+DEFINE_ACTION_BOOL       ("kill-popups",                ACTION_NO_POPUPS)
+DEFINE_ACTION_STRING     ("limit-connect",              ACTION_LIMIT_CONNECT,   ACTION_STRING_LIMIT_CONNECT)
+DEFINE_CGI_PARAM_NO_RADIO("limit-connect",              ACTION_LIMIT_CONNECT,   ACTION_STRING_LIMIT_CONNECT,  "443")
+DEFINE_ACTION_BOOL       ("prevent-compression",        ACTION_NO_COMPRESSION)
+DEFINE_ACTION_BOOL       ("send-vanilla-wafer",         ACTION_VANILLA_WAFER)
+DEFINE_ACTION_MULTI      ("send-wafer",                 ACTION_MULTI_WAFER)
+DEFINE_ACTION_BOOL       ("session-cookies-only",       ACTION_NO_COOKIE_KEEP)
+DEFINE_ACTION_STRING     ("set-image-blocker",          ACTION_IMAGE_BLOCKER,   ACTION_STRING_IMAGE_BLOCKER)
+DEFINE_CGI_PARAM_RADIO   ("set-image-blocker",          ACTION_IMAGE_BLOCKER,   ACTION_STRING_IMAGE_BLOCKER, "pattern", 1)
+DEFINE_CGI_PARAM_RADIO   ("set-image-blocker",          ACTION_IMAGE_BLOCKER,   ACTION_STRING_IMAGE_BLOCKER, "blank", 0)
+DEFINE_CGI_PARAM_CUSTOM  ("set-image-blocker",          ACTION_IMAGE_BLOCKER,   ACTION_STRING_IMAGE_BLOCKER,  CGI_PREFIX "show-banner?type=pattern")
+
+
+#if DEFINE_ACTION_ALIAS
+
+/* 
+ * Alternative spellings
+ */
+DEFINE_ACTION_BOOL       ("kill-popup",      ACTION_NO_POPUPS)
+DEFINE_ACTION_STRING     ("hide-referrer",   ACTION_HIDE_REFERER,    ACTION_STRING_REFERER)
+DEFINE_ACTION_BOOL       ("prevent-keeping-cookies", ACTION_NO_COOKIE_KEEP)
+
+/* 
+ * Pre-3.0 compatibility
+ */
+DEFINE_ACTION_BOOL       ("prevent-reading-cookies", ACTION_NO_COOKIE_READ)
+DEFINE_ACTION_BOOL       ("prevent-setting-cookies", ACTION_NO_COOKIE_SET)
+DEFINE_ACTION_BOOL       ("downgrade",               ACTION_DOWNGRADE)
+DEFINE_ACTION_BOOL       ("hide-forwarded",          ACTION_HIDE_FORWARDED)
+DEFINE_ACTION_STRING     ("hide-from",               ACTION_HIDE_FROM,       ACTION_STRING_FROM)
+DEFINE_ACTION_BOOL       ("image",                   ACTION_IMAGE)
+DEFINE_ACTION_STRING     ("image-blocker",           ACTION_IMAGE_BLOCKER,   ACTION_STRING_IMAGE_BLOCKER)
+DEFINE_ACTION_BOOL       ("no-compression",          ACTION_NO_COMPRESSION)
+DEFINE_ACTION_BOOL       ("no-cookies-keep",         ACTION_NO_COOKIE_KEEP)
+DEFINE_ACTION_BOOL       ("no-cookies-read",         ACTION_NO_COOKIE_READ)
+DEFINE_ACTION_BOOL       ("no-cookies-set",          ACTION_NO_COOKIE_SET)
+DEFINE_ACTION_BOOL       ("no-popups",               ACTION_NO_POPUPS)
+#endif /* if DEFINE_ACTION_ALIAS */
+
+#undef DEFINE_ACTION_MULTI
+#undef DEFINE_ACTION_STRING
+#undef DEFINE_ACTION_BOOL
+#undef DEFINE_ACTION_ALIAS
+#undef DEFINE_CGI_PARAM_CUSTOM
+#undef DEFINE_CGI_PARAM_RADIO
+#undef DEFINE_CGI_PARAM_NO_RADIO
+
diff --git a/actions.c b/actions.c
new file mode 100644 (file)
index 0000000..4b31f7f
--- /dev/null
+++ b/actions.c
@@ -0,0 +1,1653 @@
+const char actions_rcs[] = "$Id: actions.c,v 1.31 2002/05/06 07:56:50 oes Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/actions.c,v $
+ *
+ * Purpose     :  Declares functions to work with actions files
+ *                Functions declared include: FIXME
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: actions.c,v $
+ *    Revision 1.31  2002/05/06 07:56:50  oes
+ *    Made actions_to_html independent of FEATURE_CGI_EDIT_ACTIONS
+ *
+ *    Revision 1.30  2002/04/30 11:14:52  oes
+ *    Made csp the first parameter in *action_to_html
+ *
+ *    Revision 1.29  2002/04/26 19:30:54  jongfoster
+ *    - current_action_to_html(): Adding help link for the "-" form of
+ *      one-string actions.
+ *    - Some actions had "<br>-", some "<br> -" (note the space).
+ *      Standardizing on no space.
+ *    - Greatly simplifying some of the code by using string_join()
+ *      where appropriate.
+ *
+ *    Revision 1.28  2002/04/26 12:53:15  oes
+ *     - CGI AF editor now writes action lines split into
+ *       single lines with line continuation
+ *     - actions_to_html now embeds each action name in
+ *       link to chapter
+ *     - current_action_to_text is now called current_action_to_html
+ *       and acts like actions_to_html
+ *
+ *    Revision 1.27  2002/04/24 02:10:31  oes
+ *     - Jon's patch for multiple AFs:
+ *       - split load_actions_file, add load_one_actions_file
+ *       - make csp->actions_list files an array
+ *       - remember file id with each action
+ *     - Copy_action now frees dest action before copying
+ *
+ *    Revision 1.26  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.25  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.24  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.23  2002/03/07 03:46:16  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.22  2002/01/21 00:27:02  jongfoster
+ *    Allowing free_action(NULL).
+ *    Moving the functions that #include actionlist.h to the end of the file,
+ *    because the Visual C++ 97 debugger gets extremely confused if you try
+ *    to debug any code that comes after them in the file.
+ *
+ *    Revision 1.21  2002/01/17 20:54:44  jongfoster
+ *    Renaming free_url to free_url_spec, since it frees a struct url_spec.
+ *
+ *    Revision 1.20  2001/11/22 21:56:49  jongfoster
+ *    Making action_spec->flags into an unsigned long rather than just an
+ *    unsigned int.
+ *    Fixing a bug in the display of -add-header and -wafer
+ *
+ *    Revision 1.19  2001/11/13 00:14:07  jongfoster
+ *    Fixing stupid bug now I've figured out what || means.
+ *    (It always returns 0 or 1, not one of it's paramaters.)
+ *
+ *    Revision 1.18  2001/11/07 00:06:06  steudten
+ *    Add line number in error output for lineparsing for
+ *    actionsfile.
+ *
+ *    Revision 1.17  2001/10/25 03:40:47  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.16  2001/10/23 21:30:30  jongfoster
+ *    Adding error-checking to selected functions.
+ *
+ *    Revision 1.15  2001/10/14 21:58:22  jongfoster
+ *    Adding support for the CGI-based editor:
+ *    - Exported get_actions()
+ *    - Added new function free_alias_list()
+ *    - Added support for {{settings}} and {{description}} blocks
+ *      in the actions file.  They are currently ignored.
+ *    - Added restriction to only one {{alias}} block which must appear
+ *      first in the file, to simplify the editor's rewriting rules.
+ *    - Note that load_actions_file() is no longer used by the CGI-based
+ *      editor, but some of the other routines in this file are.
+ *
+ *    Revision 1.14  2001/09/22 16:36:59  jongfoster
+ *    Removing unused parameter fs from read_config_line()
+ *
+ *    Revision 1.13  2001/09/16 15:47:37  jongfoster
+ *    First version of CGI-based edit interface.  This is very much a
+ *    work-in-progress, and you can't actually use it to edit anything
+ *    yet.  You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
+ *    to have any effect.
+ *
+ *    Revision 1.12  2001/09/16 13:21:27  jongfoster
+ *    Changes to use new list functions.
+ *
+ *    Revision 1.11  2001/09/14 00:17:32  jongfoster
+ *    Tidying up memory allocation. New function init_action().
+ *
+ *    Revision 1.10  2001/09/10 10:14:34  oes
+ *    Removing unused variable
+ *
+ *    Revision 1.9  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.8  2001/06/29 13:19:52  oes
+ *    Removed logentry from cancelled commit
+ *
+ *    Revision 1.7  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.6  2001/06/07 23:04:34  jongfoster
+ *    Made get_actions() static.
+ *
+ *    Revision 1.5  2001/06/03 19:11:48  oes
+ *    adapted to new enlist_unique arg format
+ *
+ *    Revision 1.4  2001/06/01 20:03:42  jongfoster
+ *    Better memory management - current_action->strings[] now
+ *    contains copies of the strings, not the original.
+ *
+ *    Revision 1.3  2001/06/01 18:49:17  jongfoster
+ *    Replaced "list_share" with "list" - the tiny memory gain was not
+ *    worth the extra complexity.
+ *
+ *    Revision 1.2  2001/05/31 21:40:00  jongfoster
+ *    Removing some commented out, obsolete blocks of code.
+ *
+ *    Revision 1.1  2001/05/31 21:16:46  jongfoster
+ *    Moved functions to process the action list into this new file.
+ *
+ *
+ *********************************************************************/
+\f
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "project.h"
+#include "jcc.h"
+#include "list.h"
+#include "actions.h"
+#include "miscutil.h"
+#include "errlog.h"
+#include "loaders.h"
+#include "encode.h"
+#include "urlmatch.h"
+#include "cgi.h"
+
+const char actions_h_rcs[] = ACTIONS_H_VERSION;
+
+
+/*
+ * We need the main list of options.
+ *
+ * First, we need a way to tell between boolean, string, and multi-string
+ * options.  For string and multistring options, we also need to be
+ * able to tell the difference between a "+" and a "-".  (For bools,
+ * the "+"/"-" information is encoded in "add" and "mask").  So we use
+ * an enumerated type (well, the preprocessor equivalent).  Here are
+ * the values:
+ */
+#define AV_NONE       0 /* +opt -opt */
+#define AV_ADD_STRING 1 /* +stropt{string} */
+#define AV_REM_STRING 2 /* -stropt */
+#define AV_ADD_MULTI  3 /* +multiopt{string} +multiopt{string2} */
+#define AV_REM_MULTI  4 /* -multiopt{string} -multiopt          */
+
+/*
+ * We need a structure to hold the name, flag changes,
+ * type, and string index.
+ */
+struct action_name
+{
+   const char * name;
+   unsigned mask;   /* a bit set to "0" = remove action */
+   unsigned add;    /* a bit set to "1" = add action */
+   int takes_value; /* an AV_... constant */
+   int index;       /* index into strings[] or multi[] */
+};
+
+/*
+ * And with those building blocks in place, here's the array.
+ */
+static const struct action_name action_names[] =
+{
+   /*
+    * Well actually there's no data here - it's in actionlist.h
+    * This keeps it together to make it easy to change.
+    *
+    * Here's the macros used to format it:
+    */
+#define DEFINE_ACTION_MULTI(name,index)                   \
+   { "+" name, ACTION_MASK_ALL, 0, AV_ADD_MULTI, index }, \
+   { "-" name, ACTION_MASK_ALL, 0, AV_REM_MULTI, index },
+#define DEFINE_ACTION_STRING(name,flag,index)                 \
+   { "+" name, ACTION_MASK_ALL, flag, AV_ADD_STRING, index }, \
+   { "-" name, ~flag, 0, AV_REM_STRING, index },
+#define DEFINE_ACTION_BOOL(name,flag)   \
+   { "+" name, ACTION_MASK_ALL, flag }, \
+   { "-" name, ~flag, 0 },
+#define DEFINE_ACTION_ALIAS 1 /* Want aliases please */
+
+#include "actionlist.h"
+
+#undef DEFINE_ACTION_MULTI
+#undef DEFINE_ACTION_STRING
+#undef DEFINE_ACTION_BOOL
+#undef DEFINE_ACTION_ALIAS
+
+   { NULL, 0, 0 } /* End marker */
+};
+
+
+static int load_one_actions_file(struct client_state *csp, int fileid);
+
+
+/*********************************************************************
+ *
+ * Function    :  merge_actions
+ *
+ * Description :  Merge two actions together.
+ *                Similar to "dest += src".
+ *
+ * Parameters  :
+ *          1  :  dest = Actions to modify.
+ *          2  :  src = Action to add.
+ *
+ * Returns     :  JB_ERR_OK or JB_ERR_MEMORY
+ *
+ *********************************************************************/
+jb_err merge_actions (struct action_spec *dest,
+                      const struct action_spec *src)
+{
+   int i;
+   jb_err err;
+
+   dest->mask &= src->mask;
+   dest->add  &= src->mask;
+   dest->add  |= src->add;
+
+   for (i = 0; i < ACTION_STRING_COUNT; i++)
+   {
+      char * str = src->string[i];
+      if (str)
+      {
+         freez(dest->string[i]);
+         dest->string[i] = strdup(str);
+         if (NULL == dest->string[i])
+         {
+            return JB_ERR_MEMORY;
+         }
+      }
+   }
+
+   for (i = 0; i < ACTION_MULTI_COUNT; i++)
+   {
+      if (src->multi_remove_all[i])
+      {
+         /* Remove everything from dest */
+         list_remove_all(dest->multi_remove[i]);
+         dest->multi_remove_all[i] = 1;
+
+         err = list_duplicate(dest->multi_add[i], src->multi_add[i]);
+      }
+      else if (dest->multi_remove_all[i])
+      {
+         /*
+          * dest already removes everything, so we only need to worry
+          * about what we add.
+          */
+         list_remove_list(dest->multi_add[i], src->multi_remove[i]);
+         err = list_append_list_unique(dest->multi_add[i], src->multi_add[i]);
+      }
+      else
+      {
+         /* No "remove all"s to worry about. */
+         list_remove_list(dest->multi_add[i], src->multi_remove[i]);
+         err = list_append_list_unique(dest->multi_remove[i], src->multi_remove[i]);
+         if (!err) err = list_append_list_unique(dest->multi_add[i], src->multi_add[i]);
+      }
+
+      if (err)
+      {
+         return err;
+      }
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  copy_action
+ *
+ * Description :  Copy an action_specs.
+ *                Similar to "dest = src".
+ *
+ * Parameters  :
+ *          1  :  dest = Destination of copy.
+ *          2  :  src = Source for copy.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+jb_err copy_action (struct action_spec *dest,
+                    const struct action_spec *src)
+{
+   int i;
+   jb_err err = JB_ERR_OK;
+
+   free_action(dest);
+   memset(dest, '\0', sizeof(*dest));
+
+   dest->mask = src->mask;
+   dest->add  = src->add;
+
+   for (i = 0; i < ACTION_STRING_COUNT; i++)
+   {
+      char * str = src->string[i];
+      if (str)
+      {
+         str = strdup(str);
+         if (!str)
+         {
+            return JB_ERR_MEMORY;
+         }
+         dest->string[i] = str;
+      }
+   }
+
+   for (i = 0; i < ACTION_MULTI_COUNT; i++)
+   {
+      dest->multi_remove_all[i] = src->multi_remove_all[i];
+      err = list_duplicate(dest->multi_remove[i], src->multi_remove[i]);
+      if (err)
+      {
+         return err;
+      }
+      err = list_duplicate(dest->multi_add[i],    src->multi_add[i]);
+      if (err)
+      {
+         return err;
+      }
+   }
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_action
+ *
+ * Description :  Destroy an action_spec.  Frees memory used by it,
+ *                except for the memory used by the struct action_spec
+ *                itself.
+ *
+ * Parameters  :
+ *          1  :  src = Source to free.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void free_action (struct action_spec *src)
+{
+   int i;
+
+   if (src == NULL)
+   {
+      return;
+   }
+
+   for (i = 0; i < ACTION_STRING_COUNT; i++)
+   {
+      freez(src->string[i]);
+   }
+
+   for (i = 0; i < ACTION_MULTI_COUNT; i++)
+   {
+      destroy_list(src->multi_remove[i]);
+      destroy_list(src->multi_add[i]);
+   }
+
+   memset(src, '\0', sizeof(*src));
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_action_token
+ *
+ * Description :  Parses a line for the first action.
+ *                Modifies it's input array, doesn't allocate memory.
+ *                e.g. given:
+ *                *line="  +abc{def}  -ghi "
+ *                Returns:
+ *                *line="  -ghi "
+ *                *name="+abc"
+ *                *value="def"
+ *
+ * Parameters  :
+ *          1  :  line = [in] The line containing the action.
+ *                       [out] Start of next action on line, or
+ *                       NULL if we reached the end of line before
+ *                       we found an action.
+ *          2  :  name = [out] Start of action name, null
+ *                       terminated.  NULL on EOL
+ *          3  :  value = [out] Start of action value, null
+ *                        terminated.  NULL if none or EOL.
+ *
+ * Returns     :  JB_ERR_OK => Ok
+ *                JB_ERR_PARSE => Mismatched {} (line was trashed anyway)
+ *
+ *********************************************************************/
+jb_err get_action_token(char **line, char **name, char **value)
+{
+   char * str = *line;
+   char ch;
+
+   /* set default returns */
+   *line = NULL;
+   *name = NULL;
+   *value = NULL;
+
+   /* Eat any leading whitespace */
+   while ((*str == ' ') || (*str == '\t'))
+   {
+      str++;
+   }
+
+   if (*str == '\0')
+   {
+      return 0;
+   }
+
+   if (*str == '{')
+   {
+      /* null name, just value is prohibited */
+      return JB_ERR_PARSE;
+   }
+
+   *name = str;
+
+   /* parse option */
+   while (((ch = *str) != '\0') &&
+          (ch != ' ') && (ch != '\t') && (ch != '{'))
+   {
+      if (ch == '}')
+      {
+         /* error, '}' without '{' */
+         return JB_ERR_PARSE;
+      }
+      str++;
+   }
+   *str = '\0';
+
+   if (ch != '{')
+   {
+      /* no value */
+      if (ch == '\0')
+      {
+         /* EOL - be careful not to run off buffer */
+         *line = str;
+      }
+      else
+      {
+         /* More to parse next time. */
+         *line = str + 1;
+      }
+      return JB_ERR_OK;
+   }
+
+   str++;
+   *value = str;
+
+   str = strchr(str, '}');
+   if (str == NULL)
+   {
+      /* error */
+      *value = NULL;
+      return JB_ERR_PARSE;
+   }
+
+   /* got value */
+   *str = '\0';
+   *line = str + 1;
+
+   chomp(*value);
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_actions
+ *
+ * Description :  Parses a list of actions.
+ *
+ * Parameters  :
+ *          1  :  line = The string containing the actions.
+ *                       Will be written to by this function.
+ *          2  :  alias_list = Custom alias list, or NULL for none.
+ *          3  :  cur_action = Where to store the action.  Caller
+ *                             allocates memory.
+ *
+ * Returns     :  JB_ERR_OK => Ok
+ *                JB_ERR_PARSE => Parse error (line was trashed anyway)
+ *                nonzero => Out of memory (line was trashed anyway)
+ *
+ *********************************************************************/
+jb_err get_actions(char *line,
+                   struct action_alias * alias_list,
+                   struct action_spec *cur_action)
+{
+   jb_err err;
+   init_action(cur_action);
+   cur_action->mask = ACTION_MASK_ALL;
+
+   while (line)
+   {
+      char * option = NULL;
+      char * value = NULL;
+
+      err = get_action_token(&line, &option, &value);
+      if (err)
+      {
+         return err;
+      }
+
+      if (option)
+      {
+         /* handle option in 'option' */
+
+         /* Check for standard action name */
+         const struct action_name * action = action_names;
+
+         while ( (action->name != NULL) && (0 != strcmpic(action->name, option)) )
+         {
+            action++;
+         }
+         if (action->name != NULL)
+         {
+            /* Found it */
+            cur_action->mask &= action->mask;
+            cur_action->add  &= action->mask;
+            cur_action->add  |= action->add;
+
+            switch (action->takes_value)
+            {
+            case AV_NONE:
+               /* ignore any option. */
+               break;
+            case AV_ADD_STRING:
+               {
+                  /* add single string. */
+
+                  if ((value == NULL) || (*value == '\0'))
+                  {
+                     return JB_ERR_PARSE;
+                  }
+                  /* FIXME: should validate option string here */
+                  freez (cur_action->string[action->index]);
+                  cur_action->string[action->index] = strdup(value);
+                  if (NULL == cur_action->string[action->index])
+                  {
+                     return JB_ERR_MEMORY;
+                  }
+                  break;
+               }
+            case AV_REM_STRING:
+               {
+                  /* remove single string. */
+
+                  freez (cur_action->string[action->index]);
+                  break;
+               }
+            case AV_ADD_MULTI:
+               {
+                  /* append multi string. */
+
+                  struct list * remove_p = cur_action->multi_remove[action->index];
+                  struct list * add_p    = cur_action->multi_add[action->index];
+
+                  if ((value == NULL) || (*value == '\0'))
+                  {
+                     return JB_ERR_PARSE;
+                  }
+
+                  list_remove_item(remove_p, value);
+                  err = enlist_unique(add_p, value, 0);
+                  if (err)
+                  {
+                     return err;
+                  }
+                  break;
+               }
+            case AV_REM_MULTI:
+               {
+                  /* remove multi string. */
+
+                  struct list * remove_p = cur_action->multi_remove[action->index];
+                  struct list * add_p    = cur_action->multi_add[action->index];
+
+                  if ( (value == NULL) || (*value == '\0')
+                     || ((*value == '*') && (value[1] == '\0')) )
+                  {
+                     /*
+                      * no option, or option == "*".
+                      *
+                      * Remove *ALL*.
+                      */
+                     list_remove_all(remove_p);
+                     list_remove_all(add_p);
+                     cur_action->multi_remove_all[action->index] = 1;
+                  }
+                  else
+                  {
+                     /* Valid option - remove only 1 option */
+
+                     if ( !cur_action->multi_remove_all[action->index] )
+                     {
+                        /* there isn't a catch-all in the remove list already */
+                        err = enlist_unique(remove_p, value, 0);
+                        if (err)
+                        {
+                           return err;
+                        }
+                     }
+                     list_remove_item(add_p, value);
+                  }
+                  break;
+               }
+            default:
+               /* Shouldn't get here unless there's memory corruption. */
+               assert(0);
+               return JB_ERR_PARSE;
+            }
+         }
+         else
+         {
+            /* try user aliases. */
+            const struct action_alias * alias = alias_list;
+
+            while ( (alias != NULL) && (0 != strcmpic(alias->name, option)) )
+            {
+               alias = alias->next;
+            }
+            if (alias != NULL)
+            {
+               /* Found it */
+               merge_actions(cur_action, alias->action);
+            }
+            else
+            {
+               /* Bad action name */
+               return JB_ERR_PARSE;
+            }
+         }
+      }
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  init_current_action
+ *
+ * Description :  Zero out an action.
+ *
+ * Parameters  :
+ *          1  :  dest = An uninitialized current_action_spec.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void init_current_action (struct current_action_spec *dest)
+{
+   memset(dest, '\0', sizeof(*dest));
+
+   dest->flags = ACTION_MOST_COMPATIBLE;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  init_action
+ *
+ * Description :  Zero out an action.
+ *
+ * Parameters  :
+ *          1  :  dest = An uninitialized action_spec.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void init_action (struct action_spec *dest)
+{
+   memset(dest, '\0', sizeof(*dest));
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  merge_current_action
+ *
+ * Description :  Merge two actions together.
+ *                Similar to "dest += src".
+ *                Differences between this and merge_actions()
+ *                is that this one doesn't allocate memory for
+ *                strings (so "src" better be in memory for at least
+ *                as long as "dest" is, and you'd better free
+ *                "dest" using "free_current_action").
+ *                Also, there is no  mask or remove lists in dest.
+ *                (If we're applying it to a URL, we don't need them)
+ *
+ * Parameters  :
+ *          1  :  dest = Current actions, to modify.
+ *          2  :  src = Action to add.
+ *
+ * Returns  0  :  no error
+ *        !=0  :  error, probably JB_ERR_MEMORY.
+ *
+ *********************************************************************/
+jb_err merge_current_action (struct current_action_spec *dest,
+                             const struct action_spec *src)
+{
+   int i;
+   jb_err err = JB_ERR_OK;
+
+   dest->flags  &= src->mask;
+   dest->flags  |= src->add;
+
+   for (i = 0; i < ACTION_STRING_COUNT; i++)
+   {
+      char * str = src->string[i];
+      if (str)
+      {
+         str = strdup(str);
+         if (!str)
+         {
+            return JB_ERR_MEMORY;
+         }
+         freez(dest->string[i]);
+         dest->string[i] = str;
+      }
+   }
+
+   for (i = 0; i < ACTION_MULTI_COUNT; i++)
+   {
+      if (src->multi_remove_all[i])
+      {
+         /* Remove everything from dest, then add src->multi_add */
+         err = list_duplicate(dest->multi[i], src->multi_add[i]);
+         if (err)
+         {
+            return err;
+         }
+      }
+      else
+      {
+         list_remove_list(dest->multi[i], src->multi_remove[i]);
+         err = list_append_list_unique(dest->multi[i], src->multi_add[i]);
+         if (err)
+         {
+            return err;
+         }
+      }
+   }
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_current_action
+ *
+ * Description :  Free memory used by a current_action_spec.
+ *                Does not free the current_action_spec itself.
+ *
+ * Parameters  :
+ *          1  :  src = Source to free.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void free_current_action (struct current_action_spec *src)
+{
+   int i;
+
+   for (i = 0; i < ACTION_STRING_COUNT; i++)
+   {
+      freez(src->string[i]);
+   }
+
+   for (i = 0; i < ACTION_MULTI_COUNT; i++)
+   {
+      destroy_list(src->multi[i]);
+   }
+
+   memset(src, '\0', sizeof(*src));
+}
+
+
+static struct file_list *current_actions_file[MAX_ACTION_FILES]  = {
+   NULL, NULL, NULL, NULL, NULL,
+   NULL, NULL, NULL, NULL, NULL
+};
+
+
+#ifdef FEATURE_GRACEFUL_TERMINATION
+/*********************************************************************
+ *
+ * Function    :  unload_current_actions_file
+ *
+ * Description :  Unloads current actions file - reset to state at
+ *                beginning of program.
+ *
+ * Parameters  :  None
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void unload_current_actions_file(void)
+{
+   if (current_actions_file)
+   {
+      current_actions_file->unloader = unload_actions_file;
+      current_actions_file = NULL;
+   }
+}
+#endif /* FEATURE_GRACEFUL_TERMINATION */
+
+
+/*********************************************************************
+ *
+ * Function    :  unload_actions_file
+ *
+ * Description :  Unloads an actions module.
+ *
+ * Parameters  :
+ *          1  :  file_data = the data structure associated with the
+ *                            actions file.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void unload_actions_file(void *file_data)
+{
+   struct url_actions * next;
+   struct url_actions * cur = (struct url_actions *)file_data;
+   while (cur != NULL)
+   {
+      next = cur->next;
+      free_url_spec(cur->url);
+      free_action(cur->action);
+      freez(cur);
+      cur = next;
+   }
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_alias_list
+ *
+ * Description :  Free memory used by a list of aliases.
+ *
+ * Parameters  :
+ *          1  :  alias_list = Linked list to free.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void free_alias_list(struct action_alias *alias_list)
+{
+   while (alias_list != NULL)
+   {
+      struct action_alias * next = alias_list->next;
+      alias_list->next = NULL;
+      freez(alias_list->name);
+      free_action(alias_list->action);
+      free(alias_list);
+      alias_list = next;
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  load_actions_file
+ *
+ * Description :  Read and parse all the action files and add to files
+ *                list.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  0 => Ok, everything else is an error.
+ *
+ *********************************************************************/
+int load_actions_file(struct client_state *csp)
+{
+   int i;
+   int result;
+
+   for (i = 0; i < MAX_ACTION_FILES; i++)
+   {
+      if (csp->config->actions_file[i])
+      {
+         result = load_one_actions_file(csp, i);
+         if (result)
+         {
+            return result;
+         }
+      }
+      else if (current_actions_file[i])
+      {
+         current_actions_file[i]->unloader = unload_actions_file;
+         current_actions_file[i] = NULL;
+      }
+   }
+
+   return 0;
+}
+
+/*********************************************************************
+ *
+ * Function    :  load_one_actions_file
+ *
+ * Description :  Read and parse a action file and add to files
+ *                list.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  fileid = File index to load.
+ *
+ * Returns     :  0 => Ok, everything else is an error.
+ *
+ *********************************************************************/
+static int load_one_actions_file(struct client_state *csp, int fileid)
+{
+
+   /*
+    * Parser mode.
+    * Note: Keep these in the order they occur in the file, they are
+    * sometimes tested with <=
+    */
+#define MODE_START_OF_FILE 1
+#define MODE_SETTINGS      2
+#define MODE_DESCRIPTION   3
+#define MODE_ALIAS         4
+#define MODE_ACTIONS       5
+
+   int mode = MODE_START_OF_FILE;
+
+   FILE *fp;
+   struct url_actions *last_perm;
+   struct url_actions *perm;
+   char  buf[BUFFER_SIZE];
+   struct file_list *fs;
+   struct action_spec * cur_action = NULL;
+   int cur_action_used = 0;
+   struct action_alias * alias_list = NULL;
+   unsigned long linenum = 0;
+
+   if (!check_file_changed(current_actions_file[fileid], csp->config->actions_file[fileid], &fs))
+   {
+      /* No need to load */
+      csp->actions_list[fileid] = current_actions_file[fileid];
+      return 0;
+   }
+   if (!fs)
+   {
+      log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': error finding file: %E",
+                csp->config->actions_file[fileid]);
+      return 1; /* never get here */
+   }
+
+   fs->f = last_perm = (struct url_actions *)zalloc(sizeof(*last_perm));
+   if (last_perm == NULL)
+   {
+      log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': out of memory!",
+                csp->config->actions_file[fileid]);
+      return 1; /* never get here */
+   }
+
+   if ((fp = fopen(csp->config->actions_file[fileid], "r")) == NULL)
+   {
+      log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': error opening file: %E",
+                csp->config->actions_file[fileid]);
+      return 1; /* never get here */
+   }
+
+   while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
+   {
+      if (*buf == '{')
+      {
+         /* It's a header block */
+         if (buf[1] == '{')
+         {
+            /* It's {{settings}} or {{alias}} */
+            int len = strlen(buf);
+            char * start = buf + 2;
+            char * end = buf + len - 1;
+            if ((len < 5) || (*end-- != '}') || (*end-- != '}'))
+            {
+               /* too short */
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                  "can't load actions file '%s': invalid line (%lu): %s", 
+                  csp->config->actions_file[fileid], linenum, buf);
+               return 1; /* never get here */
+            }
+
+            /* Trim leading and trailing whitespace. */
+            end[1] = '\0';
+            chomp(start);
+
+            if (*start == '\0')
+            {
+               /* too short */
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                  "can't load actions file '%s': invalid line (%lu): {{ }}",
+                  csp->config->actions_file[fileid], linenum);
+               return 1; /* never get here */
+            }
+
+            /*
+             * An actionsfile can optionally contain the following blocks.
+             * They *MUST* be in this order, to simplify processing:
+             *
+             * {{settings}}
+             * name=value...
+             *
+             * {{description}}
+             * ...free text, format TBD, but no line may start with a '{'...
+             *
+             * {{alias}}
+             * name=actions...
+             *
+             * The actual actions must be *after* these special blocks.
+             * None of these special blocks may be repeated.
+             *
+             */
+            if (0 == strcmpic(start, "settings"))
+            {
+               /* it's a {{settings}} block */
+               if (mode >= MODE_SETTINGS)
+               {
+                  /* {{settings}} must be first thing in file and must only
+                   * appear once.
+                   */
+                  fclose(fp);
+                  log_error(LOG_LEVEL_FATAL,
+                     "can't load actions file '%s': line %lu: {{settings}} must only appear once, and it must be before anything else.",
+                     csp->config->actions_file[fileid], linenum);
+               }
+               mode = MODE_SETTINGS;
+            }
+            else if (0 == strcmpic(start, "description"))
+            {
+               /* it's a {{description}} block */
+               if (mode >= MODE_DESCRIPTION)
+               {
+                  /* {{description}} is a singleton and only {{settings}} may proceed it
+                   */
+                  fclose(fp);
+                  log_error(LOG_LEVEL_FATAL,
+                     "can't load actions file '%s': line %lu: {{description}} must only appear once, and only a {{settings}} block may be above it.",
+                     csp->config->actions_file[fileid], linenum);
+               }
+               mode = MODE_DESCRIPTION;
+            }
+            else if (0 == strcmpic(start, "alias"))
+            {
+               /* it's an {{alias}} block */
+               if (mode >= MODE_ALIAS)
+               {
+                  /* {{alias}} must be first thing in file, possibly after
+                   * {{settings}} and {{description}}
+                   *
+                   * {{alias}} must only appear once.
+                   *
+                   * Note that these are new restrictions introduced in
+                   * v2.9.10 in order to make actionsfile editing simpler.
+                   * (Otherwise, reordering actionsfile entries without
+                   * completely rewriting the file becomes non-trivial)
+                   */
+                  fclose(fp);
+                  log_error(LOG_LEVEL_FATAL,
+                     "can't load actions file '%s': line %lu: {{alias}} must only appear once, and it must be before all actions.",
+                     csp->config->actions_file[fileid], linenum);
+               }
+               mode = MODE_ALIAS;
+            }
+            else
+            {
+               /* invalid {{something}} block */
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                  "can't load actions file '%s': invalid line (%lu): {{%s}}",
+                  csp->config->actions_file[fileid], linenum, start);
+               return 1; /* never get here */
+            }
+         }
+         else
+         {
+            /* It's an actions block */
+
+            char  actions_buf[BUFFER_SIZE];
+            char * end;
+
+            /* set mode */
+            mode    = MODE_ACTIONS;
+
+            /* free old action */
+            if (cur_action)
+            {
+               if (!cur_action_used)
+               {
+                  free_action(cur_action);
+                  free(cur_action);
+               }
+               cur_action = NULL;
+            }
+            cur_action_used = 0;
+            cur_action = (struct action_spec *)zalloc(sizeof(*cur_action));
+            if (cur_action == NULL)
+            {
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                  "can't load actions file '%s': out of memory",
+                  csp->config->actions_file[fileid]);
+               return 1; /* never get here */
+            }
+            init_action(cur_action);
+
+            /* trim { */
+            strcpy(actions_buf, buf + 1);
+
+            /* check we have a trailing } and then trim it */
+            end = actions_buf + strlen(actions_buf) - 1;
+            if (*end != '}')
+            {
+               /* No closing } */
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                  "can't load actions file '%s': invalid line (%lu): %s",
+                  csp->config->actions_file[fileid], linenum, buf);
+               return 1; /* never get here */
+            }
+            *end = '\0';
+
+            /* trim any whitespace immediately inside {} */
+            chomp(actions_buf);
+
+            if (get_actions(actions_buf, alias_list, cur_action))
+            {
+               /* error */
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                  "can't load actions file '%s': invalid line (%lu): %s",
+                  csp->config->actions_file[fileid], linenum, buf);
+               return 1; /* never get here */
+            }
+         }
+      }
+      else if (mode == MODE_SETTINGS)
+      {
+         /*
+          * Part of the {{settings}} block.
+          * Ignore for now, but we may want to read & check permissions
+          * when we go multi-user.
+          */
+      }
+      else if (mode == MODE_DESCRIPTION)
+      {
+         /*
+          * Part of the {{description}} block.
+          * Ignore for now.
+          */
+      }
+      else if (mode == MODE_ALIAS)
+      {
+         /*
+          * define an alias
+          */
+         char  actions_buf[BUFFER_SIZE];
+         struct action_alias * new_alias;
+
+         char * start = strchr(buf, '=');
+         char * end = start;
+
+         if ((start == NULL) || (start == buf))
+         {
+            log_error(LOG_LEVEL_FATAL,
+               "can't load actions file '%s': invalid alias line (%lu): %s",
+               csp->config->actions_file[fileid], linenum, buf);
+            return 1; /* never get here */
+         }
+
+         if ((new_alias = zalloc(sizeof(*new_alias))) == NULL)
+         {
+            fclose(fp);
+            log_error(LOG_LEVEL_FATAL,
+               "can't load actions file '%s': out of memory!",
+               csp->config->actions_file[fileid]);
+            return 1; /* never get here */
+         }
+
+         /* Eat any the whitespace before the '=' */
+         end--;
+         while ((*end == ' ') || (*end == '\t'))
+         {
+            /*
+             * we already know we must have at least 1 non-ws char
+             * at start of buf - no need to check
+             */
+            end--;
+         }
+         end[1] = '\0';
+
+         /* Eat any the whitespace after the '=' */
+         start++;
+         while ((*start == ' ') || (*start == '\t'))
+         {
+            start++;
+         }
+         if (*start == '\0')
+         {
+            log_error(LOG_LEVEL_FATAL,
+               "can't load actions file '%s': invalid alias line (%lu): %s",
+               csp->config->actions_file[fileid], linenum, buf);
+            return 1; /* never get here */
+         }
+
+         new_alias->name = strdup(buf);
+
+         strcpy(actions_buf, start);
+
+         if (get_actions(actions_buf, alias_list, new_alias->action))
+         {
+            /* error */
+            fclose(fp);
+            log_error(LOG_LEVEL_FATAL,
+               "can't load actions file '%s': invalid alias line (%lu): %s = %s",
+               csp->config->actions_file[fileid], linenum, buf, start);
+            return 1; /* never get here */
+         }
+
+         /* add to list */
+         new_alias->next = alias_list;
+         alias_list = new_alias;
+      }
+      else if (mode == MODE_ACTIONS)
+      {
+         /* it's a URL pattern */
+
+         /* allocate a new node */
+         if ((perm = zalloc(sizeof(*perm))) == NULL)
+         {
+            fclose(fp);
+            log_error(LOG_LEVEL_FATAL,
+               "can't load actions file '%s': out of memory!",
+               csp->config->actions_file[fileid]);
+            return 1; /* never get here */
+         }
+
+         /* Save flags */
+         copy_action (perm->action, cur_action);
+
+         /* Save the URL pattern */
+         if (create_url_spec(perm->url, buf))
+         {
+            fclose(fp);
+            log_error(LOG_LEVEL_FATAL,
+               "can't load actions file '%s': line %lu: cannot create URL pattern from: %s",
+               csp->config->actions_file[fileid], linenum, buf);
+            return 1; /* never get here */
+         }
+
+         /* add it to the list */
+         last_perm->next = perm;
+         last_perm = perm;
+      }
+      else if (mode == MODE_START_OF_FILE)
+      {
+         /* oops - please have a {} line as 1st line in file. */
+         fclose(fp);
+         log_error(LOG_LEVEL_FATAL,
+            "can't load actions file '%s': first needed line (%lu) is invalid: %s",
+            csp->config->actions_file[fileid], linenum, buf);
+         return 1; /* never get here */
+      }
+      else
+      {
+         /* How did we get here? This is impossible! */
+         fclose(fp);
+         log_error(LOG_LEVEL_FATAL,
+            "can't load actions file '%s': INTERNAL ERROR - mode = %d",
+            csp->config->actions_file[fileid], mode);
+         return 1; /* never get here */
+      }
+   }
+
+   fclose(fp);
+
+   free_action(cur_action);
+
+   free_alias_list(alias_list);
+
+   /* the old one is now obsolete */
+   if (current_actions_file[fileid])
+   {
+      current_actions_file[fileid]->unloader = unload_actions_file;
+   }
+
+   fs->next    = files->next;
+   files->next = fs;
+   current_actions_file[fileid] = fs;
+
+   csp->actions_list[fileid] = fs;
+
+   return(0);
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  actions_to_text
+ *
+ * Description :  Converts a actionsfile entry from the internal
+ *                structurt into a text line.  The output is split
+ *                into one line for each action with line continuation. 
+ *
+ * Parameters  :
+ *          1  :  action = The action to format.
+ *
+ * Returns     :  A string.  Caller must free it.
+ *                NULL on out-of-memory error.
+ *
+ *********************************************************************/
+char * actions_to_text(struct action_spec *action)
+{
+   unsigned mask = action->mask;
+   unsigned add  = action->add;
+   char * result = strdup("");
+   struct list_entry * lst;
+
+   /* sanity - prevents "-feature +feature" */
+   mask |= add;
+
+
+#define DEFINE_ACTION_BOOL(__name, __bit)          \
+   if (!(mask & __bit))                            \
+   {                                               \
+      string_append(&result, " -" __name " \\\n"); \
+   }                                               \
+   else if (add & __bit)                           \
+   {                                               \
+      string_append(&result, " +" __name " \\\n"); \
+   }
+
+#define DEFINE_ACTION_STRING(__name, __bit, __index)   \
+   if (!(mask & __bit))                                \
+   {                                                   \
+      string_append(&result, " -" __name " \\\n");     \
+   }                                                   \
+   else if (add & __bit)                               \
+   {                                                   \
+      string_append(&result, " +" __name "{");         \
+      string_append(&result, action->string[__index]); \
+      string_append(&result, "} \\\n");                \
+   }
+
+#define DEFINE_ACTION_MULTI(__name, __index)         \
+   if (action->multi_remove_all[__index])            \
+   {                                                 \
+      string_append(&result, " -" __name " \\\n");   \
+   }                                                 \
+   else                                              \
+   {                                                 \
+      lst = action->multi_remove[__index]->first;    \
+      while (lst)                                    \
+      {                                              \
+         string_append(&result, " -" __name "{");    \
+         string_append(&result, lst->str);           \
+         string_append(&result, "} \\\n");           \
+         lst = lst->next;                            \
+      }                                              \
+   }                                                 \
+   lst = action->multi_add[__index]->first;          \
+   while (lst)                                       \
+   {                                                 \
+      string_append(&result, " +" __name "{");       \
+      string_append(&result, lst->str);              \
+      string_append(&result, "} \\\n");              \
+      lst = lst->next;                               \
+   }
+
+#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
+
+#include "actionlist.h"
+
+#undef DEFINE_ACTION_MULTI
+#undef DEFINE_ACTION_STRING
+#undef DEFINE_ACTION_BOOL
+#undef DEFINE_ACTION_ALIAS
+
+   return result;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  actions_to_html
+ *
+ * Description :  Converts a actionsfile entry from numeric form
+ *                ("mask" and "add") to a <br>-seperated HTML string
+ *                in which each action is linked to its chapter in
+ *                the user manual.
+ *
+ * Parameters  :
+ *          1  :  csp    = Client state (for config)
+ *          2  :  action = Action spec to be converted
+ *
+ * Returns     :  A string.  Caller must free it.
+ *                NULL on out-of-memory error.
+ *
+ *********************************************************************/
+char * actions_to_html(struct client_state *csp,
+                       struct action_spec *action)
+{
+   unsigned mask = action->mask;
+   unsigned add  = action->add;
+   char * result = strdup("");
+   struct list_entry * lst;
+
+   /* sanity - prevents "-feature +feature" */
+   mask |= add;
+
+
+#define DEFINE_ACTION_BOOL(__name, __bit)       \
+   if (!(mask & __bit))                         \
+   {                                            \
+      string_append(&result, "\n<br>-");        \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }                                            \
+   else if (add & __bit)                        \
+   {                                            \
+      string_append(&result, "\n<br>+");        \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }
+
+#define DEFINE_ACTION_STRING(__name, __bit, __index) \
+   if (!(mask & __bit))                              \
+   {                                                 \
+      string_append(&result, "\n<br>-");             \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }                                                 \
+   else if (add & __bit)                             \
+   {                                                 \
+      string_append(&result, "\n<br>+");             \
+      string_join(&result, add_help_link(__name, csp->config)); \
+      string_append(&result, "{");                   \
+      string_join(&result, html_encode(action->string[__index])); \
+      string_append(&result, "}");                   \
+   }
+
+#define DEFINE_ACTION_MULTI(__name, __index)          \
+   if (action->multi_remove_all[__index])             \
+   {                                                  \
+      string_append(&result, "\n<br>-");              \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }                                                  \
+   else                                               \
+   {                                                  \
+      lst = action->multi_remove[__index]->first;     \
+      while (lst)                                     \
+      {                                               \
+         string_append(&result, "\n<br>-");           \
+         string_join(&result, add_help_link(__name, csp->config)); \
+         string_append(&result, "{");                 \
+         string_join(&result, html_encode(lst->str)); \
+         string_append(&result, "}");                 \
+         lst = lst->next;                             \
+      }                                               \
+   }                                                  \
+   lst = action->multi_add[__index]->first;           \
+   while (lst)                                        \
+   {                                                  \
+      string_append(&result, "\n<br>+");              \
+      string_join(&result, add_help_link(__name, csp->config)); \
+      string_append(&result, "{");                    \
+      string_join(&result, html_encode(lst->str));    \
+      string_append(&result, "}");                    \
+      lst = lst->next;                                \
+   }
+
+#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
+
+#include "actionlist.h"
+
+#undef DEFINE_ACTION_MULTI
+#undef DEFINE_ACTION_STRING
+#undef DEFINE_ACTION_BOOL
+#undef DEFINE_ACTION_ALIAS
+
+   /* trim leading <br> */
+   if (result && *result)
+   {
+      char * s = result;
+      result = strdup(result + 5);
+      free(s);
+   }
+
+   return result;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  current_actions_to_html
+ *
+ * Description :  Converts a curren action spec to a <br> seperated HTML
+ *                text in which each action is linked to its chapter in
+ *                the user manual.
+ *
+ * Parameters  :
+ *          1  :  csp    = Client state (for config) 
+ *          2  :  action = Current action spec to be converted
+ *
+ * Returns     :  A string.  Caller must free it.
+ *                NULL on out-of-memory error.
+ *
+ *********************************************************************/
+char *current_action_to_html(struct client_state *csp,
+                             struct current_action_spec *action)
+{
+   unsigned long flags  = action->flags;
+   char * result = strdup("");
+   struct list_entry * lst;
+
+#define DEFINE_ACTION_BOOL(__name, __bit)  \
+   if (flags & __bit)                      \
+   {                                       \
+      string_append(&result, "\n<br>+");   \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }                                       \
+   else                                    \
+   {                                       \
+      string_append(&result, "\n<br>-");   \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }
+
+#define DEFINE_ACTION_STRING(__name, __bit, __index)   \
+   if (flags & __bit)                                  \
+   {                                                   \
+      string_append(&result, "\n<br>+");               \
+      string_join(&result, add_help_link(__name, csp->config)); \
+      string_append(&result, "{");                     \
+      string_join(&result, html_encode(action->string[__index])); \
+      string_append(&result, "}");                     \
+   }                                                   \
+   else                                                \
+   {                                                   \
+      string_append(&result, "\n<br>-");               \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }
+
+#define DEFINE_ACTION_MULTI(__name, __index)           \
+   lst = action->multi[__index]->first;                \
+   if (lst == NULL)                                    \
+   {                                                   \
+      string_append(&result, "\n<br>-");              \
+      string_join(&result, add_help_link(__name, csp->config)); \
+   }                                                   \
+   else                                                \
+   {                                                   \
+      while (lst)                                      \
+      {                                                \
+         string_append(&result, "\n<br>+");            \
+         string_join(&result, add_help_link(__name, csp->config)); \
+         string_append(&result, "{");                  \
+         string_join(&result, html_encode(lst->str));  \
+         string_append(&result, "}");                  \
+         lst = lst->next;                              \
+      }                                                \
+   }
+
+#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
+
+#include "actionlist.h"
+
+#undef DEFINE_ACTION_MULTI
+#undef DEFINE_ACTION_STRING
+#undef DEFINE_ACTION_BOOL
+#undef DEFINE_ACTION_ALIAS
+
+   return result;
+}
diff --git a/actions.h b/actions.h
new file mode 100644 (file)
index 0000000..f4365f0
--- /dev/null
+++ b/actions.h
@@ -0,0 +1,158 @@
+#ifndef ACTIONS_H_INCLUDED
+#define ACTIONS_H_INCLUDED
+#define ACTIONS_H_VERSION "$Id: actions.h,v 1.11 2002/04/30 11:14:52 oes Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/actions.h,v $
+ *
+ * Purpose     :  Declares functions to work with actions files
+ *                Functions declared include: FIXME
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: actions.h,v $
+ *    Revision 1.11  2002/04/30 11:14:52  oes
+ *    Made csp the first parameter in *action_to_html
+ *
+ *    Revision 1.10  2002/04/26 12:53:33  oes
+ *     -  actions_to_html signature change
+ *     -  current_action_to_text: renamed to current_action_to_html
+ *        and signature change
+ *
+ *    Revision 1.9  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.8  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.7  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.6  2001/10/23 21:30:30  jongfoster
+ *    Adding error-checking to selected functions.
+ *
+ *    Revision 1.5  2001/10/14 21:58:22  jongfoster
+ *    Adding support for the CGI-based editor:
+ *    - Exported get_actions()
+ *    - Added new function free_alias_list()
+ *    - Added support for {{settings}} and {{description}} blocks
+ *      in the actions file.  They are currently ignored.
+ *    - Added restriction to only one {{alias}} block which must appear
+ *      first in the file, to simplify the editor's rewriting rules.
+ *    - Note that load_actions_file() is no longer used by the CGI-based
+ *      editor, but some of the other routines in this file are.
+ *
+ *    Revision 1.4  2001/09/16 15:47:37  jongfoster
+ *    First version of CGI-based edit interface.  This is very much a
+ *    work-in-progress, and you can't actually use it to edit anything
+ *    yet.  You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
+ *    to have any effect.
+ *
+ *    Revision 1.3  2001/09/14 00:17:32  jongfoster
+ *    Tidying up memory allocation. New function init_action().
+ *
+ *    Revision 1.2  2001/07/29 19:01:11  jongfoster
+ *    Changed _FILENAME_H to FILENAME_H_INCLUDED.
+ *    Added forward declarations for needed structures.
+ *
+ *    Revision 1.1  2001/05/31 21:16:46  jongfoster
+ *    Moved functions to process the action list into this new file.
+ *
+ *
+ *********************************************************************/
+\f
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct action_spec;
+struct current_action_spec;
+struct client_state;
+
+
+
+/* This structure is used to hold user-defined aliases */
+struct action_alias
+{
+   const char * name;
+   struct action_spec action[1];
+   struct action_alias * next;
+};
+
+
+extern jb_err get_actions (char *line, 
+                           struct action_alias * alias_list,
+                           struct action_spec *cur_action);
+extern void free_alias_list(struct action_alias *alias_list);
+
+extern void init_action(struct action_spec *dest);
+extern void free_action(struct action_spec *src);
+extern jb_err merge_actions (struct action_spec *dest, 
+                             const struct action_spec *src);
+extern jb_err copy_action (struct action_spec *dest, 
+                           const struct action_spec *src);
+extern char * actions_to_text     (struct action_spec *action);
+extern char * actions_to_html     (struct client_state *csp,
+                                   struct action_spec *action);
+extern void init_current_action     (struct current_action_spec *dest);
+extern void free_current_action     (struct current_action_spec *src);
+extern jb_err merge_current_action  (struct current_action_spec *dest, 
+                                     const struct action_spec *src);
+extern char * current_action_to_html(struct client_state *csp,
+                                     struct current_action_spec *action);
+
+extern jb_err get_action_token(char **line, char **name, char **value);
+extern void unload_actions_file(void *file_data);
+extern int load_actions_file(struct client_state *csp);
+
+#ifdef FEATURE_GRACEFUL_TERMINATION
+void unload_current_actions_file(void);
+#endif
+
+
+/* Revision control strings from this header and associated .c file */
+extern const char actions_rcs[];
+extern const char actions_h_rcs[];
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef ACTIONS_H_INCLUDED */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
+
diff --git a/amiga.c b/amiga.c
index cd22898..493a00e 100644 (file)
--- a/amiga.c
+++ b/amiga.c
@@ -1,12 +1,12 @@
-const char amiga_rcs[] = "$Id: amiga.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char amiga_rcs[] = "$Id: amiga.c,v 1.8 2002/03/25 19:32:15 joergs Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/jcc.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/amiga.c,v $
  *
  * Purpose     :  Amiga-specific declarations.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                This program is free software; you can redistribute it 
  *                and/or modify it under the terms of the GNU General
@@ -27,7 +27,52 @@ const char amiga_rcs[] = "$Id: amiga.c,v 1.1 2001/05/13 21:57:06 administrator E
  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
  * Revisions   :
- *    $Log: jcc.c,v $
+ *    $Log: amiga.c,v $
+ *    Revision 1.8  2002/03/25 19:32:15  joergs
+ *    Name in version string changed from junkbuster to Privoxy.
+ *
+ *    Revision 1.7  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.6  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.5  2002/03/03 09:18:03  joergs
+ *    Made jumbjuster work on AmigaOS again.
+ *
+ *    Revision 1.4  2001/10/07 15:35:13  oes
+ *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
+ *
+ *    Revision 1.3  2001/09/12 22:54:51  joergs
+ *    Stacksize of main thread increased.
+ *
+ *    Revision 1.2  2001/05/23 00:13:58  joergs
+ *    AmigaOS support fixed.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:46  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -39,12 +84,12 @@ const char amiga_rcs[] = "$Id: amiga.c,v 1.1 2001/05/13 21:57:06 administrator E
 #include <stdio.h>
 #include <signal.h>
 
-#include "amiga.h"
+#include "project.h"
 
-chonst char amiga_h_rcs[] = AMIGA_H_VERSION;
+const char amiga_h_rcs[] = AMIGA_H_VERSION;
 
-unsigned long __stack = 20*1024;
-/* static char ver[] = "$VER: junkbuster " __AMIGAVERSION__ " (" __AMIGADATE__ ")"; */
+unsigned long __stack = 100*1024;
+static char ver[] = "$VER: Privoxy " __AMIGAVERSION__ " (" __AMIGADATE__ ")";
 struct Task *main_task = NULL;
 int childs = 0;
 
@@ -64,29 +109,32 @@ __saveds ULONG server_thread(void)
    {
       SetErrnoPtr(&(UserData.eno),sizeof(int));
       local_csp->cfd=ObtainSocket(local_csp->cfd, AF_INET, SOCK_STREAM, 0);
-      if(-1!=local_csp->cfd)
+      if(JB_INVALID_SOCKET!=local_csp->cfd)
       {
          Signal(main_task,SIGF_SINGLE);
          serve((struct client_state *) local_csp);
       } else {
-         local_csp->active = 0;
+         local_csp->flags &= ~CSP_FLAG_ACTIVE;
          Signal(main_task,SIGF_SINGLE);
       }
       CloseLibrary(SocketBase);
    } else {
-      local_csp->active = 0;
+      local_csp->flags &= ~CSP_FLAG_ACTIVE;
       Signal(main_task,SIGF_SINGLE);
    }
    childs--;
    return 0;
 }
 
+static BPTR olddir;
+
 void amiga_exit(void)
 {
    if(SocketBase)
    {
       CloseLibrary(SocketBase);
    }
+   CurrentDir(olddir);
 }
 
 static struct SignalSemaphore memsem;
@@ -114,12 +162,13 @@ void InitAmiga(void)
    InitSemaphore(&memsem);
    memsemptr = &memsem;
 
+   olddir=CurrentDir(GetProgramDir());
    atexit(amiga_exit);
 }
 
 #ifdef __GNUC__
 #ifdef libnix
-/* multitaskingsafe libnix replacements */
+/* multithreadingsafe libnix replacements */
 static void *memPool=NULL;
 
 void *malloc (size_t s)
@@ -228,7 +277,7 @@ ADD2EXIT(__memCleanUp,-50);
 #error No libnix and no ixemul!?
 #endif /* libnix */
 #else
-#error Only GCC is supported, multitasking safe malloc/free required.
+#error Only GCC is supported, multithreading safe malloc/free required.
 #endif /* __GNUC__ */
 
 #endif /* def AMIGA */
diff --git a/amiga.h b/amiga.h
index 6f132d0..580dc32 100644 (file)
--- a/amiga.h
+++ b/amiga.h
@@ -1,15 +1,15 @@
 #ifdef AMIGA
-#ifndef _AMIGA_H
-#define _AMIGA_H
-#define AMIGA_H_VERSION "$Id: amiga.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef AMIGA_H_INCLUDED
+#define AMIGA_H_INCLUDED
+#define AMIGA_H_VERSION "$Id: amiga.h,v 1.8 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/amiga.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/amiga.h,v $
  *
  * Purpose     :  Amiga-specific declarations.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                This program is free software; you can redistribute it 
  *                and/or modify it under the terms of the GNU General
  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
  * Revisions   :
- *    $Log: jcc.h,v $
+ *    $Log: amiga.h,v $
+ *    Revision 1.8  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.7  2002/03/03 09:18:03  joergs
+ *    Made jumbjuster work on AmigaOS again.
+ *
+ *    Revision 1.6  2001/10/13 12:46:08  joergs
+ *    Added #undef EINTR to avoid warnings
+ *
+ *    Revision 1.5  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.4  2001/05/29 20:05:06  joergs
+ *    Fixed exit() macro not exiting if called before InitAmiga()
+ *    (junkbuster --help and --version).
+ *
+ *    Revision 1.3  2001/05/25 21:53:27  jongfoster
+ *    Fixing indentation
+ *
+ *    Revision 1.2  2001/05/23 00:13:58  joergs
+ *    AmigaOS support fixed.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:46  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -43,6 +69,8 @@
 #include <proto/socket.h>
 #undef __NOLIBBASE__
 
+#define __CONSTLIBBASEDECL__ const
+#define DEVICES_TIMER_H
 #include <proto/exec.h>
 #include <exec/tasks.h>
 #include <proto/dos.h>
@@ -50,8 +78,8 @@
 
 struct UserData
 {
-       struct Library *sb;
-       int eno;
+   struct Library *sb;
+   int eno;
 };
 
 #define SocketBase ((struct Library *)(((struct UserData *)(FindTask(NULL)->tc_UserData))->sb))
@@ -67,22 +95,29 @@ void amiga_exit(void);
 void __memCleanUp(void);
 __saveds ULONG server_thread(void);
 
-#define exit(x)\
-{\
-   if(main_task)\
-   {\
-      if(main_task == FindTask(NULL))\
-      {\
-         while(childs) Delay(10*TICKS_PER_SECOND); exit(x);\
-      } else {\
-         CloseLibrary(SocketBase);\
-         childs--;\
-         RemTask(NULL);\
-      }\
-   }\
+#define exit(x)                                             \
+{                                                           \
+   if(main_task)                                            \
+   {                                                        \
+      if(main_task == FindTask(NULL))                       \
+      {                                                     \
+         while(childs) Delay(10*TICKS_PER_SECOND); exit(x); \
+      }                                                     \
+      else                                                  \
+      {                                                     \
+         CloseLibrary(SocketBase);                          \
+         childs--;                                          \
+         RemTask(NULL);                                     \
+      }                                                     \
+   }                                                        \
+   else                                                     \
+   {                                                        \
+      exit(x);                                              \
+   }                                                        \
 }
 
+#undef EINTR
 #define EINTR 0
 
-#endif /* ndef _AMIGA_H */
+#endif /* ndef AMIGA_H_INCLUDED */
 #endif /* def AMIGA */
diff --git a/blocklist b/blocklist
deleted file mode 100644 (file)
index 7b48f3a..0000000
--- a/blocklist
+++ /dev/null
@@ -1,1060 +0,0 @@
-#
-# This is /etc/junkbuster/blocklist which was put here by a junkbuster rpm
-#
-# $Id: blocklist,v 1.3 2000/09/17 07:29:18 swa Exp $
-#
-# Last modified on Mon Sep 25 20:41:50 2000 (CEST)
-#
-# --------------------------------------------------------------------------
-#
-# Newest version is always available from 
-#
-#          http://www.waldherr.org/blocklist 
-#
-# Read http://www.waldherr.org/junkbuster/update.shtml on how to keep
-# this file up-to-date.
-#
-# This list is Copyright (c) Stefan Waldherr <stefan@waldherr.org>.
-#
-# No distribution of this list without acknowledgement of the author(s). 
-# No selling of thist list without prior written agreement.
-#
-# --------------------------------------------------------------------------
-#
-# Contributors are listed in the Hall Of Fame at
-#
-#        http://www.waldherr.org/junkbuster/hof.shtml
-#
-#  PS: I know that there are a ton of redundant regexps in this 
-#      file, but I haven't had time to fix them. Any help 
-#      appreciated.
-#
-# --------------------------------------------------------------------------
-#
-# For more detail, see http://www.junkbusters.com/ht/en/ijbfaq.html#blocking
-#
-# --------------------------------------------------------------------------
-#
-# Empty lines and lines beginning with a `#' are ignored.
-# The following line should be included to block use of telnet (port 23)
-:23
-
-# --------------------------------------------------------------------------
-#
-# generic paths
-#
-# --------------------------------------------------------------------------
-
-/*.*/(.*[-_.])?ads?[0-9]?(/|[-_.].*|\.(gif|jpe?g))
-/*.*/(.*[-_.])?count(er)?(\.cgi|\.dll|\.exe|[?/])
-/*.*/(ng)?adclient\.cgi
-/*.*/(plain|live|rotate)[-_.]?ads?/
-
-/*.*/(sponsor)s?[0-9]?/
-###/*.*/(sponsor|banner)s?[0-9]?/
-###/*.*/.*banner([-_]?[a-z0-9]+)?\.(gif|jpg)
-
-/*.*/_?(plain|live)?ads?(-banners)?/
-/*.*/abanners/
-/*.*/ad(sdna_image|gifs?)/
-/*.*/ad(server|stream|juggler)\.(cgi|pl|dll|exe)
-/*.*/adbanners/
-/*.*/adserver
-/*.*/adstream\.cgi
-/*.*/adv((er)?ts?|ertis(ing|ements?))?/
-/*.*/anzei(gen)?/?
-/*.*/ban[-_]cgi/
-/*.*/banner_?ads/
-/*.*/banner_?anzeigen
-/*.*/bannerimage/
-/*.*/banners?/
-/*.*/banners?\.cgi/
-/*.*/cgi-bin/centralad/getimage
-/*.*/images/addver\.gif
-/*.*/images/advert\.gif
-/*.*/images/marketing/.*\.(gif|jpe?g)
-/*.*/place-ads
-/*.*/popupads/
-/*.*/promobar.*
-/*.*/publicite/
-/*.*/randomads/.*\.(gif|jpe?g)
-/*.*/reklama/.*\.(gif|jpe?g)
-/*.*/reklame/.*\.(gif|jpe?g)
-/*.*/reklaam/.*\.(gif|jpe?g)
-/*.*/siteads/
-/*.*/sponsor.*\.gif
-/*.*/sponsors?[0-9]?/
-/*.*/ucbandeimg/
-/*.*/werb\..*
-/*.*/werbebanner/
-/*.*/werbung/.*\.(gif|jpe?g)
-/.*/adv\.      # www.telegraaf.nl
-/.*/advert[0-9]+\.jpg
-/.*bann\.gif
-/Media/Images/Adds/
-/_banner/
-/ad_images/
-/adgenius/
-/adimages/
-/*.*/ads/
-/*.*/ads\\
-/viewad/
-/adserve/
-/adverts/
-/annonser?/
-/bando/
-/bannerad/
-/bannerfarm/
-/bin/getimage.cgi/...\?AD
-/bin/nph-oma.count/ct/default.shtml
-/bin/nph-oma.count/ix/default.html
-/cgi-bin/getimage.cgi/....\?GROUP=
-/cgi-bin/nph-load
-/cgi-bin/webad.dll/ad
-/cwmail/acc\.gif
-/cwmail/amzn-bm1\.gif
-/db_area/banrgifs/
-/gif/teasere/
-/grafikk/annonse/
-/graphics/defaultAd/
-/grf/annonif
-/htmlad/
-/image\.ng/AdType
-/image\.ng/transactionID
-/images/.*/.*_anim\.gif # alvin brattli
-/ip_img/.*\.(gif|jpe?g)
-/marketpl*/
-/minibanners/
-/netscapeworld/nw-ad/
-/promotions/houseads/
-/rotads/ 
-/rotateads/
-/rotations/ 
-/torget/jobline/.*\.gif
-/viewad/
-/werbung/
-/worldnet/ad\.cgi
-/zhp/auktion/img/
-/cgi-bin/nph-adclick.exe/
-/*.*/Image/BannerAdvertising/
-/*.*/ad-bin/
-/*.*/adlib/server\.cgi
-/*.*/gsa_bs/gsa_bs.cmdl
-/autoads/
-/anz/pics/
-
-# for our finnish friends, by Kai Puolamaki <Kai.Puolamaki@iki.fi>
-/*.*/mainos/*.*/.*\.gif
-/*.*/mainos/*.*/.*\.jpe?g
-
-# more from a finnish friend Petri Haapio <pha@iki.fi>
-cgi.tietovalta.fi
-keltaisetsivut.fi/web/img/\.*gif
-haku.net/pics/pana\.*gif
-www.fi/guvat/\.*gif
-/*.*/(.*[-_.].*)?maino(kset|nta|s).*(/|\.(gif|html?|jpe?g|png))
-/*.*/(ilm(oitus)?|kampanja)(hallinta|kuvat?)(/|\.(gif|html?|jpe?g|png))
-
-# and even more from a finnish friend Hannu Napari <Hannu.Napari@hut.fi>
-194.251.243.50/cgi-bin/banner
-
-www.dime.net/ad
-www.iltalehti.fi/ad
-www.iltalehti.fi/ilmkuvat
-www.mtv3.fi/mainoskuvat
-
-# <jwz@jwz.org>
-/*.*/adfinity
-/*.*/[?]adserv
-/*.*/bizgrphx/
-/*.*/smallad2\.gif
-/*.*/ana2ad\.gif
-/*.*/adimg/
-/*.*/.*counter\.pl
-/*.*/spin_html/
-/*.*/images/topics/topicgimp\.gif
-discovery.com/.*banner_id
-/*.*/.*bannr\.gif
-cruel.com/images/
-idrink.com/frm_bottom.htm
-/*.*/.*pb_ihtml\.gif
-/*.*/ph-ad.*\.focalink\.com
-/cgi-bin/adjuggler
-
-/we_ba/ # hausfrauenseite.de *bwhahahaaaaa*
-
-# ms sucks !
-/.*(ms)?backoff(ice)?.*\.(gif|jpe?g)
-/.*(/ie4|/ie3|msie|sqlbans|powrbybo|activex|backoffice|explorer|netnow|getpoint|ntbutton|hmlink).*\.(gif|jpe?g)
-/.*activex.*(gif|jpe?g)
-/.*explorer?.(gif|jpe?g)
-/.*freeie\.(gif|jpe?g)
-/.*/ie_?(buttonlogo|static?|anim.*)?\.(gif|jpe?g)
-/.*ie_sm\.(gif|jpe?g)
-/.*msie(30)?\.(gif|jpe?g)
-/.*msnlogo\.(gif|jpe?g)
-/.*office97_ad1\.(gif|jpe?g)
-/.*pbbobansm\.(gif|jpe?g)
-/.*powrbybo\.(gif|jpe?g)
-/.*sqlbans\.(gif|jpe?g)
-/.*exc_ms\.gif
-/.*ie4get_animated\.gif
-/.*ie4_animated\.gif
-/.*n_iemap\.gif
-/.*ieget\.gif
-/.*logo_msnhm_*
-/.*mcsp2\.gif
-/.*msn2\.gif
-/.*add_active\.gif
-/.*n_msnmap\.gif
-/.*Ad00\.gif
-/.*s_msn\.gif
-/.*addchannel\.gif
-/.*adddesktop\.gif
-/.*/ns4\.gif
-/.*/v3sban\.gif
-/.*/?FPCreated\.gif
-/.*/opera35\.gif
-/.*/opera13\.gif
-/.*/opera_b\.gif
-/.*/ie_horiz\.gif
-/.*/ie_logo\.gif
-
-# ... and even more!
-/.*/favicon\.ico
-
-# generally useless information and promo stuff (commented out)
-#/*.*/(counter|getpcbutton|BuiltByNOF|netscape|hotmail|vcr(rated)?|rsaci(rated)?|freeloader|cache_now(_anim)?|apache_pb|now_(anim_)?button|ie_?(buttonlogo|static?|.*ani.*)?)\.(gif|jpe?g)
-
-/*.*/images/na/us/brand/
-/*.*/advantage\.(gif|jpg)
-/*.*/advanbar\.(gif|jpg)
-/*.*/advanbtn\.(gif|jpg)
-/*.*/biznetsmall\.(gif|jpg)
-/*.*/utopiad\.(gif|jpg)
-/*.*/epipo\.(gif|jpg)
-/*.*/amazon([a-zA-Z0-9]+)\.(gif|jpg)
-/*.*/bnlogo.(gif|jpg)
-/*.*/buynow([a-zA-Z0-9]+)\.(gif|jpg)
-
-/p/d/publicid
-
-
-# for the dutch folks by a dutch friend gertjan@west.nl
-/*.*/Advertenties/
-/.*./Adverteerders/
-netdirect.nl/nd_servlet/___
-
-# --------------------------------------------------------------------------
-#
-# specific servers
-#
-# --------------------------------------------------------------------------
-
-# the next two lines work 
-12.16.1.10/web_GIF
-12.16.1.10/~web_ani
-193.158.37.3/cgi-bin/impact
-193.210.156.114
-193.98.1.160/img
-194.221.183.222/mailsentlu
-194.221.183.223
-194.221.183.224
-194.221.183.225
-194.221.183.226
-194.221.183.227
-194.231.79.38
-195.124.124.56
-195.27.70.69
-195.30.94.21
-195.63.104.222//inbox
-195.63.104.222//log    # www.weltbild.de
-195.63.104.222//meld
-195.63.104.222//menu
-195.63.104.222/folderlu
-195.63.104.222/folderru
-195.63.104.222/inbox
-195.63.104.222/loginlu
-195.63.104.222/loginmu
-195.63.104.222/loginru
-195.63.104.222/logoutlu
-195.63.104.222/logoutmu
-195.63.104.222/logoutru
-195.63.104.61//inbox
-195.63.104.61//log     # www.weltbild.de
-195.63.104.61//meld
-195.63.104.61//menu
-195.63.104.61/inbox
-195.63.104.61/loginlu
-195.63.104.61/loginmu
-195.63.104.61/loginru
-195.63.104.61/logoutlu
-195.63.104.61/logoutmu
-195.63.104.61/logoutru
-199.78.52.10
-1st-fuss.com
-204.253.46.71:1977
-204.94.67.40/wc/
-205.153.208.93
-205.216.163.62
-205.217.103.58:1977
-206.165.5.162/images/gcanim\.gif
-206.221.254.181:80
-206.50.219.33
-207.137.96.35
-207.159.129.131/abacus
-207.159.135.72
-207.82.250.9
-207.87.15.234
-207.87.27.10/tool/includes/gifs/
-208.156.39.142
-208.156.39.144
-208.156.60.230
-208.156.60.234
-208.156.60.235
-209.1.112.252/adgraph/
-209.1.135.142:1971
-209.1.135.144:1971
-209.132.97.164/IMG/
-209.185.222.45
-209.185.222.60
-209.185.253.199
-209.207.224.220/servfu.pl 
-209.207.224.222/servfu.pl
-209.239.37.214/cgi-pilotfaq/getimage\.cgi
-209.297.224.220
-209.75.21.6
-209.85.89.183/cgi-bin/cycle\?host
-212.63.155.122/(banner|concret|softwareclub)
-216.15.157.34
-216.27.61.150
-216.49.10.236/web1000/
-247media.com
-62.144.115.12/dk/
-ICDirect.com/cgi-bin
-Shannon.Austria.Eu.net/\.cgi/
-WebSiteSponsor.de
-207.181.220.145
-213.165.64.42
-
-#
-# generic hosts (probably most effective)
-#
-ad*.*.*
-ad*.*.*.*
-*.ads.*.*
-banner*.*.*
-banner*.*.*.*
-
-*.admaximize.com
-*.imgis.com
-/*.*/*preferences.com*
-1ad.prolinks.de
-adwisdom.com
-akamaitech.net/.*/Banners/
-altavista.telia.com/av/pix/sponsors/
-amazon.com/g/associates/logos/
-annonce.insite.dk
-asinglesplace.com/asplink\.gif
-athand.com/rotation
-automatiseringgids.nl/gfx/advertenties/
-#avenuea.com/Banners/
-avenuea.com/view/
-badservant.guj.de
-befriends.net/personals/matchmaking\.jpg
-bizad.nikkeibp.co.jp
-bs.gsanet.com/gsa_bs/
-cash-for-clicks.de
-cda.at/customer/
-cgicounter.puretec.de/cgi-bin/
-ciec.org/images/countdown\.gif
-classic.adlink.de/cgi-bin/accipiter/adserver.exe
-click..wisewire.com
-clickhere.egroups.com/img/
-imagine-inc.com
-commonwealth.riddler.com/Commonwealth/bin/statdeploy\?[0-9]+
-customad.cnn.com
-dagbladet.no/ann-gif
-deja.com/jump/
-digits.com/wc/
-dino.mainz.ibm.de
-dn.adzerver.com/image.ad
-ds.austriaonline.at
-emap.admedia.net
-etrade.com/promo/
-eur.yimg.com/a/
-eur.a1.yimg.com/eur.yimg.com/a/
-us.a1.yimg.com/us.yimg.com/a/
-eurosponsor.de
-fastcounter.linkexchange.com
-flycast.com
-focalink.com/SmartBanner
-freepage.de/cgi-bin/feets/freepage_ext/.*/rw_banner
-freespace.virgin.net/andy.drake
-futurecard.com/images/
-gaia.occ.com/click.*
-globaltrack.com
-globaltrak.net
-go.com/cimages\?SEEK_
-gp.dejanews.com/gtplacer
-gtp.dejanews.com/gtplacer
-deja.com/gifs/onsale/
-hitbox.com 
-home.miningco.com/event.ng/.*AdID
-hurra.de
-hyperbanner.net
-icount.com/.*count
-image*.narrative.com/news/.*\.(gif|jpe?g)
-image.click2net.com
-image.linkexchange.com
-images.nytimes.com
-images.yahoo.com/adv/
-images.yahoo.com/promotions/
-imageserv.adtech.de
-img.web.de
-impartner.de/cgi-bin
-informer2.comdirect.de:6004/cd/banner2
-infoseek.go.com/cimages
-ins.at/asp/images/
-kaufwas.com/cgi-bin/zentralbanner\.cgi
-leader.linkexchange.com
-link4ads.com
-link4link.com
-linktrader.com/cgi-bin/
-logiclink.nl/cgi-bin/
-lucky.theonion.com/cgi-bin/oniondirectin\.cgi
-lucky.theonion.com/cgi-bin/onionimp\.cgi
-lucky.theonion.com/cgi-bin/onionimpin\.cgi
-m.doubleclick.net
-mailorderbrides.com/mlbrd2\.gif
-media.priceline.com
-mediaplex.com
-members.sexroulette.com
-messenger.netscape.com
-miningco.com/zadz/
-# movielink became moviefone
-moviefone.com/.*banner
-moviefone.com/.*newbutton
-moviefone.com/.*ad\.gif
-moviefone.com/.*mmail
-moviefone.com/.*poster\.gif
-moviefone.com/.*btyb
-moviefone.com/.*h_guy
-moviefone.com/.*h_showtick
-moviefone.com/.*h_aML
-moviefone.com/.*/m_
-moviefone.com/.*/icon_
-moviefone.com/.*/NF_.*back
-moviefone.com/.*/h_.*gif
-moviefone.com/media/imagelinks
-moviefone.com/media/imagelinks/MF.(ad|sponsor)
-moviefone.com/media/art
-mqgraphics.mapquest.com/graphics/Advertisements/
-netgravity.*
-newads.cmpnet.com
-news.com/cgi-bin/acc_clickthru
-ngadcenter.net
-ngserve.pcworld.com/adgifs/
-nol.at:81
-nrsite.com
-nytsyn.com/gifs
-offers.egroups.com
-pagecount.com
-ph-ad.*\.focalink.com
-preferences.com
-promotions.yahoo.com/
-pub.nomade.fr
-qsound.com/tracker/tracker.exe
-resource-marketing.com/tb/
-revenue.infi.net
-rtl.de/homepage/wb/images/
-schnellsuche.de/images/*
-shout-ads.com/cgibin/shout.php3
-sjmercury.com/advert/
-smartclicks.com/.*/smart(img|banner|host|bar|site)
-smh.com.au/adproof/
-spinbox1.filez.com
-static.wired.com/advertising/
-swiftad.com
-sysdoc.pair.com/cgi-sys/cgiwrap/sysdoc/sponsor\.gif
-t-online.de/home/040255162-001/*
-taz.de/taz/anz/
-tcsads.tcs.co.at
-teleauskunft.de/commercial/
-thecounter.com/id
-tm.intervu.net
-tvguide.com/rbitmaps/
-ubl.com/graphics/
-ubl.com/images/
-ultra.multimania.com
-ultra1.socomm.net
-uproar.com
-us.yimg.com/a/
-us.yimg.com/promotions/
-valueclick.com
-valueclick.net
-victory.cnn.com
-videoserver.kpix.com
-washingtonpost.com/wp-adv/
-webconnect.net/cgi-bin/webconnect.dll
-webcounter.goweb.de
-webserv.vnunet.com/ip_img/.*ban
-werbung.pro-sieben.de/cgi-bin
-whatis.com/cgi-bin/getimage.exe/
-www..bigyellow.com/......mat.*
-www.adclub.net
-www.addme.com/link8\.gif
-www.aftonbladet.se/annons
-www.americanpassage.com/
-www.angelfire.com/in/twistriot/images/wish4\.gif
-www.bizlink.ru/cgi-bin/irads\.cgi
-www.blacklightmedia.com/adlemur
-www.bluesnews.com/flameq\.gif
-www.bluesnews.com/images/ad[0-9]+\.gif
-www.bluesnews.com/images/gcanim3\.gif
-www.bluesnews.com/images/throbber2\.gif
-www.bluesnews.com/miscimages/fragbutton\.gif
-www.businessweek.com/sponsors/
-www.canoe.ca/AdsCanoe/
-www.cdnow.com/MN/client.banners
-www.clickagents.com
-www.clickthrough.ca
-www.clicmoi.com/cgi-bin/pub\.exe
-www.dailycal.org/graphics/adbanner-ab\.gif
-www.detelefoongids.com/pic/[0-9]*
-www.dhd.de/CGI/werbepic
-www.dsf.de/cgi-bin/site_newiac.adpos
-www.firsttarget.com/cgi-bin/klicklog.cgi
-www.forbes.com/forbes/gifs/ads
-www.forbes.com/tool/includes/gifs/
-www.fxweb.holowww.com/.*\.cgi
-www.geocities.com/TimesSquare/Zone/5267/
-www.goto.com/images-promoters/
-www.handelsblatt.de/hbad
-www.hotlinks.de/cgi-bin/barimage\.cgi
-www.infoseek.com/cimages
-www.infoworld.com/pageone/gif
-www.isys.net/customer/images
-www.javaworld.com/javaworld/jw-ad
-www.kron.com/place-ads/
-www.leo.org/leoclick/
-www.linkexchange.ru/cgi-bin/erle\.cgi
-www.linkstation.de/cgi-bin/zeige
-www.linux.org/graphic/miniature/
-www.linux.org/graphic/square/
-www.linux.org/graphic/standard/
-www.luncha.se/annonsering
-www.mediashower.com
-www.ml.org/gfx/spon/icom/
-www.ml.org/gfx/spon/wmv
-www.musicblvd.com/mb2/graphics/netgravity/
-nedstat.nl/cgi-bin/
-www.news.com/Midas/Images/
-www.newscientist.com/houseads
-www.nextcard.com/affiliates/
-www.nikkeibp.asiabiztech.com/image/NAIS4\.gif
-www.nordlys.no/imaker/.*/.*/.*/.....\.gif      # alvin brattli
-www.nordlys.no/imaker/.*/.*/.*/..003           # alvin brattli
-www.oanda.com/server/banner
-omdispatch.co.uk
-www.oneandonlynetwork.com
-www.page2page.de/cgi-bin/
-www.prnet.de/.*/bannerschnippel/.*\.(gif|jpe?g)
-www.promptsoftware.com/marketing/
-#www.reklama.ru/cgi-bin/banners/
-www.riddler.com/sponsors/
-www.rle.ru/cgi-bin/erle\.cgi
-www.rock.com/images/affiliates/search_black\.gif
-www.rtl.de/search/.*kunde
-#www.search.com/Banners
-www.sfgate.com/place-ads/
-www.shareware.com/midas/images/borders-btn\.gif
-#www.sjmercury.com/products/marcom/banners/
-www.smartclicks.com:81
-www.sol.dk/graphics/portalmenu
-www.sponsornetz.de/jump/show.exe
-www.sponsorpool.net
-www.sunworld.com/sunworldonline/icons/adinfo.sm\.gif
-www.swwwap.com/cgi-bin/
-www.taz.de/~taz/anz/
-www.telecom.at/icons/.*film\.(gif|jpe?g)
-www.theonion.com/bin/
-www.topsponsor.de/cgi-bin/show.exe
-www.ugo.net
-www.ugu.com/images/EJ\.gif
-www.warzone.com/pics/banner/
-www.warzone.com/wzfb/ads.cgi
-www.webpeep.com
-www.websitepromote.com/partner/img/
-www.winjey.com/onlinewerbung/*\.gif
-www.wishing.com/webaudit
-www.www-pool.de/cgi-bin/banner-pool
-www2.blol.com/agrJRU\.gif
-www3.exn.net:80
-yahoo.com/CategoryID=0
-yahoo.de/adv/images
-~cpan.valueclick.com
-~www.hitbox.com
-
-#swa
-www.bannerland.de/click.exe
-*.cyberclick.net
-*.eu-adcenter.net/
-www.web-stat.com
-www.slate.com/snav/
-www.slate.com/redirect/
-www.slate.com/articleimages/
-usads.imdb.com
-www.forbes.com/tool/images/frontend/
-www.zserver.com
-www.spinbox.com
-pathfinder.com/shopping/marketplace/images/
-/*.*/adbanner*
-/*.*/adgraphic*
-static.wired.com/images
-perso.estat.com/cgi-bin/perso/
-dinoadserver1.roka.net
-fooladclient*.fool.com
-affiliate.aol.com/static/
-cybereps.com:8000
-iadnet.com
-orientserve.com
-wvolante.com
-findcommerce.com
-smartage.com
-
-# www.sunday-times.co.uk
-www.sunday-times.co.uk/standing/newsint/ticker
-
-# Für Germany.Net-User: Germany.Net (fast) banner- u. grafikfrei!
-germany.net/gebu-frei\.gif
-germany.net/bilder/menue/leiste\.gif
-germany.net/bilder/gn_logos/*
-germany.net/bilder/90x90/*
-germany.net/banner-homepage/*
-germany.net/downloadshop/*
-germany.net/bilder/action/promopoly/germanynet/basisdienste/hilfe/*
-
-# Block as much of GeoCities as possible
-# All geocities-owned images
-www.geocities.com/images
-www.geocities.com/MemberBanners/live/
-pic.geocities.com/images
-# And the popup (it still pops up, but does not eat up precious bandwidth)
-#www.geocities.com/ad_container/pop.html # already fixed by other regexp
-
-# from corion@informatik.uni-frankfurt.de
-sam.songline.com/@
-img.getstats.com/
-#ads.xmonitor.net/xadengine.cgi # fixed by above regexp
-# Also block the japanese geocities popups
-www.geocities.co.jp/images
-# Also block the come.to, surf.to etc. popups
-v3.come.to/pop.asp
-
-# Also block the xoom stuff.
-xb.xoom.com
-home.talkcity.com/homepopup.html.*
-
-# Max Maischein <max.maischein@econsult.de> again ...
-# Halflife.net uses WON banners
-# Banners from Freeserve
-#banner.freeservers.com/cgi-bin/fs_adbar # fixed by above regexp
-# And those nasty va-popups !
-/.*/?va_banner.html
-# And an all-around hit against advert*.jpg
-/.*/advert[0-9]+\.jpg
-# And yet another Internet Explorer gif ...
-/.*/ie_horiz\.gif
-# Some uninteresting buttons I think...
-mircx.com/images/buttons/
-services.mircx.com/.*\.gif
-# Ooops - UserFriendly (Iambe) has a banner that gets eaten ...
-~www.userfriendly.org/images/banners/banner_dp_heart\.gif
-# Easyspace - yet another "free disk space" provider with <yuck> banner popups
-www.easyspace.com/(fpub)?banner.html
-www.easyspace.com/100\.gif
-# Some russian banner exchanges
-banner.ricor.ru/cgi-bin/banner.pl
-#www.bizlink.ru/cgi-bin/irads.cgi # already fixed by other regexp
-stx9.sextracker.com/stx/send/
-# And even more of geocities :
-www.geocities.com/pictures/
-# Gaah - www.angelfire.com - another webspace provider with popups
-angelfire.com/sys/download.html
-# Gamasutra.com uses this ad provider
-sally.songline.com/@
-
-# Eule.de (search engine)
-# maybe images.eule.de as a whole...
-www.eule.de/cgi-bin/
-images.eule.de/comdirect\.gif 
-images.eule.de/wp\.gif
-aladin.de/125_1\.gif
-images.eule.de/neu/books\.gif
-
-# --------------------------------------------------------------------------
-#
-# some images
-#
-# --------------------------------------------------------------------------
-
-# some images on cnn's website just suck!
-/.*cnnstore\.gif
-/.*book.search\.gif
-/.*cnnpostopinionhome.\.gif
-/.*custom_feature\.gif
-/.*explore.anim.*gif
-/.*infoseek\.gif
-/.*pathnet.warner\.gif
-/.*images/cnnfn_infoseek\.gif
-/.*images/pathfinder_btn2\.gif
-/.*img/gen/fosz_front_em_abc\.gif
-/.*img/promos/bnsearch\.gif
-/.*navbars/nav_partner_logos\.gif
-/BarnesandNoble/images/bn.recommend.box.*
-/digitaljam/images/digital_ban\.gif
-/hotstories/companies/images/companies_banner\.gif
-/markets/images/markets_banner\.gif
-/ows-img/bnoble\.gif
-/ows-img/nb_Infoseek\.gif
-cnn.com/images/custom/totale\.gif
-cnn.com/images/lotd/custom.wheels\.gif
-cnn.com/images/.*/by/main.12\.gif
-cnn.com/images/.*/find115\.gif
-cnn.com/.*/free.email.120\.gif
-cnnfn.com/images/left_banner\.gif
-focus.de/A/AF/AFL/
-www.cnn.com/images/.*/bn/books\.gif
-www.cnn.com/images/.*/pointcast\.gif
-www.cnn.com/images/.*/fusa\.gif
-cnn.com/images/.*/start120\.gif
-images.cnn.com/SHOP/
-/.*by/main\.gif
-/.*gutter117\.gif
-/.*barnes_logo\.gif
-# the / indicates the beginning of the path (and no longer the FQDN)
-/.*nbclogo\.gif
-/.*microdell\.gif
-/.*secureit\.gif
-
-g.deja.com/gifs/(q|us)west_120x120\.gif
-
-#
-/gif/buttons/banner_.*
-/gif/buttons/cd_shop_.*
-/gif/cd_shop/cd_shop_ani_.*
-
-#altavista
-/av/gifs/av_map\.gif
-/av/gifs/av_logo\.gif
-/av/gifs/new/ns\.gif
-altavista.com/i/valsdc3\.gif
-jump.altavista.com/gn_sf
-
-# tucows
-tucows.*.*/images/locallogo\.gif
-#tucows.dsuper.net/images/locallogo\.gif
-
-#
-mt_freshmeat\.jpg
-
-# simpliemu.hypermart.net/frames.html
-go2net.com/mgic/adpopup
-go2net.com/metaspy/images/exposed\.gif
-go2net.com/metaspy/images/ms_un\.gif
-
-#
-www.cebu-usa.com/cwbanim1\.gif
-www.cebu-usa.com/Connection\.jpg
-www.cebu-usa.com/phonead\.gif
-www.cebu-usa.com/ban3\.jpg
-www.cebu-usa.com/tlban\.gif
-www.cebu-usa.com/apwlogo1\.gif
-www.cebu-usa.com/rose\.gif
-
-# fnet
-www.fnet.de/img/geldboerselogo\.jpg
-
-# hirsch@mathcs.emory.edu
-/images/getareal2\.gif
-
-www.assalom.com/aziza/logos/cniaffil\.gif
-www.assalom.com/aziza/logos/4starrl1\.gif
-www.phantomstar.com/images/media/m1\.gif
-
-#
-wahlstreet.de/MediaW\$/tsponline\.gif
-wahlstreet.de/MediaW\$/dzii156x60\.gif
-wahlstreet.de/MediaW\$/etban156x60_2_opt2\.gif
-
-# linuxtoday.com
-/pics/gotlx1\.gif
-/pics/getareal1\.gif
-/pics/amzn-b5\.gif
-/ltbs/cgi-bin/click.cgi
-linuxtoday.com/ltbs/pics/
-
-# Geocities popups
-/ad[-_]container/
-/include/watermark/v2/
-
-# Reinier Bikker <R.P.Bikker@phys.uu.nl>
-# Banner.xxLINK.nl/
-
-# Mark Lutz <luma@nikocity.de>
-/.*/*werb.*\.(gif|jpe?g) # hope that's not to restrictive
-
-#Free Yellow thing at bottom of pages (HereticPC)
-www.freeyellow.com/images/powerlink5a\.gif
-www.freeyellow.com/images/powerlink5b\.gif
-www.freeyellow.com/images/powerlink5c\.gif
-www.freeyellow.com/images/powerlink5d\.gif
-www.freeyellow.com/images/powerlink5e\.gif
-
-#HereticPC
-www.eads.com/images/refbutton\.gif
-www.fortunecity.com/console2/newnav/*
-www.goldetc.net/search\.gif
-www.cris.com/~Lzrdking/carpix/cars3-le\.gif
-www.justfreestuff.com/scott\.gif
-www.cyberthrill.com/entrance\.gif
-secure.pec.net/images/pec69ani\.gif
-www.new-direction.com/avviva\.gif
-internetmarketingcenter\.gif
-www.new-direction.com/wp-linkexchange-loop\.gif
-www.new-direction.com/windough\.gif
-www.digitalwork.com/universal_images/affiliate/dw_le_3\.gif
-service.bfast.com/bfast/click/*
-www.new-direction.com/magiclearning\.gif
-www.new-direction.com/mailloop\.gif
-
-www.free-banners.com/images/hitslogo\.gif
-rob.simplenet.com/dyndns/fortune5\.gif
-nasdaq-amex.com/images/bn_ticker\.gif
-
-#
-# navilor@hotmail.com
-#
-#
-# wayne@staff.msen.com
-#
-a*.*.*.yimg.com/([0-9]*|\/)*us.yimg.com/*
-ad.doubleclick.net
-www.dnps.com/ads
-www.realtop50.com/cgi-bin/ad
-~a*.*.*.yimg.com/([0-9]|\/)*us.yimg.com/i/*
-
-#
-www.yacht.de/images/(my_ani|eissingani|chartertrans|fum|schnupper|fysshop|garmin)\.gif
-www.sponsorweb.de/web-sponsor/nt-bin/show.exe
-
-#
-# Club-internet pops up a complain if you refuse cookie (still pops up...)
-perso.club-internet.fr/html/Popup/popup_frame_nocookie.html
-perso.club-internet.fr/pagesperso/popup_nocookie.html
-
-gmx.net/images/newsbanner/
-cash4banner.de
-
-quicken.lexware.de/images/us7-468x60.gif
-/img/special/chatpromo\.gif
-www.travelocity.com/images/promos/
-
-# wonder that that does...
-p01.com/1x1.dyn
-
-/*.*/phpAds/viewbanner.php
-/*.*/phpAds/phpads.php
-
-www.linux-magazin.de/banner    
-comtrack.comclick.com
-click-fr.com
-iac-online.de/filler
-
-media.interadnet.com
-stat.www.fi/cgi-bin
-/cgi/banners.cgi
-ads-digi.sol.no
-fp.buy.com
-disneystoreaffiliates.com
-
-powerwork.mobile.de/cgi-bin/getimage\.cgi
-
-
-
-####################################################
-# Jon's addition:
-#
-# Register ads
-#www.theregister.co.uk/media/155\.gif
-www.theregister.dealtime.co.uk/BannerIn/
-#www.theregister.co.uk/media/SearchDomainRed\.gif
-#www.theregister.co.uk/media/ByDomainbusterRed\.gif
-#www.theregister.co.uk/media/454\.gif
-#www.theregister.co.uk/media/461\.gif
-#www.theregister.co.uk/media/dealtime-lh\.gif
-# Ad target:
-www.domainbuster.com/cgi-bin/domainbuster/dpro\.pl
-
-#www.theregister.co.uk/media/.*\.swf
-#www.theregister.co.uk/media/.*\.js
-
-# get agressive:
-www.theregister.co.uk/media/
-
-# Dilbert:
-www.dilbert.com/comics/dilbert/images/.*_140x800.*\.gif
-
-# stattrack.com
-# Uses URL: http://www.stattrack.com/cgi-bin/stats/image.cgi
-/cgi-bin/stats/
-# And loads JavaScript from http://www.stattrack.com/stats/code
-www.stattrack.com/stats/
-
-#GeoCities crap
-##geo.yahoo.com/serv
-##visit.geocities.com/visit.gif
-*.*.*.yimg.com/*/www.geocities.com/js_source
-#http://us.toto.geo.yahoo.com/toto?s=76001086
-##*.toto.geo.yahoo.com
-
-# Nuke GeoCities rubbish
-*.*.geo.yahoo.com
-*.geo.yahoo.com
-geo.yahoo.com
-visit.geocities.com
-*.*.*.yimg.com/.*/www.geocities.com/
-
-#http://counter16.bravenet.com/counter.php
-counter*.*.*
-
-#http://stat.cybermonitor.com/7emezone_p?1707_USdvd
-stat*.*.*
-
-#http://members.tripod.com/adm/popup/.....
-members.tripod.com/adm/popup/
-
-#This is the worst ad idea ever!  Bye bye!
-#count.exitexchange.com/exit/1100661
-#count.exitexchange.com/clients/navbar.html
-#(used in http://skyhivisuals.tripod.com/malfunctions_.htm)
-exitexchange.com
-
-#SourceForge ads.
-sfads.osdn.com
-
-#Crap trapping sites
-webhideout.com
-
-####################################################
-
-
-
-#
-# some regexps are simply too aggressive ...
-#
-# equalizer to /*.*(.*[-_.])?ads?[0-9]?(/|[-_.].*|.(gif|jpe?g)) 
-# or other regexps
-#
-#
-~adamwhone.co.uk
-~adsl.tin.it
-~stsci.edu
-~tgs.com
-~sun.com
-~povray.org
-~admin.*.*
-~admin.*.*.*
-~ad.siemens.de             # SIEMENS Automation & Drives
-~add-url.altavista.com
-~adis.on.ca
-~address*.*.*
-~address*.*.*.*
-~add*.*.*
-~add*.*.*.*
-~adu*.*.*
-~adu*.*.*.*
-~advice.*.*
-~advice.*.*.*
-
-# univ. don't advertise, do they :-)
-~*.*.edu
-~*.*.*.edu
-~www.ugu.com/sui/ugu/adv
-~adfa.edu.au
-~adsl*.*.*
-
-~clubs.yahoo.com/clubs
-~edit.my.yahoo.com/config/show_identity
-~www.ix.de/newsticker/data/ad
-~www.heise.de/newsticker/data/ad
-~www.careernet.de/anzeige
-~www.careernet.de/bewerber/stellenanzeigen
-~www.baumgartner.de/stellenmarkt/anzeigen
-~www.dspartner.de/Anzeigen
-~www.aws-jobs.de/Anzeigen
-~www.jobware.de/.*/anzeigen/
-~www.jobworld.de/bilder/
-~www.cnn.com/TECH/computing/.*/internet.ads/
-~www.financial.de/shop/
-~gnn.de/.*\.html
-~www.auktionen.de
-
-~194.221.152.2/phptelefontmp
-~harvard.edu/images/banner/
-
-~adswww.harvard.edu
-~www.dhd.de/CGI/anzeigen/
-
-~ads.web.de/web/
-~img.web.de/web/img/
-
-~www.segel.de/menu/bilder/anzeigen\.gif
-~www.corel.com/graphics/banners/
-~www.software.ibm.com/ad/
-~www.omg.org/docs/ad/
-
-~sperrmuell.de/scripts/anzeigen
-www.freenet.de/index.html
-www.01019freenet.de/index.html
-~www.freenet.de/freenet/
-~www.01019freenet.de/freenet/
-~webfactory.de/anzeigen.php
-~www.cdmag.com
-~www.internatif.org/bortzmeyer/debian/sponsor/
-~hp.com
-
-~www.software.hosting.ibm.com/ad/
-~www.ibm.com/software/ad/
-~brickshelf.com
-
-~www.debian.org/Pics/banner-blue\.gif
-~www.linux.de/pics/Nachrichten_banner\.gif
-~www.werbekurier.de
-
-~finder.shopping.yahoo.com/shop/
-~national.com/pf
-~mozilla.org
-~eidos.de
-~e-sheep.com
-~punkassgear.com
-~mozilla.org
-~mozillazine.org
-~adbusters.org
-~annoy.com
-~consumer-direct.com
-~www.iez-auktion.de
-~ibm.com
-~sgi.com
-
-# my banking stuff => no ads. last regexp for fast access :-)
-~comdirekt.de
-~comdirect.de
-~teledata.de
-
-
-~msdn.microsoft.com
-
-# do not forget newline at the end of this file!!!
-
diff --git a/cgi.c b/cgi.c
new file mode 100644 (file)
index 0000000..4a523b2
--- /dev/null
+++ b/cgi.c
@@ -0,0 +1,2166 @@
+const char cgi_rcs[] = "$Id: cgi.c,v 1.69 2002/05/14 21:28:40 oes Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/cgi.c,v $
+ *
+ * Purpose     :  Declares functions to intercept request, generate
+ *                html or gif answers, and to compose HTTP resonses.
+ *                This only contains the framework functions, the
+ *                actual handler functions are declared elsewhere.
+ *                
+ *                Functions declared include:
+ * 
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: cgi.c,v $
+ *    Revision 1.69  2002/05/14 21:28:40  oes
+ *     - Fixed add_help_link to link to the (now split) actions
+ *       part of the config chapter
+ *     - Renamed helplink export to actions-help-prefix
+ *
+ *    Revision 1.68  2002/05/12 21:36:29  jongfoster
+ *    Correcting function comments
+ *
+ *    Revision 1.67  2002/04/30 12:02:07  oes
+ *    Nit: updated a comment
+ *
+ *    Revision 1.66  2002/04/26 18:32:57  jongfoster
+ *    Fixing a memory leak on error
+ *
+ *    Revision 1.65  2002/04/26 12:53:51  oes
+ *     - New function add_help_link
+ *     - default_exports now exports links to the user manual
+ *       and a prefix for links into the config chapter
+ *
+ *    Revision 1.64  2002/04/24 02:17:21  oes
+ *     - Better descriptions for CGIs
+ *     - Hide edit-actions, more shortcuts
+ *     - Moved get_char_param, get_string_param and get_number_param here
+ *       from cgiedit.c
+ *
+ *    Revision 1.63  2002/04/15 19:06:43  jongfoster
+ *    Typos
+ *
+ *    Revision 1.62  2002/04/10 19:59:46  jongfoster
+ *    Fixes to #include in templates:
+ *    - Didn't close main file if loading an included template fails.
+ *    - I'm paranoid and want to disallow "#include /etc/passwd".
+ *
+ *    Revision 1.61  2002/04/10 13:37:48  oes
+ *    Made templates modular: template_load now recursive with max depth 1
+ *
+ *    Revision 1.60  2002/04/08 20:50:25  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.59  2002/04/05 15:51:51  oes
+ *     - added send-stylesheet CGI
+ *     - bugfix: error-pages now get correct request protocol
+ *     - fixed
+ *     - kludged CGI descriptions and menu not to break JS syntax
+ *
+ *    Revision 1.58  2002/03/29 03:33:13  david__schmidt
+ *    Fix Mac OSX compiler warnings
+ *
+ *    Revision 1.57  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.56  2002/03/24 17:50:46  jongfoster
+ *    Fixing compile error if actions file editor disabled
+ *
+ *    Revision 1.55  2002/03/24 16:55:06  oes
+ *    Making GIF checkerboard transparent
+ *
+ *    Revision 1.54  2002/03/24 16:18:15  jongfoster
+ *    Removing old logo
+ *
+ *    Revision 1.53  2002/03/24 16:06:00  oes
+ *    Correct transparency for checkerboard PNG. Thanks, Magnus!
+ *
+ *    Revision 1.52  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.51  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.50  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.49  2002/03/13 00:27:04  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.48  2002/03/08 17:47:07  jongfoster
+ *    Adding comments
+ *
+ *    Revision 1.47  2002/03/08 16:41:33  oes
+ *    Added GIF images again
+ *
+ *    Revision 1.46  2002/03/07 03:48:38  oes
+ *     - Changed built-in images from GIF to PNG
+ *       (with regard to Unisys patent issue)
+ *     - Added a 4x4 pattern PNG which is less intrusive
+ *       than the logo but also clearly marks the deleted banners
+ *
+ *    Revision 1.45  2002/03/06 22:54:35  jongfoster
+ *    Automated function-comment nitpicking.
+ *
+ *    Revision 1.44  2002/03/05 22:43:45  david__schmidt
+ *    - Better error reporting on OS/2
+ *    - Fix double-slash comment (oops)
+ *
+ *    Revision 1.43  2002/03/05 21:33:45  david__schmidt
+ *    - Re-enable OS/2 building after new parms were added
+ *    - Fix false out of memory report when resolving CGI templates when no IP
+ *      address is available of failed attempt (a la no such domain)
+ *
+ *    Revision 1.42  2002/01/21 00:33:20  jongfoster
+ *    Replacing strsav() with the safer string_append() or string_join().
+ *    Adding map_block_keep() to save a few bytes in the edit-actions-list HTML.
+ *    Adding missing html_encode() to error message generators.
+ *    Adding edit-actions-section-swap and many "shortcuts" to the list of CGIs.
+ *
+ *    Revision 1.41  2002/01/17 20:56:22  jongfoster
+ *    Replacing hard references to the URL of the config interface
+ *    with #defines from project.h
+ *
+ *    Revision 1.40  2002/01/09 14:26:46  oes
+ *    Added support for thread-safe gmtime_r call.
+ *
+ *    Revision 1.39  2001/11/16 00:48:13  jongfoster
+ *    Fixing a compiler warning
+ *
+ *    Revision 1.38  2001/11/13 00:31:21  jongfoster
+ *    - Adding new CGIs for use by non-JavaScript browsers:
+ *        edit-actions-url-form
+ *        edit-actions-add-url-form
+ *        edit-actions-remove-url-form
+ *    - Fixing make_menu()'s HTML generation - it now quotes the href parameter.
+ *    - Fixing || bug.
+ *
+ *    Revision 1.37  2001/11/01 14:28:47  david__schmidt
+ *    Show enablement/disablement status in almost all templates.
+ *    There is a little trickiness here: apparent recursive resolution of
+ *    @if-enabled-then@ caused the toggle template to show status out-of-phase with
+ *    the actual enablement status.  So a similar construct,
+ *    @if-enabled-display-then@, is used to resolve the status display on non-'toggle'
+ *    templates.
+ *
+ *    Revision 1.36  2001/10/26 17:33:27  oes
+ *    marginal bugfix
+ *
+ *    Revision 1.35  2001/10/23 21:48:19  jongfoster
+ *    Cleaning up error handling in CGI functions - they now send back
+ *    a HTML error page and should never cause a FATAL error.  (Fixes one
+ *    potential source of "denial of service" attacks).
+ *
+ *    CGI actions file editor that works and is actually useful.
+ *
+ *    Ability to toggle Junkbuster remotely using a CGI call.
+ *
+ *    You can turn off both the above features in the main configuration
+ *    file, e.g. if you are running a multi-user proxy.
+ *
+ *    Revision 1.34  2001/10/18 22:22:09  david__schmidt
+ *    Only show "Local support" on templates conditionally:
+ *      - if either 'admin-address' or 'proxy-info-url' are uncommented in config
+ *      - if not, no Local support section appears
+ *
+ *    Revision 1.33  2001/10/14 22:28:41  jongfoster
+ *    Fixing stupid typo.
+ *
+ *    Revision 1.32  2001/10/14 22:20:18  jongfoster
+ *    - Changes to CGI dispatching method to match CGI names exactly,
+ *      rather than doing a prefix match.
+ *    - No longer need to count the length of the CGI handler names by hand.
+ *    - Adding new handler for 404 error when disptching a CGI, if none of
+ *      the handlers match.
+ *    - Adding new handlers for CGI actionsfile editor.
+ *
+ *    Revision 1.31  2001/10/10 10:56:39  oes
+ *    Failiure to load template now fatal. Before, the user got a hard-to-understand assertion failure from cgi.c
+ *
+ *    Revision 1.30  2001/10/02 15:30:57  oes
+ *    Introduced show-request cgi
+ *
+ *    Revision 1.29  2001/09/20 15:47:44  steudten
+ *
+ *    Fix BUG: Modify int size to size_t size in fill_template()
+ *     - removes big trouble on machines where sizeof(int) != sizeof(size_t).
+ *
+ *    Revision 1.28  2001/09/19 18:00:37  oes
+ *     - Deletef time() FIXME (Can't fail under Linux either, if
+ *       the argument is guaranteed to be in out address space,
+ *       which it is.)
+ *     - Fixed comments
+ *     - Pointer notation cosmetics
+ *     - Fixed a minor bug in template_fill(): Failiure of
+ *       pcrs_execute() now secure.
+ *
+ *    Revision 1.27  2001/09/16 17:08:54  jongfoster
+ *    Moving simple CGI functions from cgi.c to new file cgisimple.c
+ *
+ *    Revision 1.26  2001/09/16 15:47:37  jongfoster
+ *    First version of CGI-based edit interface.  This is very much a
+ *    work-in-progress, and you can't actually use it to edit anything
+ *    yet.  You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
+ *    to have any effect.
+ *
+ *    Revision 1.25  2001/09/16 15:02:35  jongfoster
+ *    Adding i.j.b/robots.txt.
+ *    Inlining add_stats() since it's only ever called from one place.
+ *
+ *    Revision 1.24  2001/09/16 11:38:01  jongfoster
+ *    Splitting fill_template() into 2 functions:
+ *    template_load() loads the file
+ *    template_fill() performs the PCRS regexps.
+ *    This is because the CGI edit interface has a "table row"
+ *    template which is used many times in the page - this
+ *    change means it's only loaded from disk once.
+ *
+ *    Revision 1.23  2001/09/16 11:16:05  jongfoster
+ *    Better error handling in dispatch_cgi() and parse_cgi_parameters()
+ *
+ *    Revision 1.22  2001/09/16 11:00:10  jongfoster
+ *    New function alloc_http_response, for symmetry with free_http_response
+ *
+ *    Revision 1.21  2001/09/13 23:53:03  jongfoster
+ *    Support for both static and dynamically generated CGI pages.
+ *    Correctly setting Last-Modified: and Expires: HTTP headers.
+ *
+ *    Revision 1.20  2001/09/13 23:40:36  jongfoster
+ *    (Cosmetic only) Indentation correction
+ *
+ *    Revision 1.19  2001/09/13 23:31:25  jongfoster
+ *    Moving image data to cgi.c rather than cgi.h.
+ *
+ *    Revision 1.18  2001/08/05 16:06:20  jongfoster
+ *    Modifiying "struct map" so that there are now separate header and
+ *    "map_entry" structures.  This means that functions which modify a
+ *    map no longer need to return a pointer to the modified map.
+ *    Also, it no longer reverses the order of the entries (which may be
+ *    important with some advanced template substitutions).
+ *
+ *    Revision 1.17  2001/08/05 15:57:38  oes
+ *    Adapted finish_http_response to new list_to_text
+ *
+ *    Revision 1.16  2001/08/01 21:33:18  jongfoster
+ *    Changes to fill_template() that reduce memory usage without having
+ *    an impact on performance.  I also renamed some variables so as not
+ *    to clash with the C++ keywords "new" and "template".
+ *
+ *    Revision 1.15  2001/08/01 21:19:22  jongfoster
+ *    Moving file version information to a separate CGI page.
+ *
+ *    Revision 1.14  2001/08/01 00:19:03  jongfoster
+ *    New function: map_conditional() for an if-then-else syntax.
+ *    Changing to use new version of show_defines()
+ *
+ *    Revision 1.13  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.12  2001/07/29 18:47:05  jongfoster
+ *    Adding missing #include "loadcfg.h"
+ *
+ *    Revision 1.11  2001/07/18 17:24:37  oes
+ *    Changed to conform to new pcrs interface
+ *
+ *    Revision 1.10  2001/07/13 13:53:13  oes
+ *    Removed all #ifdef PCRS and related code
+ *
+ *    Revision 1.9  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.8  2001/06/29 13:21:46  oes
+ *    - Cosmetics: renamed and reordered functions, variables,
+ *      texts, improved comments  etc
+ *
+ *    - Removed ij_untrusted_url() The relevant
+ *      info is now part of the "untrusted" page,
+ *      which is generated by filters.c:trust_url()
+ *
+ *    - Generators of content now call finish_http_response()
+ *      themselves, making jcc.c:chat() a little less
+ *      cluttered
+ *
+ *    - Removed obsolete "Pragma: no-cache" from our headers
+ *
+ *    - http_responses now know their head length
+ *
+ *    - fill_template now uses the new interface to pcrs, so that
+ *       - long jobs (like whole files) no longer have to be assembled
+ *         in a fixed size buffer
+ *       - the new T (trivial) option is used, and the replacement may
+ *         contain Perl syntax backrefs without confusing pcrs
+ *
+ *    - Introduced default_exports() which generates a set of exports
+ *      common to all CGIs and other content generators
+ *
+ *    - Introduced convenience function map_block_killer()
+ *
+ *    - Introduced convenience function make_menu()
+ *
+ *    - Introduced CGI-like function error_response() which generates
+ *      the "No such domain" and "Connect failed" messages using the
+ *      CGI platform
+ *
+ *    - cgi_show_url_info:
+ *      - adapted to new CGI features
+ *      - form and answers now generated from same template
+ *      - http:// prefix in URL now OK
+ *
+ *    - cgi_show_status:
+ *      - adapted to new CGI features
+ *      - no longer uses csp->init_proxy_args
+ *
+ *    - cgi_default:
+ *      - moved menu generation to make_menu()
+ *
+ *    - add_stats now writes single export map entries instead
+ *      of a fixed string
+ *
+ *    - Moved redirect_url() to filters.c
+ *
+ *    - Fixed mem leak in free_http_response(), map_block_killer(),
+ *
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.7  2001/06/09 10:51:58  jongfoster
+ *    Changing "show URL info" handler to new style.
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.6  2001/06/07 23:05:19  jongfoster
+ *    Removing code related to old forward and ACL files.
+ *
+ *    Revision 1.5  2001/06/05 19:59:16  jongfoster
+ *    Fixing multiline character string (a GCC-only "feature"), and snprintf (it's _snprintf under VC++).
+ *
+ *    Revision 1.4  2001/06/04 10:41:52  swa
+ *    show version string of cgi.h and cgi.c
+ *
+ *    Revision 1.3  2001/06/03 19:12:16  oes
+ *    introduced new cgi handling
+ *
+ *    No revisions before 1.3
+ *
+ **********************************************************************/
+\f
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#endif /* def _WIN32 */
+
+#include "project.h"
+#include "cgi.h"
+#include "list.h"
+#include "encode.h"
+#include "ssplit.h"
+#include "errlog.h"
+#include "miscutil.h"
+#include "cgisimple.h"
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+#include "cgiedit.h"
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
+#include "loadcfg.h"
+/* loadcfg.h is for g_bToggleIJB only */
+
+const char cgi_h_rcs[] = CGI_H_VERSION;
+
+/*
+ * List of CGI functions: name, handler, description
+ * Note: Do NOT use single quotes in the description;
+ *       this will break the dynamic "blocked" template!
+ */
+static const struct cgi_dispatcher cgi_dispatchers[] = {
+   { "",
+         cgi_default,
+         "Privoxy main page" },
+#ifdef FEATURE_GRACEFUL_TERMINATION
+   { "die", 
+         cgi_die,  
+         "<b>Shut down</b> - <em class=\"warning\">Do not deploy this build in a production environment, "
+         "this is a one click Denial Of Service attack!!!</em>" }, 
+#endif
+   { "show-status", 
+         cgi_show_status,  
+         "View & change the current configuration" }, 
+   { "show-version", 
+         cgi_show_version,  
+         "View the source code version numbers" }, 
+   { "show-request", 
+         cgi_show_request,  
+         "View the request headers." }, 
+   { "show-url-info",
+         cgi_show_url_info, 
+         "Look up which actions apply to a URL and why"  },
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+   { "toggle",
+         cgi_toggle, 
+         "Toggle Privoxy on or off" },
+
+   { "edit-actions", /* Edit the actions list */
+         cgi_edit_actions, 
+         NULL },
+   { "eaa", /* Shortcut for edit-actions-add-url-form */
+         cgi_edit_actions_add_url_form, 
+         NULL },
+   { "eau", /* Shortcut for edit-actions-url-form */
+         cgi_edit_actions_url_form, 
+         NULL },
+   { "ear", /* Shortcut for edit-actions-remove-url-form */
+         cgi_edit_actions_remove_url_form, 
+         NULL },
+   { "eafu", /* Shortcut for edit-actions-for-url */
+         cgi_edit_actions_for_url, 
+         NULL },
+   { "eas", /* Shortcut for edit-actions-submit */
+         cgi_edit_actions_submit, 
+         NULL },
+   { "easa", /* Shortcut for edit-actions-section-add */
+         cgi_edit_actions_section_add, 
+         NULL },
+   { "easr", /* Shortcut for edit-actions-section-remove */
+         cgi_edit_actions_section_remove, 
+         NULL },
+   { "eass", /* Shortcut for edit-actions-section-swap */
+         cgi_edit_actions_section_swap, 
+         NULL },
+   { "edit-actions-for-url",
+         cgi_edit_actions_for_url, 
+         NULL /* Edit the actions for (a) specified URL(s) */ },
+   { "edit-actions-list",
+         cgi_edit_actions_list, 
+         NULL /* Edit the actions list */ },
+   { "edit-actions-submit",
+         cgi_edit_actions_submit, 
+         NULL /* Change the actions for (a) specified URL(s) */ },
+   { "edit-actions-url",
+         cgi_edit_actions_url, 
+         NULL /* Change a URL pattern in the actionsfile */ },
+   { "edit-actions-url-form",
+         cgi_edit_actions_url_form, 
+         NULL /* Form to change a URL pattern in the actionsfile */ },
+   { "edit-actions-add-url",
+         cgi_edit_actions_add_url, 
+         NULL /* Add a URL pattern to the actionsfile */ },
+   { "edit-actions-add-url-form",
+         cgi_edit_actions_add_url_form, 
+         NULL /* Form to add a URL pattern to the actionsfile */ },
+   { "edit-actions-remove-url",
+         cgi_edit_actions_remove_url, 
+         NULL /* Remove a URL pattern from the actionsfile */ },
+   { "edit-actions-remove-url-form",
+         cgi_edit_actions_remove_url_form, 
+         NULL /* Form to remove a URL pattern from the actionsfile */ },
+   { "edit-actions-section-add",
+         cgi_edit_actions_section_add, 
+         NULL /* Remove a section from the actionsfile */ },
+   { "edit-actions-section-remove",
+         cgi_edit_actions_section_remove, 
+         NULL /* Remove a section from the actionsfile */ },
+   { "edit-actions-section-swap",
+         cgi_edit_actions_section_swap, 
+         NULL /* Swap two sections in the actionsfile */ },
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
+   { "robots.txt", 
+         cgi_robots_txt,  
+         NULL /* Sends a robots.txt file to tell robots to go away. */ }, 
+   { "send-banner",
+         cgi_send_banner, 
+         NULL /* Send a built-in image */ },
+   { "send-stylesheet",
+         cgi_send_stylesheet, 
+         NULL /* Send templates/cgi-style.css */ },
+   { "t",
+         cgi_transparent_image, 
+         NULL /* Send a transparent image (short name) */ },
+   { NULL, /* NULL Indicates end of list and default page */
+         cgi_error_404,
+         NULL /* Unknown CGI page */ }
+};
+
+
+/*
+ * Bulit-in images for ad replacement
+ *
+ * Hint: You can encode your own images like this:
+ * cat your-image | perl -e 'while (read STDIN, $c, 1) { printf("\\%.3o", unpack("C", $c)); }'
+ */
+
+#ifdef FEATURE_NO_GIFS
+
+/*
+ * Checkerboard pattern, as a PNG.
+ */
+const char image_pattern_data[] =
+   "\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104"
+   "\122\000\000\000\004\000\000\000\004\010\002\000\000\000\046"
+   "\223\011\051\000\000\000\006\142\113\107\104\000\310\000\310"
+   "\000\310\052\045\225\037\000\000\000\032\111\104\101\124\170"
+   "\332\143\070\161\342\304\377\377\377\041\044\003\234\165\342"
+   "\304\011\006\234\062\000\125\200\052\251\125\174\360\223\000"
+   "\000\000\000\111\105\116\104\256\102\140\202";
+
+/*
+ * 1x1 transparant PNG.
+ */
+const char image_blank_data[] =
+ "\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104\122"
+ "\000\000\000\004\000\000\000\004\010\006\000\000\000\251\361\236"
+ "\176\000\000\000\007\164\111\115\105\007\322\003\013\020\073\070"
+ "\013\025\036\203\000\000\000\011\160\110\131\163\000\000\013\022"
+ "\000\000\013\022\001\322\335\176\374\000\000\000\004\147\101\115"
+ "\101\000\000\261\217\013\374\141\005\000\000\000\033\111\104\101"
+ "\124\170\332\143\070\161\342\304\207\377\377\377\347\302\150\006"
+ "\144\016\210\146\040\250\002\000\042\305\065\221\270\027\131\110"
+ "\000\000\000\000\111\105\116\104\256\102\140\202";
+#else
+
+/*
+ * Checkerboard pattern, as a GIF.
+ */
+const char image_pattern_data[] =
+   "\107\111\106\070\071\141\004\000\004\000\200\000\000\310\310"
+   "\310\377\377\377\041\376\016\111\040\167\141\163\040\141\040"
+   "\142\141\156\156\145\162\000\041\371\004\001\012\000\001\000"
+   "\054\000\000\000\000\004\000\004\000\000\002\005\104\174\147"
+   "\270\005\000\073";
+
+/*
+ * 1x1 transparant GIF.
+ */
+const char image_blank_data[] =
+   "GIF89a\001\000\001\000\200\000\000\377\377\377\000\000"
+   "\000!\371\004\001\000\000\000\000,\000\000\000\000\001"
+   "\000\001\000\000\002\002D\001\000;";
+#endif
+
+const size_t image_pattern_length = sizeof(image_pattern_data) - 1;
+const size_t image_blank_length   = sizeof(image_blank_data) - 1;
+
+
+static struct http_response cgi_error_memory_response[1];
+
+static struct http_response *dispatch_known_cgi(struct client_state * csp,
+                                                const char * path);
+static struct map *parse_cgi_parameters(char *argstring);
+
+
+/*********************************************************************
+ * 
+ * Function    :  dispatch_cgi
+ *
+ * Description :  Checks if a request URL has either the magical
+ *                hostname CGI_SITE_1_HOST (usually http://p.p/) or
+ *                matches CGI_SITE_2_HOST CGI_SITE_2_PATH (usually
+ *                http://config.privoxy.org/). If so, it passes
+ *                the (rest of the) path onto dispatch_known_cgi, which
+ *                calls the relevant CGI handler function.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  http_response if match, NULL if nonmatch or handler fail
+ *
+ *********************************************************************/
+struct http_response *dispatch_cgi(struct client_state *csp)
+{
+   const char *host = csp->http->host;
+   const char *path = csp->http->path;
+
+   /*
+    * Should we intercept ?
+    */
+
+   /* Note: "example.com" and "example.com." are equivalent hostnames. */
+
+   /* Either the host matches CGI_SITE_1_HOST ..*/
+   if (   ( (0 == strcmpic(host, CGI_SITE_1_HOST))
+         || (0 == strcmpic(host, CGI_SITE_1_HOST ".")))
+       && (path[0] == '/') )
+   {
+      /* ..then the path will all be for us.  Remove leading '/' */
+      path++;
+   }
+   /* Or it's the host part CGI_SITE_2_HOST, and the path CGI_SITE_2_PATH */
+   else if ( ( (0 == strcmpic(host, CGI_SITE_2_HOST ))
+            || (0 == strcmpic(host, CGI_SITE_2_HOST ".")) )
+          && (0 == strncmpic(path, CGI_SITE_2_PATH, strlen(CGI_SITE_2_PATH))) )
+   {
+      /* take everything following CGI_SITE_2_PATH */
+      path += strlen(CGI_SITE_2_PATH);
+      if (*path == '/')
+      {
+         /* skip the forward slash after CGI_SITE_2_PATH */
+         path++;
+      }
+      else if (*path != '\0')
+      {
+         /*
+          * wierdness: URL is /configXXX, where XXX is some string
+          * Do *NOT* intercept.
+          */
+         return NULL;
+      }
+   }
+   else
+   {
+      /* Not a CGI */
+      return NULL;
+   }
+
+   /* 
+    * This is a CGI call.
+    */
+
+   return dispatch_known_cgi(csp, path);
+}
+
+
+/*********************************************************************
+ * 
+ * Function    :  dispatch_known_cgi
+ *
+ * Description :  Processes a CGI once dispatch_cgi has determined that
+ *                it matches one of the magic prefixes. Parses the path
+ *                as a cgi name plus query string, prepares a map that
+ *                maps CGI parameter names to their values, initializes
+ *                the http_response struct, and calls the relevant CGI
+ *                handler function.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  path = Path of CGI, with the CGI prefix removed.
+ *                       Should not have a leading "/".
+ *
+ * Returns     :  http_response, or NULL on handler failure or out of
+ *                memory.
+ *
+ *********************************************************************/
+static struct http_response *dispatch_known_cgi(struct client_state * csp,
+                                                const char * path)
+{
+   const struct cgi_dispatcher *d;
+   struct map *param_list;
+   struct http_response *rsp;
+   char *query_args_start;
+   char *path_copy;
+   jb_err err;
+
+   if (NULL == (path_copy = strdup(path)))
+   {
+      return cgi_error_memory();
+   }
+
+   query_args_start = path_copy;
+   while (*query_args_start && *query_args_start != '?')
+   {
+      query_args_start++;
+   }
+   if (*query_args_start == '?')
+   {
+      *query_args_start++ = '\0';
+   }
+
+   if (NULL == (param_list = parse_cgi_parameters(query_args_start)))
+   {
+      free(path_copy);
+      return cgi_error_memory();
+   }
+
+
+   /*
+    * At this point:
+    * path_copy        = CGI call name
+    * param_list       = CGI params, as map
+    */
+
+   /* Get mem for response or fail*/
+   if (NULL == (rsp = alloc_http_response()))
+   {
+      free(path_copy);
+      free_map(param_list);
+      return cgi_error_memory();
+   }
+
+   log_error(LOG_LEVEL_GPC, "%s%s cgi call", csp->http->hostport, csp->http->path);
+   log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 3", 
+                            csp->ip_addr_str, csp->http->cmd); 
+
+   /* Find and start the right CGI function*/
+   d = cgi_dispatchers;
+   for (;;)
+   {
+      if ((d->name == NULL) || (strcmp(path_copy, d->name) == 0))
+      {
+         err = (d->handler)(csp, rsp, param_list);
+         free(path_copy);
+         free_map(param_list);
+         if (err == JB_ERR_CGI_PARAMS)
+         {
+            err = cgi_error_bad_param(csp, rsp);
+         }
+         if (err && (err != JB_ERR_MEMORY))
+         {
+            /* Unexpected error! Shouldn't get here */
+            log_error(LOG_LEVEL_ERROR, "Unexpected CGI error %d in top-level handler.  Please file a bug report!", err);
+            err = cgi_error_unknown(csp, rsp, err);
+         }
+         if (!err)
+         {
+            /* It worked */
+            return finish_http_response(rsp);
+         }
+         else
+         {
+            /* Error in handler, probably out-of-memory */
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+      }
+      d++;
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  parse_cgi_parameters
+ *
+ * Description :  Parse a URL-encoded argument string into name/value
+ *                pairs and store them in a struct map list.
+ *
+ * Parameters  :
+ *          1  :  argstring = string to be parsed.  Will be trashed.
+ *
+ * Returns     :  pointer to param list, or NULL if out of memory.
+ *
+ *********************************************************************/
+static struct map *parse_cgi_parameters(char *argstring)
+{
+   char *p;
+   char *vector[BUFFER_SIZE];
+   int pairs, i;
+   struct map *cgi_params;
+
+   if (NULL == (cgi_params = new_map()))
+   {
+      return NULL;
+   }
+
+   pairs = ssplit(argstring, "&", vector, SZ(vector), 1, 1);
+
+   for (i = 0; i < pairs; i++)
+   {
+      if ((NULL != (p = strchr(vector[i], '='))) && (*(p+1) != '\0'))
+      {
+         *p = '\0';
+         if (map(cgi_params, url_decode(vector[i]), 0, url_decode(++p), 0))
+         {
+            free_map(cgi_params);
+            return NULL;
+         }
+      }
+   }
+
+   return cgi_params;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_char_param
+ *
+ * Description :  Get a single-character parameter passed to a CGI
+ *                function.
+ *
+ * Parameters  :
+ *          1  :  parameters = map of cgi parameters
+ *          2  :  param_name = The name of the parameter to read
+ *
+ * Returns     :  Uppercase character on success, '\0' on error.
+ *
+ *********************************************************************/
+char get_char_param(const struct map *parameters,
+                    const char *param_name)
+{
+   char ch;
+
+   assert(parameters);
+   assert(param_name);
+
+   ch = *(lookup(parameters, param_name));
+   if ((ch >= 'a') && (ch <= 'z'))
+   {
+      ch = ch - 'a' + 'A';
+   }
+
+   return ch;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_string_param
+ *
+ * Description :  Get a string paramater, to be used as an
+ *                ACTION_STRING or ACTION_MULTI paramater.
+ *                Validates the input to prevent stupid/malicious
+ *                users from corrupting their action file.
+ *
+ * Parameters  :
+ *          1  :  parameters = map of cgi parameters
+ *          2  :  param_name = The name of the parameter to read
+ *          3  :  pparam = destination for paramater.  Allocated as
+ *                part of the map "parameters", so don't free it.
+ *                Set to NULL if not specified.
+ *
+ * Returns     :  JB_ERR_OK         on success, or if the paramater
+ *                                  was not specified.
+ *                JB_ERR_MEMORY     on out-of-memory.
+ *                JB_ERR_CGI_PARAMS if the paramater is not valid.
+ *
+ *********************************************************************/
+jb_err get_string_param(const struct map *parameters,
+                        const char *param_name,
+                        const char **pparam)
+{
+   const char *param;
+   const char *s;
+   char ch;
+
+   assert(parameters);
+   assert(param_name);
+   assert(pparam);
+
+   *pparam = NULL;
+
+   param = lookup(parameters, param_name);
+   if (!*param)
+   {
+      return JB_ERR_OK;
+   }
+
+   if (strlen(param) >= CGI_PARAM_LEN_MAX)
+   {
+      /*
+       * Too long.
+       *
+       * Note that the length limit is arbitrary, it just seems
+       * sensible to limit it to *something*.  There's no
+       * technical reason for any limit at all.
+       */
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* Check every character to see if it's legal */
+   s = param;
+   while ((ch = *s++) != '\0')
+   {
+      if ( ((unsigned char)ch < (unsigned char)' ')
+        || (ch == '}') )
+      {
+         /* Probable hack attempt, or user accidentally used '}'. */
+         return JB_ERR_CGI_PARAMS;
+      }
+   }
+
+   /* Success */
+   *pparam = param;
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_number_param
+ *
+ * Description :  Get a non-negative integer from the parameters
+ *                passed to a CGI function.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  parameters = map of cgi parameters
+ *          3  :  name = Name of CGI parameter to read
+ *          4  :  pvalue = destination for value.
+ *                         Set to -1 on error.
+ *
+ * Returns     :  JB_ERR_OK         on success
+ *                JB_ERR_MEMORY     on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the parameter was not specified
+ *                                  or is not valid.
+ *
+ *********************************************************************/
+jb_err get_number_param(struct client_state *csp,
+                        const struct map *parameters,
+                        char *name,
+                        unsigned *pvalue)
+{
+   const char *param;
+   char ch;
+   unsigned value;
+
+   assert(csp);
+   assert(parameters);
+   assert(name);
+   assert(pvalue);
+
+   *pvalue = 0; 
+
+   param = lookup(parameters, name);
+   if (!*param)
+   {
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* We don't use atoi because I want to check this carefully... */
+
+   value = 0;
+   while ((ch = *param++) != '\0')
+   {
+      if ((ch < '0') || (ch > '9'))
+      {
+         return JB_ERR_CGI_PARAMS;
+      }
+
+      ch -= '0';
+
+      /* Note:
+       *
+       * <limits.h> defines UINT_MAX
+       *
+       * (UINT_MAX - ch) / 10 is the largest number that
+       *     can be safely multiplied by 10 then have ch added.
+       */
+      if (value > ((UINT_MAX - (unsigned)ch) / 10U))
+      {
+         return JB_ERR_CGI_PARAMS;
+      }
+
+      value = value * 10 + ch;
+   }
+
+   /* Success */
+   *pvalue = value;
+
+   return JB_ERR_OK;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  error_response
+ *
+ * Description :  returns an http_response that explains the reason
+ *                why a request failed.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  templatename = Which template should be used for the answer
+ *          3  :  sys_err = system error number
+ *
+ * Returns     :  A http_response.  If we run out of memory, this
+ *                will be cgi_error_memory().
+ *
+ *********************************************************************/
+struct http_response *error_response(struct client_state *csp,
+                                     const char *templatename,
+                                     int sys_err)
+{
+   jb_err err;
+   struct http_response *rsp;
+   struct map * exports = default_exports(csp, NULL);
+   if (exports == NULL)
+   {
+      return cgi_error_memory();
+   }
+
+   if (NULL == (rsp = alloc_http_response()))
+   {
+      free_map(exports);
+      return cgi_error_memory();
+   }
+
+   err = map(exports, "host", 1, html_encode(csp->http->host), 0);
+   if (!err) err = map(exports, "hostport", 1, html_encode(csp->http->hostport), 0);
+   if (!err) err = map(exports, "path", 1, html_encode(csp->http->path), 0);
+   if (!err) err = map(exports, "error", 1, html_encode_and_free_original(safe_strerror(sys_err)), 0);
+   if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); 
+   if (!err)
+   {
+     err = map(exports, "host-ip", 1, html_encode(csp->http->host_ip_addr_str), 0);
+     if (err)
+     {
+       /* Some failures, like "404 no such domain", don't have an IP address. */
+       err = map(exports, "host-ip", 1, html_encode(csp->http->host), 0);
+     }
+   }
+
+
+   if (err)
+   {
+      free_map(exports);
+      free_http_response(rsp);
+      return cgi_error_memory();
+   }
+
+   if (!strcmp(templatename, "no-such-domain"))
+   {
+      rsp->status = strdup("404 No such domain");
+      if (rsp->status == NULL)
+      {
+         free_map(exports);
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
+   }
+   else if (!strcmp(templatename, "connect-failed"))
+   {
+      rsp->status = strdup("503 Connect failed");
+      if (rsp->status == NULL)
+      {
+         free_map(exports);
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
+   }
+
+   err = template_fill_for_cgi(csp, templatename, exports, rsp);
+   if (err)
+   {
+      free_http_response(rsp);
+      return cgi_error_memory();
+   }
+
+   return finish_http_response(rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_init_error_messages
+ *
+ * Description :  Call at the start of the program to initialize
+ *                the error message used by cgi_error_memory().
+ *
+ * Parameters  :  N/A
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void cgi_init_error_messages(void)
+{
+   memset(cgi_error_memory_response, '\0', sizeof(*cgi_error_memory_response));
+   cgi_error_memory_response->head =
+      "HTTP/1.0 500 Internal Privoxy Error\r\n"
+      "Content-Type: text/html\r\n"
+      "\r\n";
+   cgi_error_memory_response->body =
+      "<html>\r\n"
+      "<head><title>500 Internal Privoxy Error</title></head>\r\n"
+      "<body>\r\n"
+      "<h1>500 Internal Privoxy Error</h1>\r\n"
+      "<p>Privoxy <b>ran out of memory</b> while processing your request.</p>\r\n"
+      "<p>Please contact your proxy administrator, or try again later</p>\r\n"
+      "</body>\r\n"
+      "</html>\r\n";
+
+   cgi_error_memory_response->head_length =
+      strlen(cgi_error_memory_response->head);
+   cgi_error_memory_response->content_length =
+      strlen(cgi_error_memory_response->body);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_memory
+ *
+ * Description :  Called if a CGI function runs out of memory.
+ *                Returns a statically-allocated error response.
+ *
+ * Parameters  :  N/A
+ *
+ * Returns     :  http_response data structure for output.  This is
+ *                statically allocated, for obvious reasons.
+ *
+ *********************************************************************/
+struct http_response *cgi_error_memory(void)
+{
+   /* assert that it's been initialized. */
+   assert(cgi_error_memory_response->head);
+
+   return cgi_error_memory_response;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_no_template
+ *
+ * Description :  Almost-CGI function that is called if a template
+ *                cannot be loaded.  Note this is not a true CGI,
+ *                it takes a template name rather than a map of 
+ *                parameters.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  template_name = Name of template that could not
+ *                                be loaded.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_error_no_template(struct client_state *csp,
+                             struct http_response *rsp,
+                             const char *template_name)
+{
+   static const char status[] =
+      "500 Internal Privoxy Error";
+   static const char body_prefix[] =
+      "<html>\r\n"
+      "<head><title>500 Internal Privoxy Error</title></head>\r\n"
+      "<body>\r\n"
+      "<h1>500 Internal Privoxy Error</h1>\r\n"
+      "<p>Privoxy encountered an error while processing your request:</p>\r\n"
+      "<p><b>Could not load template file <code>";
+   static const char body_suffix[] =
+      "</code> or one of it's included components.</b></p>\r\n"
+      "<p>Please contact your proxy administrator.</p>\r\n"
+      "<p>If you are the proxy administrator, please put the required file(s)"
+      "in the <code><i>(confdir)</i>/templates</code> directory.  The "
+      "location of the <code><i>(confdir)</i></code> directory "
+      "is specified in the main Privoxy <code>config</code> "
+      "file.  (It's typically the Privoxy install directory"
+#ifndef _WIN32
+      ", or <code>/etc/privoxy/</code>"
+#endif /* ndef _WIN32 */
+      ").</p>\r\n"
+      "</body>\r\n"
+      "</html>\r\n";
+
+   assert(csp);
+   assert(rsp);
+   assert(template_name);
+
+   /* Reset rsp, if needed */
+   freez(rsp->status);
+   freez(rsp->head);
+   freez(rsp->body);
+   rsp->content_length = 0;
+   rsp->head_length = 0;
+   rsp->is_static = 0;
+
+   rsp->body = malloc(strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1);
+   if (rsp->body == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+   strcpy(rsp->body, body_prefix);
+   strcat(rsp->body, template_name);
+   strcat(rsp->body, body_suffix);
+
+   rsp->status = strdup(status);
+   if (rsp->body == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_unknown
+ *
+ * Description :  Almost-CGI function that is called if an unexpected
+ *                error occurs in the top-level CGI dispatcher.
+ *                In this context, "unexpected" means "anything other
+ *                than JB_ERR_MEMORY or JB_ERR_CGI_PARAMS" - CGIs are
+ *                expected to handle all other errors internally,
+ *                since they can give more relavent error messages
+ *                that way.
+ *
+ *                Note this is not a true CGI, it takes an error
+ *                code rather than a map of parameters.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  error_to_report = Error code to report.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_error_unknown(struct client_state *csp,
+                         struct http_response *rsp,
+                         jb_err error_to_report)
+{
+   static const char status[] =
+      "500 Internal Privoxy Error";
+   static const char body_prefix[] =
+      "<html>\r\n"
+      "<head><title>500 Internal Privoxy Error</title></head>\r\n"
+      "<body>\r\n"
+      "<h1>500 Internal Privoxy Error</h1>\r\n"
+      "<p>Privoxy encountered an error while processing your request:</p>\r\n"
+      "<p><b>Unexpected internal error: ";
+   static const char body_suffix[] =
+      "</b></p>\r\n"
+      "<p>Please "
+      "<a href=\"http://sourceforge.net/tracker/?group_id=11118&atid=111118\">"
+      "file a bug report</a>.</p>\r\n"
+      "</body>\r\n"
+      "</html>\r\n";
+   char errnumbuf[30];
+   assert(csp);
+   assert(rsp);
+
+   /* Reset rsp, if needed */
+   freez(rsp->status);
+   freez(rsp->head);
+   freez(rsp->body);
+   rsp->content_length = 0;
+   rsp->head_length = 0;
+   rsp->is_static = 0;
+
+   sprintf(errnumbuf, "%d", error_to_report);
+
+   rsp->body = malloc(strlen(body_prefix) + strlen(errnumbuf) + strlen(body_suffix) + 1);
+   if (rsp->body == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+   strcpy(rsp->body, body_prefix);
+   strcat(rsp->body, errnumbuf);
+   strcat(rsp->body, body_suffix);
+
+   rsp->status = strdup(status);
+   if (rsp->body == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_bad_param
+ *
+ * Description :  CGI function that is called if the parameters
+ *                (query string) for a CGI were wrong.
+ *               
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_error_bad_param(struct client_state *csp,
+                           struct http_response *rsp)
+{
+   struct map *exports;
+
+   assert(csp);
+   assert(rsp);
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   return template_fill_for_cgi(csp, "cgi-error-bad-param", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  add_help_link
+ *
+ * Description :  Produce a copy of the string given as item,
+ *                embedded in an HTML link to its corresponding
+ *                section (item name in uppercase) in the actions
+ *                chapter of the user manual, (whose URL is given in
+ *                the config and defaults to our web site).
+ *
+ *                FIXME: I currently only work for actions, and would
+ *                       like to be generalized for other topics.
+ *
+ * Parameters  :  
+ *          1  :  item = item (will NOT be free()d.) 
+ *                       It is assumed to be HTML-safe.
+ *          2  :  config = The current configuration.
+ *
+ * Returns     :  String with item embedded in link, or NULL on
+ *                out-of-memory
+ *
+ *********************************************************************/
+char *add_help_link(const char *item,
+                    struct configuration_spec *config)
+{
+   char *result;
+
+   if (!item) return NULL;
+
+   result = strdup("<a href=\"");
+   string_append(&result, config->usermanual);
+   string_append(&result, ACTIONS_HELP_PREFIX);
+   string_join  (&result, string_toupper(item));
+   string_append(&result, "\">");
+   string_append(&result, item);
+   string_append(&result, "</a> ");
+
+   return result;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_http_time
+ *
+ * Description :  Get the time in a format suitable for use in a
+ *                HTTP header - e.g.:
+ *                "Sun, 06 Nov 1994 08:49:37 GMT"
+ *
+ * Parameters  :  
+ *          1  :  time_offset = Time returned will be current time
+ *                              plus this number of seconds.
+ *          2  :  buf = Destination for result.  Must be long enough
+ *                      to hold 29 characters plus a trailing zero.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void get_http_time(int time_offset, char *buf)
+{
+   static const char day_names[7][4] =
+      { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+   static const char month_names[12][4] =
+      { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+   struct tm *t;
+   time_t current_time;
+
+   assert(buf);
+
+   time(&current_time); /* get current time */
+
+   current_time += time_offset;
+
+   /* get and save the gmt */
+   {
+#ifdef HAVE_GMTIME_R
+      struct tm dummy;
+      t = gmtime_r(&current_time, &dummy);
+#else
+      t = gmtime(&current_time);
+#endif
+   }
+
+   /* Format: "Sun, 06 Nov 1994 08:49:37 GMT" */
+   snprintf(buf, 30,
+      "%s, %02d %s %4d %02d:%02d:%02d GMT",
+      day_names[t->tm_wday],
+      t->tm_mday,
+      month_names[t->tm_mon],
+      t->tm_year + 1900,
+      t->tm_hour,
+      t->tm_min,
+      t->tm_sec
+      );
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  finish_http_response
+ *
+ * Description :  Fill in the missing headers in an http response,
+ *                and flatten the headers to an http head.
+ *
+ * Parameters  :
+ *          1  :  rsp = pointer to http_response to be processed
+ *
+ * Returns     :  A http_response, usually the rsp parameter.
+ *                On error, free()s rsp and returns cgi_error_memory()
+ *
+ *********************************************************************/
+struct http_response *finish_http_response(struct http_response *rsp)
+{
+   char buf[BUFFER_SIZE];
+   jb_err err;
+
+   /* Special case - do NOT change this statically allocated response,
+    * which is ready for output anyway.
+    */
+   if (rsp == cgi_error_memory_response)
+   {
+      return rsp;
+   }
+
+   /* 
+    * Fill in the HTTP Status
+    */
+   sprintf(buf, "HTTP/1.0 %s", rsp->status ? rsp->status : "200 OK");
+   err = enlist_first(rsp->headers, buf);
+
+   /* 
+    * Set the Content-Length
+    */
+   if (rsp->content_length == 0)
+   {
+      rsp->content_length = rsp->body ? strlen(rsp->body) : 0;
+   }
+   if (!err)
+   {
+      sprintf(buf, "Content-Length: %d", (int)rsp->content_length);
+      err = enlist(rsp->headers, buf);
+   }
+
+   /* 
+    * Fill in the default headers:
+    *
+    * Content-Type: default to text/html if not already specified.
+    * Date: set to current date/time.
+    * Last-Modified: set to date/time the page was last changed.
+    * Expires: set to date/time page next needs reloading.
+    * Cache-Control: set to "no-cache" if applicable.
+    * 
+    * See http://www.w3.org/Protocols/rfc2068/rfc2068
+    */
+   if (!err) err = enlist_unique(rsp->headers, "Content-Type: text/html", 13);
+
+   if (rsp->is_static)
+   {
+      /*
+       * Set Expires to about 10 min into the future so it'll get reloaded
+       * occasionally, e.g. if Privoxy gets upgraded.
+       */
+
+      if (!err)
+      {
+         get_http_time(0, buf);
+         err = enlist_unique_header(rsp->headers, "Date", buf);
+      }
+
+      /* Some date in the past. */
+      if (!err) err = enlist_unique_header(rsp->headers, "Last-Modified", "Sat, 17 Jun 2000 12:00:00 GMT");
+
+      if (!err)
+      {
+         get_http_time(10 * 60, buf); /* 10 * 60sec = 10 minutes */
+         err = enlist_unique_header(rsp->headers, "Expires", buf);
+      }
+   }
+   else
+   {
+      /*
+       * Compliant browsers should not cache this due to the "Cache-Control"
+       * setting.  However, to be certain, we also set both "Last-Modified"
+       * and "Expires" to the current time.
+       */
+      if (!err) err = enlist_unique_header(rsp->headers, "Cache-Control", "no-cache");
+
+      get_http_time(0, buf);
+      if (!err) err = enlist_unique_header(rsp->headers, "Date", buf);
+      if (!err) err = enlist_unique_header(rsp->headers, "Last-Modified", buf);
+      if (!err) err = enlist_unique_header(rsp->headers, "Expires", buf);
+   }
+
+
+   /* 
+    * Write the head
+    */
+   if (err || (NULL == (rsp->head = list_to_text(rsp->headers))))
+   {
+      free_http_response(rsp);
+      return cgi_error_memory();
+   }
+   rsp->head_length = strlen(rsp->head);
+
+   return rsp;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  alloc_http_response
+ *
+ * Description :  Allocates a new http_response structure.
+ *
+ * Parameters  :  N/A
+ *
+ * Returns     :  pointer to a new http_response, or NULL.
+ *
+ *********************************************************************/
+struct http_response *alloc_http_response(void)
+{
+   return (struct http_response *) zalloc(sizeof(struct http_response));
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_http_response
+ *
+ * Description :  Free the memory occupied by an http_response
+ *                and its depandant structures.
+ *
+ * Parameters  :
+ *          1  :  rsp = pointer to http_response to be freed
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void free_http_response(struct http_response *rsp)
+{
+   /*
+    * Must special case cgi_error_memory_response, which is never freed.
+    */
+   if (rsp && (rsp != cgi_error_memory_response))
+   {
+      freez(rsp->status);
+      freez(rsp->head);
+      freez(rsp->body);
+      destroy_list(rsp->headers);
+      free(rsp);
+   }
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  template_load
+ *
+ * Description :  CGI support function that loads a given HTML
+ *                template from the confdir, ignoring comment
+ *                lines and following #include statements up to
+ *                a depth of 1.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  template_ptr = Destination for pointer to loaded
+ *                               template text.
+ *          3  :  templatename = name of the HTML template to be used
+ *          4  :  recursive = Flag set if this function calls itself
+ *                            following an #include statament
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *                JB_ERR_FILE if the template file cannot be read
+ *
+ *********************************************************************/
+jb_err template_load(struct client_state *csp, char **template_ptr, 
+                     const char *templatename, int recursive)
+{
+   jb_err err;
+   char *templates_dir_path;
+   char *full_path;
+   char *file_buffer;
+   char *included_module;
+   const char *p;
+   FILE *fp;
+   char buf[BUFFER_SIZE];
+
+   assert(csp);
+   assert(template_ptr);
+   assert(templatename);
+
+   *template_ptr = NULL;
+
+   /* Validate template name.  Paranoia. */
+   for (p = templatename; *p != 0; p++)
+   {
+      if ( ((*p < 'a') || (*p > 'z'))
+        && ((*p < 'A') || (*p > 'Z'))
+        && ((*p < '0') || (*p > '9'))
+        && (*p != '-')
+        && (*p != '.'))
+      {
+         /* Illegal character */
+         return JB_ERR_FILE;
+      }
+   }
+
+   /* Generate full path */
+
+   templates_dir_path = make_path(csp->config->confdir, "templates");
+   if (templates_dir_path == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   full_path = make_path(templates_dir_path, templatename);
+   free(templates_dir_path);
+   if (full_path == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   /* Allocate buffer */
+
+   file_buffer = strdup("");
+   if (file_buffer == NULL)
+   {
+      free(full_path);
+      return JB_ERR_MEMORY;
+   }
+
+   /* Open template file */
+
+   if (NULL == (fp = fopen(full_path, "r")))
+   {
+      log_error(LOG_LEVEL_ERROR, "Cannot open template file %s: %E", full_path);
+      free(full_path);
+      free(file_buffer);
+      return JB_ERR_FILE;
+   }
+   free(full_path);
+
+   /* 
+    * Read the file, ignoring comments, and honoring #include
+    * statements, unless we're already called recursively.
+    *
+    * FIXME: The comment handling could break with lines >BUFFER_SIZE long.
+    *        This is unlikely in practise.
+    */
+   while (fgets(buf, BUFFER_SIZE, fp))
+   {
+      if (!recursive && !strncmp(buf, "#include ", 9))
+      {
+         if (JB_ERR_OK != (err = template_load(csp, &included_module, chomp(buf + 9), 1)))
+         {
+            free(file_buffer);
+            fclose(fp);
+            return err;
+         }
+
+         if (string_join(&file_buffer, included_module))
+         {
+            fclose(fp);
+            return JB_ERR_MEMORY;
+         }
+
+         continue;
+      }
+
+      /* skip lines starting with '#' */
+      if (*buf == '#')
+      {
+         continue;
+      }
+
+      if (string_append(&file_buffer, buf))
+      {
+         fclose(fp);
+         return JB_ERR_MEMORY;
+      }
+   }
+   fclose(fp);
+
+   *template_ptr = file_buffer;
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  template_fill
+ *
+ * Description :  CGI support function that fills in a pre-loaded
+ *                HTML template by replacing @name@ with value using
+ *                pcrs, for each item in the output map.
+ *
+ *                Note that a leading '$' charachter in the export map's
+ *                values will be stripped and toggle on backreference
+ *                interpretation.
+ *
+ * Parameters  :
+ *          1  :  template_ptr = IN: Template to be filled out.
+ *                                   Will be free()d.
+ *                               OUT: Filled out template.
+ *                                    Caller must free().
+ *          2  :  exports = map with fill in symbol -> name pairs
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error
+ *
+ *********************************************************************/
+jb_err template_fill(char **template_ptr, const struct map *exports)
+{
+   struct map_entry *m;
+   pcrs_job *job;
+   char buf[BUFFER_SIZE];
+   char *tmp_out_buffer;
+   char *file_buffer;
+   size_t  size;
+   int error;
+   const char *flags;
+
+   assert(template_ptr);
+   assert(*template_ptr);
+   assert(exports);
+
+   file_buffer = *template_ptr;
+   size = strlen(file_buffer) + 1;
+
+   /* 
+    * Assemble pcrs joblist from exports map
+    */
+   for (m = exports->first; m != NULL; m = m->next)
+   {
+      if (*m->name == '$')
+      {
+         /*
+          * First character of name is '$', so remove this flag
+          * character and allow backreferences ($1 etc) in the
+          * "replace with" text.
+          */
+         snprintf(buf, BUFFER_SIZE, "%s", m->name + 1);
+         flags = "sigU";
+      }
+      else
+      {
+         /*
+          * Treat the "replace with" text as a literal string - 
+          * no quoting needed, no backreferences allowed.
+          * ("Trivial" ['T'] flag).
+          */
+         flags = "sigTU";
+
+         /* Enclose name in @@ */
+         snprintf(buf, BUFFER_SIZE, "@%s@", m->name);
+      }
+
+
+      log_error(LOG_LEVEL_CGI, "Substituting: s/%s/%s/%s", buf, m->value, flags);
+
+      /* Make and run job. */
+      job = pcrs_compile(buf, m->value, flags,  &error);
+      if (job == NULL) 
+      {
+         if (error == PCRS_ERR_NOMEM)
+         {
+            free(file_buffer);
+            *template_ptr = NULL;
+            return JB_ERR_MEMORY;
+         }
+         else
+         {
+            log_error(LOG_LEVEL_ERROR, "Error compiling template fill job %s: %d", m->name, error);
+            /* Hope it wasn't important and silently ignore the invalid job */
+         }
+      }
+      else
+      {
+         pcrs_execute(job, file_buffer, size, &tmp_out_buffer, &size);
+         free(file_buffer);
+         pcrs_free_job(job);
+         if (NULL == tmp_out_buffer)
+         {
+            *template_ptr = NULL;
+            return JB_ERR_MEMORY;
+         }
+         file_buffer = tmp_out_buffer;
+      }
+   }
+
+   /*
+    * Return
+    */
+   *template_ptr = file_buffer;
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  template_fill_for_cgi
+ *
+ * Description :  CGI support function that loads a HTML template
+ *                and fills it in.  Handles file-not-found errors
+ *                by sending a HTML error message.  For convenience,
+ *                this function also frees the passed "exports" map.
+ *
+ * Parameters  :
+ *          1  :  csp = Client state
+ *          2  :  templatename = name of the HTML template to be used
+ *          3  :  exports = map with fill in symbol -> name pairs.
+ *                          Will be freed by this function.
+ *          4  :  rsp = Response structure to fill in.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error
+ *
+ *********************************************************************/
+jb_err template_fill_for_cgi(struct client_state *csp,
+                             const char *templatename,
+                             struct map *exports,
+                             struct http_response *rsp)
+{
+   jb_err err;
+   
+   assert(csp);
+   assert(templatename);
+   assert(exports);
+   assert(rsp);
+
+   err = template_load(csp, &rsp->body, templatename, 0);
+   if (err == JB_ERR_FILE)
+   {
+      free_map(exports);
+      return cgi_error_no_template(csp, rsp, templatename);
+   }
+   else if (err)
+   {
+      free_map(exports);
+      return err; /* JB_ERR_MEMORY */
+   }
+   err = template_fill(&rsp->body, exports);
+   free_map(exports);
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  default_exports
+ *
+ * Description :  returns a struct map list that contains exports
+ *                which are common to all CGI functions.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  caller = name of CGI who calls us and which should
+ *                         be excluded from the generated menu. May be
+ *                         NULL.
+ * Returns     :  NULL if no memory, else a new map.  Caller frees.
+ *
+ *********************************************************************/
+struct map *default_exports(const struct client_state *csp, const char *caller)
+{
+   char buf[20];
+   jb_err err;
+   struct map * exports;
+   int local_help_exists = 0;
+
+   assert(csp);
+
+   exports = new_map();
+   if (exports == NULL)
+   {
+      return NULL;
+   }
+
+   err = map(exports, "version", 1, html_encode(VERSION), 0);
+   if (!err) err = map(exports, "my-ip-address", 1, html_encode(csp->my_ip_addr_str ? csp->my_ip_addr_str : "unknown"), 0);
+   if (!err) err = map(exports, "my-hostname",   1, html_encode(csp->my_hostname ? csp->my_hostname : "unknown"), 0);
+   if (!err) err = map(exports, "homepage",      1, html_encode(HOME_PAGE_URL), 0);
+   if (!err) err = map(exports, "default-cgi",   1, html_encode(CGI_PREFIX), 0);
+   if (!err) err = map(exports, "menu",          1, make_menu(caller), 0);
+   if (!err) err = map(exports, "code-status",   1, CODE_STATUS, 1);
+   if (!err) err = map(exports, "user-manual",   1, csp->config->usermanual ,1);
+   if (!err) err = map(exports, "actions-help-prefix", 1, ACTIONS_HELP_PREFIX ,1);
+   if (!err) err = map_conditional(exports, "enabled-display", g_bToggleIJB);
+
+   snprintf(buf, 20, "%d", csp->config->hport);
+   if (!err) err = map(exports, "my-port", 1, buf, 1);
+
+   if(!strcmp(CODE_STATUS, "stable"))
+   {
+      if (!err) err = map_block_killer(exports, "unstable");
+   }
+
+   if (csp->config->admin_address != NULL)
+   {
+      if (!err) err = map(exports, "admin-address", 1, html_encode(csp->config->admin_address), 0);
+      local_help_exists = 1;
+   }
+   else
+   {
+      if (!err) err = map_block_killer(exports, "have-adminaddr-info");
+   }
+
+   if (csp->config->proxy_info_url != NULL)
+   {
+      if (!err) err = map(exports, "proxy-info-url", 1, html_encode(csp->config->proxy_info_url), 0);
+      local_help_exists = 1;
+   }
+   else
+   {
+      if (!err) err = map_block_killer(exports, "have-proxy-info");
+   }
+
+   if (local_help_exists == 0)
+   {
+      if (!err) err = map_block_killer(exports, "have-help-info");
+   }
+
+   if (err)
+   {
+      free_map(exports);
+      return NULL;
+   }
+
+   return exports;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  map_block_killer
+ *
+ * Description :  Convenience function.
+ *                Adds a "killer" for the conditional HTML-template
+ *                block <name>, i.e. a substitution of the regex
+ *                "if-<name>-start.*if-<name>-end" to the given
+ *                export list.
+ *
+ * Parameters  :  
+ *          1  :  exports = map to extend
+ *          2  :  name = name of conditional block
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err map_block_killer(struct map *exports, const char *name)
+{
+   char buf[1000]; /* Will do, since the names are hardwired */
+
+   assert(exports);
+   assert(name);
+   assert(strlen(name) < 490);
+
+   snprintf(buf, 1000, "if-%s-start.*if-%s-end", name, name);
+   return map(exports, buf, 1, "", 1);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  map_block_keep
+ *
+ * Description :  Convenience function.  Removes the markers used
+ *                by map-block-killer, to save a few bytes.
+ *                i.e. removes "@if-<name>-start@" and "@if-<name>-end@"
+ *
+ * Parameters  :  
+ *          1  :  exports = map to extend
+ *          2  :  name = name of conditional block
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err map_block_keep(struct map *exports, const char *name)
+{
+   jb_err err;
+   char buf[500]; /* Will do, since the names are hardwired */
+
+   assert(exports);
+   assert(name);
+   assert(strlen(name) < 490);
+
+   snprintf(buf, 500, "if-%s-start", name);
+   err = map(exports, buf, 1, "", 1);
+
+   if (err)
+   {
+      return err;
+   }
+
+   snprintf(buf, 500, "if-%s-end", name);
+   return map(exports, buf, 1, "", 1);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  map_conditional
+ *
+ * Description :  Convenience function.
+ *                Adds an "if-then-else" for the conditional HTML-template
+ *                block <name>, i.e. a substitution of the form:
+ *                @if-<name>-then@
+ *                   True text
+ *                @else-not-<name>@
+ *                   False text
+ *                @endif-<name>@
+ *
+ *                The control structure and one of the alternatives
+ *                will be hidden.
+ *
+ * Parameters  :  
+ *          1  :  exports = map to extend
+ *          2  :  name = name of conditional block
+ *          3  :  choose_first = nonzero for first, zero for second.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err map_conditional(struct map *exports, const char *name, int choose_first)
+{
+   char buf[1000]; /* Will do, since the names are hardwired */
+   jb_err err;
+
+   assert(exports);
+   assert(name);
+   assert(strlen(name) < 480);
+
+   snprintf(buf, 1000, (choose_first
+      ? "else-not-%s@.*@endif-%s"
+      : "if-%s-then@.*@else-not-%s"),
+      name, name);
+
+   err = map(exports, buf, 1, "", 1);
+   if (err)
+   {
+      return err;
+   }
+
+   snprintf(buf, 1000, (choose_first ? "if-%s-then" : "endif-%s"), name);
+   return map(exports, buf, 1, "", 1);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  make_menu
+ *
+ * Description :  Returns an HTML-formatted menu of the available 
+ *                unhidden CGIs, excluding the one given in <self>
+ *
+ * Parameters  :  self = name of CGI to leave out, can be NULL for
+ *                complete listing.
+ *
+ * Returns     :  menu string, or NULL on out-of-memory error.
+ *
+ *********************************************************************/
+char *make_menu(const char *self)
+{
+   const struct cgi_dispatcher *d;
+   char *result = strdup("");
+
+   if (self == NULL)
+   {
+      self = "NO-SUCH-CGI!";
+   }
+
+   /* List available unhidden CGI's and export as "other-cgis" */
+   for (d = cgi_dispatchers; d->name; d++)
+   {
+      if (d->description && strcmp(d->name, self))
+      {
+         string_append(&result, "<li><a href=\"" CGI_PREFIX);
+         string_append(&result, d->name);
+         string_append(&result, "\">");
+         string_append(&result, d->description);
+         string_append(&result, "</a></li>");
+      }
+   }
+
+   return result;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  dump_map
+ *
+ * Description :  HTML-dump a map for debugging (as table)
+ *
+ * Parameters  :
+ *          1  :  the_map = map to dump
+ *
+ * Returns     :  string with HTML
+ *
+ *********************************************************************/
+char *dump_map(const struct map *the_map)
+{
+   struct map_entry *cur_entry;
+   char *ret = strdup("");
+
+   string_append(&ret, "<table>\n");
+
+   for (cur_entry = the_map->first;
+        (cur_entry != NULL) && (ret != NULL);
+        cur_entry = cur_entry->next)
+   {
+      string_append(&ret, "<tr><td><b>");
+      string_join  (&ret, html_encode(cur_entry->name));
+      string_append(&ret, "</b></td><td>");
+      string_join  (&ret, html_encode(cur_entry->value));
+      string_append(&ret, "</td></tr>\n");
+   }
+
+   string_append(&ret, "</table>\n");
+   return ret;
+}
+
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/cgi.h b/cgi.h
new file mode 100644 (file)
index 0000000..39c6938
--- /dev/null
+++ b/cgi.h
@@ -0,0 +1,245 @@
+#ifndef CGI_H_INCLUDED
+#define CGI_H_INCLUDED
+#define CGI_H_VERSION "$Id: cgi.h,v 1.28 2002/04/26 12:54:03 oes Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/cgi.h,v $
+ *
+ * Purpose     :  Declares functions to intercept request, generate
+ *                html or gif answers, and to compose HTTP resonses.
+ *                
+ *                Functions declared include:
+ * 
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: cgi.h,v $
+ *    Revision 1.28  2002/04/26 12:54:03  oes
+ *    New function add_help_link
+ *
+ *    Revision 1.27  2002/04/24 02:16:51  oes
+ *    Moved get_char_param, get_string_param and get_number_param here from cgiedit.c
+ *
+ *    Revision 1.26  2002/04/10 13:38:35  oes
+ *    load_template signature changed
+ *
+ *    Revision 1.25  2002/04/08 20:50:25  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.24  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.23  2002/03/24 16:18:15  jongfoster
+ *    Removing old logo
+ *
+ *    Revision 1.22  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.21  2002/03/07 03:48:38  oes
+ *     - Changed built-in images from GIF to PNG
+ *       (with regard to Unisys patent issue)
+ *     - Added a 4x4 pattern PNG which is less intrusive
+ *       than the logo but also clearly marks the deleted banners
+ *
+ *    Revision 1.20  2002/03/04 17:53:22  oes
+ *    Fixed compiled warning
+ *
+ *    Revision 1.19  2002/01/21 00:33:52  jongfoster
+ *    Adding map_block_keep() to save a few bytes in the edit-actions-list HTML.
+ *
+ *    Revision 1.18  2001/11/16 00:46:31  jongfoster
+ *    Fixing compiler warnings
+ *
+ *    Revision 1.17  2001/10/23 21:48:19  jongfoster
+ *    Cleaning up error handling in CGI functions - they now send back
+ *    a HTML error page and should never cause a FATAL error.  (Fixes one
+ *    potential source of "denial of service" attacks).
+ *
+ *    CGI actions file editor that works and is actually useful.
+ *
+ *    Ability to toggle Junkbuster remotely using a CGI call.
+ *
+ *    You can turn off both the above features in the main configuration
+ *    file, e.g. if you are running a multi-user proxy.
+ *
+ *    Revision 1.16  2001/09/16 17:08:54  jongfoster
+ *    Moving simple CGI functions from cgi.c to new file cgisimple.c
+ *
+ *    Revision 1.15  2001/09/16 15:02:35  jongfoster
+ *    Adding i.j.b/robots.txt.
+ *    Inlining add_stats() since it's only ever called from one place.
+ *
+ *    Revision 1.14  2001/09/16 11:38:02  jongfoster
+ *    Splitting fill_template() into 2 functions:
+ *    template_load() loads the file
+ *    template_fill() performs the PCRS regexps.
+ *    This is because the CGI edit interface has a "table row"
+ *    template which is used many times in the page - this
+ *    change means it's only loaded from disk once.
+ *
+ *    Revision 1.13  2001/09/16 11:00:10  jongfoster
+ *    New function alloc_http_response, for symmetry with free_http_response
+ *
+ *    Revision 1.12  2001/09/13 23:31:25  jongfoster
+ *    Moving image data to cgi.c rather than cgi.h.
+ *
+ *    Revision 1.11  2001/08/05 16:06:20  jongfoster
+ *    Modifiying "struct map" so that there are now separate header and
+ *    "map_entry" structures.  This means that functions which modify a
+ *    map no longer need to return a pointer to the modified map.
+ *    Also, it no longer reverses the order of the entries (which may be
+ *    important with some advanced template substitutions).
+ *
+ *    Revision 1.10  2001/08/01 21:19:22  jongfoster
+ *    Moving file version information to a separate CGI page.
+ *
+ *    Revision 1.9  2001/08/01 00:17:54  jongfoster
+ *    Adding prototype for map_conditional
+ *
+ *    Revision 1.8  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.7  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.6  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.5  2001/06/29 13:22:44  oes
+ *    - Cleaned up
+ *    - Added new functions: default_exports(), make_menu(),
+ *      error_response() etc, ranamed others and changed
+ *      param and return types.
+ *    - Removed HTTP/HTML snipplets
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.4  2001/06/09 10:50:58  jongfoster
+ *    Changing "show URL info" handler to new style.
+ *    Adding "extern" to some function prototypes.
+ *
+ *    Revision 1.3  2001/06/03 19:12:16  oes
+ *    introduced new cgi handling
+ *
+ *    No revisions before 1.3
+ *
+ **********************************************************************/
+\f
+
+#include "project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Main dispatch function
+ */
+extern struct http_response *dispatch_cgi(struct client_state *csp);
+
+/* Not exactly a CGI */
+extern struct http_response * error_response(struct client_state *csp,
+                                             const char *templatename,
+                                             int err);
+
+/*
+ * CGI support functions
+ */
+extern struct http_response * alloc_http_response(void);
+extern void free_http_response(struct http_response *rsp);
+
+extern struct http_response *finish_http_response(struct http_response *rsp);
+
+extern struct map * default_exports(const struct client_state *csp, const char *caller);
+
+extern jb_err map_block_killer (struct map *exports, const char *name);
+extern jb_err map_block_keep   (struct map *exports, const char *name);
+extern jb_err map_conditional  (struct map *exports, const char *name, int choose_first);
+
+extern jb_err template_load(struct client_state *csp, char ** template_ptr, 
+                            const char *templatename, int recursive);
+extern jb_err template_fill(char ** template_ptr, const struct map *exports);
+extern jb_err template_fill_for_cgi(struct client_state *csp,
+                                    const char *templatename,
+                                    struct map *exports,
+                                    struct http_response *rsp);
+
+extern void cgi_init_error_messages(void);
+extern struct http_response *cgi_error_memory(void);
+extern jb_err cgi_error_no_template(struct client_state *csp,
+                                    struct http_response *rsp,
+                                    const char *template_name);
+extern jb_err cgi_error_bad_param(struct client_state *csp,
+                                  struct http_response *rsp);
+jb_err cgi_error_unknown(struct client_state *csp,
+                         struct http_response *rsp,
+                         jb_err error_to_report);
+
+extern jb_err get_number_param(struct client_state *csp,
+                               const struct map *parameters,
+                               char *name,
+                               unsigned *pvalue);
+extern jb_err get_string_param(const struct map *parameters,
+                               const char *param_name,
+                               const char **pparam);
+extern char   get_char_param(const struct map *parameters,
+                             const char *param_name);
+
+/*
+ * Text generators
+ */
+extern void get_http_time(int time_offset, char * buf);
+extern char *add_help_link(const char *item, struct configuration_spec *config);
+extern char *make_menu(const char *self);
+extern char *dump_map(const struct map *the_map);
+
+/*
+ * Ad replacement images
+ */
+extern const char image_pattern_data[];
+extern const size_t  image_pattern_length;
+extern const char image_blank_data[];
+extern const size_t  image_blank_length;
+
+/* Revision control strings from this header and associated .c file */
+extern const char cgi_rcs[];
+extern const char cgi_h_rcs[];
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef CGI_H_INCLUDED */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/cgiedit.c b/cgiedit.c
new file mode 100644 (file)
index 0000000..0f0e46d
--- /dev/null
+++ b/cgiedit.c
@@ -0,0 +1,4710 @@
+const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.40 2002/05/19 11:34:35 jongfoster Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/cgiedit.c,v $
+ *
+ * Purpose     :  CGI-based actionsfile editor.
+ *
+ *                Functions declared include: cgi_edit_*
+ *
+ *                NOTE: The CGIs in this file use parameter names
+ *                such as "f" and "s" which are really *BAD* choices.
+ *                However, I'm trying to save bytes in the
+ *                edit-actions-list HTML page - the standard actions
+ *                file generated a 550kbyte page, which is ridiculous.
+ *
+ *                Stick to the short names in this file for consistency.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: cgiedit.c,v $
+ *    Revision 1.40  2002/05/19 11:34:35  jongfoster
+ *    Handling read-only actions files better - report the actual
+ *    error, not "Out of memory"!
+ *
+ *    Bug report:
+ *    http://sourceforge.net/tracker/index.php?func=detail
+ *    &aid=557905&group_id=11118&atid=111118
+ *
+ *    Revision 1.39  2002/05/12 21:39:15  jongfoster
+ *    - Adding Doxygen-style comments to structures and #defines.
+ *    - Correcting function comments
+ *
+ *    Revision 1.38  2002/05/03 23:00:38  jongfoster
+ *    Support for templates for "standard actions" buttons.
+ *    See bug #549871
+ *
+ *    Revision 1.37  2002/04/30 11:14:52  oes
+ *    Made csp the first parameter in *action_to_html
+ *
+ *    Revision 1.36  2002/04/26 21:53:30  jongfoster
+ *    Fixing a memory leak.  (Near, but not caused by, my earlier commit).
+ *
+ *    Revision 1.35  2002/04/26 21:50:02  jongfoster
+ *    Honouring default exports in edit-actions-for-url-filter template.
+ *
+ *    Revision 1.34  2002/04/26 12:54:17  oes
+ *    Adaptions to changes in actions.c
+ *
+ *    Revision 1.33  2002/04/24 02:17:47  oes
+ *     - Moved get_char_param, get_string_param and get_number_param to cgi.c
+ *     - Comments
+ *     - Activated Jon's code for editing multiple AFs
+ *     - cgi_edit_list_actions now provides context-sensitive
+ *       help, looks up all action sets from standard.action and
+ *       makes buttons for them in the catchall section
+ *     - cgi_edit_action_submit now honors a p parameter, looks up
+ *       the corresponding action set, and sets the catchall pattern's
+ *       actions accordingly.
+ *
+ *    Revision 1.32  2002/04/19 16:55:31  jongfoster
+ *    Fixing newline problems.  If we do our own text file newline
+ *    mangling, we don't want the library to do any, so we need to
+ *    open the files in *binary* mode.
+ *
+ *    Revision 1.31  2002/04/18 19:21:08  jongfoster
+ *    Added code to detect "conventional" action files, that start
+ *    with a set of actions for all URLs (the pattern "/").
+ *    These are special-cased in the "edit-actions-list" CGI, so
+ *    that a special UI can be written for them.
+ *
+ *    Revision 1.30  2002/04/10 13:38:35  oes
+ *    load_template signature changed
+ *
+ *    Revision 1.29  2002/04/08 16:59:08  oes
+ *    Fixed comment
+ *
+ *    Revision 1.28  2002/03/27 12:30:29  oes
+ *    Deleted unsused variable
+ *
+ *    Revision 1.27  2002/03/26 23:06:04  jongfoster
+ *    Removing duplicate @ifs on the toggle page
+ *
+ *    Revision 1.26  2002/03/26 22:59:17  jongfoster
+ *    Fixing /toggle to display status consistently.
+ *
+ *    Revision 1.25  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.24  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.23  2002/03/24 13:32:41  swa
+ *    name change related issues
+ *
+ *    Revision 1.22  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.21  2002/03/22 18:02:48  jongfoster
+ *    Fixing remote toggle
+ *
+ *    Revision 1.20  2002/03/16 20:28:34  oes
+ *    Added descriptions to the filters so users will know what they select in the cgi editor
+ *
+ *    Revision 1.19  2002/03/16 18:38:14  jongfoster
+ *    Stopping stupid or malicious users from breaking the actions
+ *    file using the web-based editor.
+ *
+ *    Revision 1.18  2002/03/16 14:57:44  jongfoster
+ *    Full support for enabling/disabling modular filters.
+ *
+ *    Revision 1.17  2002/03/16 14:26:42  jongfoster
+ *    First version of modular filters support - READ ONLY!
+ *    Fixing a double-free bug in the out-of-memory handling in map_radio().
+ *
+ *    Revision 1.16  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.15  2002/03/06 22:54:35  jongfoster
+ *    Automated function-comment nitpicking.
+ *
+ *    Revision 1.14  2002/03/05 00:24:51  jongfoster
+ *    Patch to always edit the current actions file.
+ *
+ *    Revision 1.13  2002/03/04 02:07:59  david__schmidt
+ *    Enable web editing of actions file on OS/2 (it had been broken all this time!)
+ *
+ *    Revision 1.12  2002/03/03 09:18:03  joergs
+ *    Made jumbjuster work on AmigaOS again.
+ *
+ *    Revision 1.11  2002/01/23 01:03:31  jongfoster
+ *    Fixing gcc [CygWin] compiler warnings
+ *
+ *    Revision 1.10  2002/01/23 00:22:59  jongfoster
+ *    Adding new function cgi_edit_actions_section_swap(), to reorder
+ *    the actions file.
+ *
+ *    Adding get_url_spec_param() to get a validated URL pattern.
+ *
+ *    Moving edit_read_line() out of this file and into loaders.c.
+ *
+ *    Adding missing html_encode() to many CGI functions.
+ *
+ *    Moving the functions that #include actionlist.h to the end of the file,
+ *    because the Visual C++ 97 debugger gets extremely confused if you try
+ *    to debug any code that comes after them in the file.
+ *
+ *    Major optimizations in cgi_edit_actions_list() to reduce the size of
+ *    the generated HTML (down 40% from 550k to 304k), with major side-effects
+ *    throughout the editor and templates.  In particular, the length of the
+ *    URLs throughout the editor has been drastically reduced, by cutting
+ *    paramater names down to 1 character and CGI names down to 3-4
+ *    characters, by removing all non-essential CGI paramaters even at the
+ *    expense of having to re-read the actions file for the most trivial
+ *    page, and by using relative rather than absolute URLs.  This means
+ *    that this (typical example):
+ *
+ *    <a href="http://ijbswa.sourceforge.net/config/edit-actions-url-form?
+ *    filename=ijb&amp;ver=1011487572&amp;section=12&amp;pattern=13
+ *    &amp;oldval=www.oesterhelt.org%2Fdeanimate-demo">
+ *
+ *    is now this:
+ *
+ *    <a href="eau?f=ijb&amp;v=1011487572&amp;p=13">
+ *
+ *    Revision 1.9  2002/01/17 20:56:22  jongfoster
+ *    Replacing hard references to the URL of the config interface
+ *    with #defines from project.h
+ *
+ *    Revision 1.8  2001/11/30 23:35:51  jongfoster
+ *    Renaming actionsfile to ijb.action
+ *
+ *    Revision 1.7  2001/11/13 00:28:24  jongfoster
+ *    - Renaming parameters from edit-actions-for-url so that they only
+ *      contain legal JavaScript characters.  If we wanted to write
+ *      JavaScript that worked with Netscape 4, this is nessacery.
+ *      (Note that at the moment the JavaScript doesn't actually work
+ *      with Netscape 4, but now this is purely a template issue, not
+ *      one affecting code).
+ *    - Adding new CGIs for use by non-JavaScript browsers:
+ *        edit-actions-url-form
+ *        edit-actions-add-url-form
+ *        edit-actions-remove-url-form
+ *    - Fixing || bug.
+ *
+ *    Revision 1.6  2001/10/29 03:48:09  david__schmidt
+ *    OS/2 native needed a snprintf() routine.  Added one to miscutil, brackedted
+ *    by and __OS2__ ifdef.
+ *
+ *    Revision 1.5  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.4  2001/10/23 21:48:19  jongfoster
+ *    Cleaning up error handling in CGI functions - they now send back
+ *    a HTML error page and should never cause a FATAL error.  (Fixes one
+ *    potential source of "denial of service" attacks).
+ *
+ *    CGI actions file editor that works and is actually useful.
+ *
+ *    Ability to toggle JunkBuster remotely using a CGI call.
+ *
+ *    You can turn off both the above features in the main configuration
+ *    file, e.g. if you are running a multi-user proxy.
+ *
+ *    Revision 1.3  2001/10/14 22:12:49  jongfoster
+ *    New version of CGI-based actionsfile editor.
+ *    Major changes, including:
+ *    - Completely new file parser and file output routines
+ *    - edit-actions CGI renamed edit-actions-for-url
+ *    - All CGIs now need a filename parameter, except for...
+ *    - New CGI edit-actions which doesn't need a filename,
+ *      to allow you to start the editor up.
+ *    - edit-actions-submit now works, and now automatically
+ *      redirects you back to the main edit-actions-list handler.
+ *
+ *    Revision 1.2  2001/09/16 17:05:14  jongfoster
+ *    Removing unused #include showarg.h
+ *
+ *    Revision 1.1  2001/09/16 15:47:37  jongfoster
+ *    First version of CGI-based edit interface.  This is very much a
+ *    work-in-progress, and you can't actually use it to edit anything
+ *    yet.  You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
+ *    to have any effect.
+ *
+ *
+ **********************************************************************/
+\f
+
+#include "config.h"
+
+/*
+ * FIXME: Following includes copied from cgi.c - which are actually needed?
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#endif /* def _WIN32 */
+
+#include "project.h"
+#include "cgi.h"
+#include "cgiedit.h"
+#include "cgisimple.h"
+#include "list.h"
+#include "encode.h"
+#include "actions.h"
+#include "miscutil.h"
+#include "errlog.h"
+#include "loaders.h"
+#include "loadcfg.h"
+/* loadcfg.h is for g_bToggleIJB only */
+#include "urlmatch.h"
+
+const char cgiedit_h_rcs[] = CGIEDIT_H_VERSION;
+
+
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+
+/**
+ * A line in an editable_file.
+ */
+struct file_line
+{
+   /** Next entry in the linked list */
+   struct file_line * next;
+   
+   /** The raw data, to write out if this line is unmodified. */
+   char * raw;
+   
+   /** Comments and/or whitespace to put before this line if it's modified
+       and then written out. */
+   char * prefix;
+
+   /** The actual data, as a string.  Line continuation and comment removal
+       are performed on the data read from file before it's stored here, so
+       it will be a single line of data.  */
+   char * unprocessed;
+   
+   /** The type of data on this line.  One of the FILE_LINE_xxx constants. */
+   int type;
+
+   /** The actual data, processed into some sensible data type. */
+   union
+   {
+
+      /** An action specification. */
+      struct action_spec action[1];
+
+      /** A name=value pair. */
+      struct
+      {
+
+         /** The name in the name=value pair. */
+         char * name;
+
+         /** The value in the name=value pair, as a string. */
+         char * svalue;
+
+         /** The value in the name=value pair, as an integer. */
+         int ivalue;
+
+      } setting;
+
+      /* Add more data types here... e.g.
+
+
+      struct url_spec url[1];
+
+      struct
+      {
+         struct action_spec action[1];
+         const char * name;
+      } alias;
+
+      */
+
+   } data;
+
+};
+
+/** This file_line has not been processed yet. */
+#define FILE_LINE_UNPROCESSED           1
+
+/** This file_line is blank. Can only appear at the end of a file, due to
+    the way the parser works. */
+#define FILE_LINE_BLANK                 2
+
+/** This file_line says {{alias}}. */
+#define FILE_LINE_ALIAS_HEADER          3
+
+/** This file_line defines an alias. */
+#define FILE_LINE_ALIAS_ENTRY           4
+
+/** This file_line defines an {action}. */
+#define FILE_LINE_ACTION                5
+
+/** This file_line specifies a URL pattern. */
+#define FILE_LINE_URL                   6
+
+/** This file_line says {{settings}}. */
+#define FILE_LINE_SETTINGS_HEADER       7
+
+/** This file_line is in a {{settings}} block. */
+#define FILE_LINE_SETTINGS_ENTRY        8
+
+/** This file_line says {{description}}. */
+#define FILE_LINE_DESCRIPTION_HEADER    9
+
+/** This file_line is in a {{description}} block. */
+#define FILE_LINE_DESCRIPTION_ENTRY    10
+
+
+/**
+ * A configuration file, in a format that can be edited and written back to
+ * disk.
+ */
+struct editable_file
+{
+   struct file_line * lines;  /**< The contents of the file.  A linked list of lines. */
+   const char * filename;     /**< Full pathname - e.g. "/etc/privoxy/wibble.action". */
+   const char * identifier;   /**< Filename stub - e.g. "wibble".  Use for CGI param. */
+                              /**< Pre-encoded with url_encode() for ease of use. */
+   const char * version_str;  /**< Last modification time, as a string.  For CGI param. */
+                              /**< Can be used in URL without using url_param(). */
+   unsigned version;          /**< Last modification time - prevents chaos with
+                                   the browser's "back" button.  Note that this is a
+                                   time_t cast to an unsigned.  When comparing, always
+                                   cast the time_t to an unsigned, and *NOT* vice-versa.
+                                   This may lose the top few bits, but they're not
+                                   significant anyway. */
+   int newline;               /**< Newline convention - one of the NEWLINE_xxx constants.
+                                   Note that changing this after the file has been
+                                   read in will cause a mess. */
+   struct file_line * parse_error; /**< On parse error, this is the offending line. */
+   const char * parse_error_text;  /**< On parse error, this is the problem.
+                                        (Statically allocated) */
+};
+
+/* FIXME: Following non-static functions should be prototyped in .h or made static */
+
+/* Functions to read and write arbitrary config files */
+jb_err edit_read_file(struct client_state *csp,
+                      const struct map *parameters,
+                      int require_version,
+                      const char *suffix,
+                      struct editable_file **pfile);
+jb_err edit_write_file(struct editable_file * file);
+void   edit_free_file(struct editable_file * file);
+
+/* Functions to read and write actions files */
+jb_err edit_parse_actions_file(struct editable_file * file);
+jb_err edit_read_actions_file(struct client_state *csp,
+                              struct http_response *rsp,
+                              const struct map *parameters,
+                              int require_version,
+                              struct editable_file **pfile);
+
+/* Error handlers */
+jb_err cgi_error_modified(struct client_state *csp,
+                          struct http_response *rsp,
+                          const char *filename);
+jb_err cgi_error_parse(struct client_state *csp,
+                       struct http_response *rsp,
+                       struct editable_file *file);
+jb_err cgi_error_file(struct client_state *csp,
+                      struct http_response *rsp,
+                      const char *filename);
+jb_err cgi_error_file_read_only(struct client_state *csp,
+                                struct http_response *rsp,
+                                const char *filename);
+jb_err cgi_error_disabled(struct client_state *csp,
+                          struct http_response *rsp);
+
+/* Internal arbitrary config file support functions */
+static jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline);
+static void edit_free_file_lines(struct file_line * first_line);
+
+/* Internal actions file support functions */
+static int match_actions_file_header_line(const char * line, const char * name);
+static jb_err split_line_on_equals(const char * line, char ** pname, char ** pvalue);
+
+/* Internal parameter parsing functions */
+static jb_err get_file_name_param(struct client_state *csp,
+                                  const struct map *parameters,
+                                  const char *param_name,
+                                  const char *suffix,
+                                  char **pfilename,
+                                  const char **pparam);
+
+static jb_err get_url_spec_param(struct client_state *csp,
+                                 const struct map *parameters,
+                                 const char *name,
+                                 char **pvalue);
+
+
+/* Internal actionsfile <==> HTML conversion functions */
+static jb_err map_radio(struct map * exports,
+                        const char * optionname,
+                        const char * values,
+                        int value);
+static jb_err actions_to_radio(struct map * exports,
+                               const struct action_spec *action);
+static jb_err actions_from_radio(const struct map * parameters,
+                                 struct action_spec *action);
+
+
+static jb_err map_copy_parameter_html(struct map *out,
+                                      const struct map *in,
+                                      const char *name);
+#if 0 /* unused function */
+static jb_err map_copy_parameter_url(struct map *out,
+                                     const struct map *in,
+                                     const char *name);
+#endif /* unused function */
+
+/* Internal convenience functions */
+static char *section_target(const unsigned sectionid);
+
+/*********************************************************************
+ *
+ * Function    :  section_target
+ *
+ * Description :  Given an unsigned (section id) n, produce a dynamically
+ *                allocated string of the form #l<n>, for use in link
+ *                targets.
+ *
+ * Parameters  :
+ *          1  :  sectionid = start line number of section
+ *
+ * Returns     :  String with link target, or NULL if out of
+ *                memory
+ *
+ *********************************************************************/
+static char *section_target(const unsigned sectionid)
+{
+   char buf[30];
+
+   snprintf(buf, 30, "#l%d", sectionid);
+   return(strdup(buf));
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  map_copy_parameter_html
+ *
+ * Description :  Copy a CGI parameter from one map to another, HTML
+ *                encoding it.
+ *
+ * Parameters  :
+ *          1  :  out = target map
+ *          2  :  in = source map
+ *          3  :  name = name of cgi parameter to copy
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the parameter doesn't exist
+ *                                  in the source map
+ *
+ *********************************************************************/
+static jb_err map_copy_parameter_html(struct map *out,
+                                      const struct map *in,
+                                      const char *name)
+{
+   const char * value;
+   jb_err err;
+
+   assert(out);
+   assert(in);
+   assert(name);
+
+   value = lookup(in, name);
+   err = map(out, name, 1, html_encode(value), 0);
+
+   if (err)
+   {
+      /* Out of memory */
+      return err;
+   }
+   else if (*value == '\0')
+   {
+      return JB_ERR_CGI_PARAMS;
+   }
+   else
+   {
+      return JB_ERR_OK;
+   }
+}
+
+
+#if 0 /* unused function */
+/*********************************************************************
+ *
+ * Function    :  map_copy_parameter_url
+ *
+ * Description :  Copy a CGI parameter from one map to another, URL
+ *                encoding it.
+ *
+ * Parameters  :
+ *          1  :  out = target map
+ *          2  :  in = source map
+ *          3  :  name = name of cgi parameter to copy
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the parameter doesn't exist
+ *                                  in the source map
+ *
+ *********************************************************************/
+static jb_err map_copy_parameter_url(struct map *out,
+                                     const struct map *in,
+                                     const char *name)
+{
+   const char * value;
+   jb_err err;
+
+   assert(out);
+   assert(in);
+   assert(name);
+
+   value = lookup(in, name);
+   err = map(out, name, 1, url_encode(value), 0);
+
+   if (err)
+   {
+      /* Out of memory */
+      return err;
+   }
+   else if (*value == '\0')
+   {
+      return JB_ERR_CGI_PARAMS;
+   }
+   else
+   {
+      return JB_ERR_OK;
+   }
+}
+#endif /* 0 - unused function */
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_url_form
+ *
+ * Description :  CGI function that displays a form for
+ *                edit-actions-url
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters
+ *           f : (filename) Identifies the file to edit
+ *           v : (version) File's last-modified time
+ *           p : (pattern) Line number of pattern to edit
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_url_form(struct client_state *csp,
+                                 struct http_response *rsp,
+                                 const struct map *parameters)
+{
+   struct map * exports;
+   unsigned patternid;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number;
+   unsigned section_start_line_number = 0;
+   jb_err err;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "p", &patternid);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   cur_line = file->lines;
+
+   for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++)
+   {
+      if (cur_line->type == FILE_LINE_ACTION)
+      {
+         section_start_line_number = line_number;
+      }
+      cur_line = cur_line->next;
+   }
+
+   if ( (cur_line == NULL)
+     || (line_number != patternid)
+     || (patternid < 1)
+     || (cur_line->type != FILE_LINE_URL))
+   {
+      /* Invalid "patternid" parameter */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   err = map(exports, "f", 1, file->identifier, 1);
+   if (!err) err = map(exports, "v", 1, file->version_str, 1);
+   if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
+   if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
+   if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
+
+   edit_free_file(file);
+
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "edit-actions-url-form", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_add_url_form
+ *
+ * Description :  CGI function that displays a form for
+ *                edit-actions-url
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *           f : (filename) Identifies the file to edit
+ *           v : (version) File's last-modified time
+ *           s : (section) Line number of section to edit
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_add_url_form(struct client_state *csp,
+                                     struct http_response *rsp,
+                                     const struct map *parameters)
+{
+   struct map *exports;
+   jb_err err;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   err = map_copy_parameter_html(exports, parameters, "f");
+   if (!err) err = map_copy_parameter_html(exports, parameters, "v");
+   if (!err) err = map_copy_parameter_html(exports, parameters, "s");
+
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "edit-actions-add-url-form", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_remove_url_form
+ *
+ * Description :  CGI function that displays a form for
+ *                edit-actions-url
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *           f : (filename) Identifies the file to edit
+ *           v : (version) File's last-modified time
+ *           p : (pattern) Line number of pattern to edit
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_remove_url_form(struct client_state *csp,
+                                     struct http_response *rsp,
+                                     const struct map *parameters)
+{
+   struct map * exports;
+   unsigned patternid;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number;
+   unsigned section_start_line_number = 0;
+   jb_err err;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "p", &patternid);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   cur_line = file->lines;
+
+   for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++)
+   {
+      if (cur_line->type == FILE_LINE_ACTION)
+      {
+         section_start_line_number = line_number;
+      }      
+      cur_line = cur_line->next;
+   }
+
+   if ( (cur_line == NULL)
+     || (line_number != patternid)
+     || (patternid < 1)
+     || (cur_line->type != FILE_LINE_URL))
+   {
+      /* Invalid "patternid" parameter */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   err = map(exports, "f", 1, file->identifier, 1);
+   if (!err) err = map(exports, "v", 1, file->version_str, 1);
+   if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
+   if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
+   if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
+
+   edit_free_file(file);
+
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "edit-actions-remove-url-form", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  edit_write_file
+ *
+ * Description :  Write a complete file to disk.
+ *
+ * Parameters  :
+ *          1  :  file = File to write.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_FILE   on error writing to file.
+ *                JB_ERR_MEMORY on out of memory
+ *
+ *********************************************************************/
+jb_err edit_write_file(struct editable_file * file)
+{
+   FILE * fp;
+   struct file_line * cur_line;
+   struct stat statbuf[1];
+   char version_buf[22]; /* 22 = ceil(log10(2^64)) + 2 = max number of
+                            digits in time_t, assuming this is a 64-bit
+                            machine, plus null terminator, plus one
+                            for paranoia */
+
+   assert(file);
+   assert(file->filename);
+
+   if (NULL == (fp = fopen(file->filename, "wb")))
+   {
+      return JB_ERR_FILE;
+   }
+
+   cur_line = file->lines;
+   while (cur_line != NULL)
+   {
+      if (cur_line->raw)
+      {
+         if (fputs(cur_line->raw, fp) < 0)
+         {
+            fclose(fp);
+            return JB_ERR_FILE;
+         }
+      }
+      else
+      {
+         if (cur_line->prefix)
+         {
+            if (fputs(cur_line->prefix, fp) < 0)
+            {
+               fclose(fp);
+               return JB_ERR_FILE;
+            }
+         }
+         if (cur_line->unprocessed)
+         {
+
+            if (NULL != strchr(cur_line->unprocessed, '#'))
+            {
+               /* Must quote '#' characters */
+               int numhash = 0;
+               int len;
+               char * src;
+               char * dest;
+               char * str;
+
+               /* Count number of # characters, so we know length of output string */
+               src = cur_line->unprocessed;
+               while (NULL != (src = strchr(src, '#')))
+               {
+                  numhash++;
+                  src++;
+               }
+               assert(numhash > 0);
+
+               /* Allocate new memory for string */
+               len = strlen(cur_line->unprocessed);
+               if (NULL == (str = malloc((size_t) len + 1 + numhash)))
+               {
+                  /* Uh oh, just trashed file! */
+                  fclose(fp);
+                  return JB_ERR_MEMORY;
+               }
+
+               /* Loop through string from end */
+               src  = cur_line->unprocessed + len;
+               dest = str + len + numhash;
+               for ( ; len >= 0; len--)
+               {
+                  if ((*dest-- = *src--) == '#')
+                  {
+                     *dest-- = '\\';
+                     numhash--;
+                     assert(numhash >= 0);
+                  }
+               }
+               assert(numhash == 0);
+               assert(src  + 1 == cur_line->unprocessed);
+               assert(dest + 1 == str);
+
+               if (fputs(str, fp) < 0)
+               {
+                  free(str);
+                  fclose(fp);
+                  return JB_ERR_FILE;
+               }
+
+               free(str);
+            }
+            else
+            {
+               /* Can write without quoting '#' characters. */
+               if (fputs(cur_line->unprocessed, fp) < 0)
+               {
+                  fclose(fp);
+                  return JB_ERR_FILE;
+               }
+            }
+            if (fputs(NEWLINE(file->newline), fp) < 0)
+            {
+               fclose(fp);
+               return JB_ERR_FILE;
+            }
+         }
+         else
+         {
+            /* FIXME: Write data from file->data->whatever */
+            assert(0);
+         }
+      }
+      cur_line = cur_line->next;
+   }
+
+   fclose(fp);
+
+
+   /* Update the version stamp in the file structure, since we just
+    * wrote to the file & changed it's date.
+    */
+   if (stat(file->filename, statbuf) < 0)
+   {
+      /* Error, probably file not found. */
+      return JB_ERR_FILE;
+   }
+   file->version = (unsigned)statbuf->st_mtime;
+
+   /* Correct file->version_str */
+   freez(file->version_str);
+   snprintf(version_buf, 22, "%u", file->version);
+   version_buf[21] = '\0';
+   file->version_str = strdup(version_buf);
+   if (version_buf == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  edit_free_file
+ *
+ * Description :  Free a complete file in memory.
+ *
+ * Parameters  :
+ *          1  :  file = Data structure to free.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void edit_free_file(struct editable_file * file)
+{
+   if (!file)
+   {
+      /* Silently ignore NULL pointer */
+      return;
+   }
+
+   edit_free_file_lines(file->lines);
+   freez(file->filename);
+   freez(file->identifier);
+   freez(file->version_str);
+   file->version = 0;
+   file->parse_error_text = NULL; /* Statically allocated */
+   file->parse_error = NULL;
+
+   free(file);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  edit_free_file_lines
+ *
+ * Description :  Free an entire linked list of file lines.
+ *
+ * Parameters  :
+ *          1  :  first_line = Data structure to free.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void edit_free_file_lines(struct file_line * first_line)
+{
+   struct file_line * next_line;
+
+   while (first_line != NULL)
+   {
+      next_line = first_line->next;
+      first_line->next = NULL;
+      freez(first_line->raw);
+      freez(first_line->prefix);
+      freez(first_line->unprocessed);
+      switch(first_line->type)
+      {
+         case 0: /* special case if memory zeroed */
+         case FILE_LINE_UNPROCESSED:
+         case FILE_LINE_BLANK:
+         case FILE_LINE_ALIAS_HEADER:
+         case FILE_LINE_SETTINGS_HEADER:
+         case FILE_LINE_DESCRIPTION_HEADER:
+         case FILE_LINE_DESCRIPTION_ENTRY:
+         case FILE_LINE_ALIAS_ENTRY:
+         case FILE_LINE_URL:
+            /* No data is stored for these */
+            break;
+
+         case FILE_LINE_ACTION:
+            free_action(first_line->data.action);
+            break;
+
+         case FILE_LINE_SETTINGS_ENTRY:
+            freez(first_line->data.setting.name);
+            freez(first_line->data.setting.svalue);
+            break;
+         default:
+            /* Should never happen */
+            assert(0);
+            break;
+      }
+      first_line->type = 0; /* paranoia */
+      free(first_line);
+      first_line = next_line;
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  match_actions_file_header_line
+ *
+ * Description :  Match an actions file {{header}} line
+ *
+ * Parameters  :
+ *          1  :  line = String from file
+ *          2  :  name = Header to match against
+ *
+ * Returns     :  0 iff they match.
+ *
+ *********************************************************************/
+static int match_actions_file_header_line(const char * line, const char * name)
+{
+   size_t len;
+
+   assert(line);
+   assert(name);
+
+   /* Look for "{{" */
+   if ((line[0] != '{') || (line[1] != '{'))
+   {
+      return 1;
+   }
+   line += 2;
+
+   /* Look for optional whitespace */
+   while ( (*line == ' ') || (*line == '\t') )
+   {
+      line++;
+   }
+
+   /* Look for the specified name (case-insensitive) */
+   len = strlen(name);
+   if (0 != strncmpic(line, name, len))
+   {
+      return 1;
+   }
+   line += len;
+
+   /* Look for optional whitespace */
+   while ( (*line == ' ') || (*line == '\t') )
+   {
+      line++;
+   }
+
+   /* Look for "}}" and end of string*/
+   if ((line[0] != '}') || (line[1] != '}') || (line[2] != '\0'))
+   {
+      return 1;
+   }
+
+   /* It matched!! */
+   return 0;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  match_actions_file_header_line
+ *
+ * Description :  Match an actions file {{header}} line
+ *
+ * Parameters  :
+ *          1  :  line = String from file.  Must not start with
+ *                       whitespace (else infinite loop!)
+ *          2  :  pname = Destination for name
+ *          2  :  pvalue = Destination for value
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_PARSE  if there's no "=" sign, or if there's
+ *                              nothing before the "=" sign (but empty
+ *                              values *after* the "=" sign are legal).
+ *
+ *********************************************************************/
+static jb_err split_line_on_equals(const char * line, char ** pname, char ** pvalue)
+{
+   const char * name_end;
+   const char * value_start;
+   size_t name_len;
+
+   assert(line);
+   assert(pname);
+   assert(pvalue);
+   assert(*line != ' ');
+   assert(*line != '\t');
+
+   *pname = NULL;
+   *pvalue = NULL;
+
+   value_start = strchr(line, '=');
+   if ((value_start == NULL) || (value_start == line))
+   {
+      return JB_ERR_PARSE;
+   }
+
+   name_end = value_start - 1;
+
+   /* Eat any whitespace before the '=' */
+   while ((*name_end == ' ') || (*name_end == '\t'))
+   {
+      /*
+       * we already know we must have at least 1 non-ws char
+       * at start of buf - no need to check
+       */
+      name_end--;
+   }
+
+   name_len = name_end - line + 1; /* Length excluding \0 */
+   if (NULL == (*pname = (char *) malloc(name_len + 1)))
+   {
+      return JB_ERR_MEMORY;
+   }
+   strncpy(*pname, line, name_len);
+   (*pname)[name_len] = '\0';
+
+   /* Eat any the whitespace after the '=' */
+   value_start++;
+   while ((*value_start == ' ') || (*value_start == '\t'))
+   {
+      value_start++;
+   }
+
+   if (NULL == (*pvalue = strdup(value_start)))
+   {
+      free(*pname);
+      *pname = NULL;
+      return JB_ERR_MEMORY;
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  edit_parse_actions_file
+ *
+ * Description :  Parse an actions file in memory.
+ *
+ *                Passed linked list must have the "data" member
+ *                zeroed, and must contain valid "next" and
+ *                "unprocessed" fields.  The "raw" and "prefix"
+ *                fields are ignored, and "type" is just overwritten.
+ *
+ *                Note that on error the file may have been
+ *                partially parsed.
+ *
+ * Parameters  :
+ *          1  :  file = Actions file to be parsed in-place.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_PARSE  on error
+ *
+ *********************************************************************/
+jb_err edit_parse_actions_file(struct editable_file * file)
+{
+   struct file_line * cur_line;
+   size_t len;
+   const char * text; /* Text from a line */
+   char * name;  /* For lines of the form name=value */
+   char * value; /* For lines of the form name=value */
+   struct action_alias * alias_list = NULL;
+   jb_err err = JB_ERR_OK;
+
+   /* alias_list contains the aliases defined in this file.
+    * It might be better to use the "file_line.data" fields
+    * in the relavent places instead.
+    */
+
+   cur_line = file->lines;
+
+   /* A note about blank line support: Blank lines should only
+    * ever occur as the last line in the file.  This function
+    * is more forgiving than that - FILE_LINE_BLANK can occur
+    * anywhere.
+    */
+
+   /* Skip leading blanks.  Should only happen if file is
+    * empty (which is valid, but pointless).
+    */
+   while ( (cur_line != NULL)
+        && (cur_line->unprocessed[0] == '\0') )
+   {
+      /* Blank line */
+      cur_line->type = FILE_LINE_BLANK;
+      cur_line = cur_line->next;
+   }
+
+   if ( (cur_line != NULL)
+     && (cur_line->unprocessed[0] != '{') )
+   {
+      /* File doesn't start with a header */
+      file->parse_error = cur_line;
+      file->parse_error_text = "First (non-comment) line of the file must contain a header.";
+      return JB_ERR_PARSE;
+   }
+
+   if ( (cur_line != NULL) && (0 ==
+      match_actions_file_header_line(cur_line->unprocessed, "settings") ) )
+   {
+      cur_line->type = FILE_LINE_SETTINGS_HEADER;
+
+      cur_line = cur_line->next;
+      while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
+      {
+         if (cur_line->unprocessed[0])
+         {
+            cur_line->type = FILE_LINE_SETTINGS_ENTRY;
+
+            err = split_line_on_equals(cur_line->unprocessed,
+                     &cur_line->data.setting.name,
+                     &cur_line->data.setting.svalue);
+            if (err == JB_ERR_MEMORY)
+            {
+               return err;
+            }
+            else if (err != JB_ERR_OK)
+            {
+               /* Line does not contain a name=value pair */
+               file->parse_error = cur_line;
+               file->parse_error_text = "Expected a name=value pair on this {{description}} line, but couldn't find one.";
+               return JB_ERR_PARSE;
+            }
+         }
+         else
+         {
+            cur_line->type = FILE_LINE_BLANK;
+         }
+         cur_line = cur_line->next;
+      }
+   }
+
+   if ( (cur_line != NULL) && (0 ==
+      match_actions_file_header_line(cur_line->unprocessed, "description") ) )
+   {
+      cur_line->type = FILE_LINE_DESCRIPTION_HEADER;
+
+      cur_line = cur_line->next;
+      while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
+      {
+         if (cur_line->unprocessed[0])
+         {
+            cur_line->type = FILE_LINE_DESCRIPTION_ENTRY;
+         }
+         else
+         {
+            cur_line->type = FILE_LINE_BLANK;
+         }
+         cur_line = cur_line->next;
+      }
+   }
+
+   if ( (cur_line != NULL) && (0 ==
+      match_actions_file_header_line(cur_line->unprocessed, "alias") ) )
+   {
+      cur_line->type = FILE_LINE_ALIAS_HEADER;
+
+      cur_line = cur_line->next;
+      while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
+      {
+         if (cur_line->unprocessed[0])
+         {
+            /* define an alias */
+            struct action_alias * new_alias;
+
+            cur_line->type = FILE_LINE_ALIAS_ENTRY;
+
+            err = split_line_on_equals(cur_line->unprocessed, &name, &value);
+            if (err == JB_ERR_MEMORY)
+            {
+               return err;
+            }
+            else if (err != JB_ERR_OK)
+            {
+               /* Line does not contain a name=value pair */
+               file->parse_error = cur_line;
+               file->parse_error_text = "Expected a name=value pair on this {{alias}} line, but couldn't find one.";
+               return JB_ERR_PARSE;
+            }
+
+            if ((new_alias = zalloc(sizeof(*new_alias))) == NULL)
+            {
+               /* Out of memory */
+               free(name);
+               free(value);
+               free_alias_list(alias_list);
+               return JB_ERR_MEMORY;
+            }
+
+            err = get_actions(value, alias_list, new_alias->action);
+            if (err)
+            {
+               /* Invalid action or out of memory */
+               free(name);
+               free(value);
+               free(new_alias);
+               free_alias_list(alias_list);
+               if (err == JB_ERR_MEMORY)
+               {
+                  return err;
+               }
+               else
+               {
+                  /* Line does not contain a name=value pair */
+                  file->parse_error = cur_line;
+                  file->parse_error_text = "This alias does not specify a valid set of actions.";
+                  return JB_ERR_PARSE;
+               }
+            }
+
+            free(value);
+
+            new_alias->name = name;
+
+            /* add to list */
+            new_alias->next = alias_list;
+            alias_list = new_alias;
+         }
+         else
+         {
+            cur_line->type = FILE_LINE_BLANK;
+         }
+         cur_line = cur_line->next;
+      }
+   }
+
+   /* Header done, process the main part of the file */
+   while (cur_line != NULL)
+   {
+      /* At this point, (cur_line->unprocessed[0] == '{') */
+      assert(cur_line->unprocessed[0] == '{');
+      text = cur_line->unprocessed + 1;
+      len = strlen(text) - 1;
+      if (text[len] != '}')
+      {
+         /* No closing } on header */
+         free_alias_list(alias_list);
+         file->parse_error = cur_line;
+         file->parse_error_text = "Headers starting with '{' must have a "
+            "closing bracket ('}').  Headers starting with two brackets ('{{') "
+            "must close with two brackets ('}}').";
+         return JB_ERR_PARSE;
+      }
+
+      if (text[0] == '{')
+      {
+         /* An invalid {{ header.  */
+         free_alias_list(alias_list);
+         file->parse_error = cur_line;
+         file->parse_error_text = "Unknown or unexpected two-bracket header.  "
+            "Please remember that the system (two-bracket) headers must "
+            "appear in the order {{settings}}, {{description}}, {{alias}}, "
+            "and must appear before any actions (one-bracket) headers.  "
+            "Also note that system headers may not be repeated.";
+         return JB_ERR_PARSE;
+      }
+
+      while ( (*text == ' ') || (*text == '\t') )
+      {
+         text++;
+         len--;
+      }
+      while ( (len > 0)
+           && ( (text[len - 1] == ' ')
+             || (text[len - 1] == '\t') ) )
+      {
+         len--;
+      }
+
+      cur_line->type = FILE_LINE_ACTION;
+
+      /* Remove {} and make copy */
+      if (NULL == (value = (char *) malloc(len + 1)))
+      {
+         /* Out of memory */
+         free_alias_list(alias_list);
+         return JB_ERR_MEMORY;
+      }
+      strncpy(value, text, len);
+      value[len] = '\0';
+
+      /* Get actions */
+      err = get_actions(value, alias_list, cur_line->data.action);
+      if (err)
+      {
+         /* Invalid action or out of memory */
+         free(value);
+         free_alias_list(alias_list);
+         if (err == JB_ERR_MEMORY)
+         {
+            return err;
+         }
+         else
+         {
+            /* Line does not contain a name=value pair */
+            file->parse_error = cur_line;
+            file->parse_error_text = "This header does not specify a valid set of actions.";
+            return JB_ERR_PARSE;
+         }
+      }
+
+      /* Done with string - it was clobbered anyway */
+      free(value);
+
+      /* Process next line */
+      cur_line = cur_line->next;
+
+      /* Loop processing URL patterns */
+      while ((cur_line != NULL) && (cur_line->unprocessed[0] != '{'))
+      {
+         if (cur_line->unprocessed[0])
+         {
+            /* Could parse URL here, but this isn't currently needed */
+
+            cur_line->type = FILE_LINE_URL;
+         }
+         else
+         {
+            cur_line->type = FILE_LINE_BLANK;
+         }
+         cur_line = cur_line->next;
+      }
+   } /* End main while(cur_line != NULL) loop */
+
+   free_alias_list(alias_list);
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  edit_read_file_lines
+ *
+ * Description :  Read all the lines of a file into memory.
+ *                Handles whitespace, comments and line continuation.
+ *
+ * Parameters  :
+ *          1  :  fp = File to read from.  On return, this will be
+ *                     at EOF but it will not have been closed.
+ *          2  :  pfile = Destination for a linked list of file_lines.
+ *                        Will be set to NULL on error.
+ *          3  :  newline = How to handle newlines.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *
+ *********************************************************************/
+jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline)
+{
+   struct file_line * first_line; /* Keep for return value or to free */
+   struct file_line * cur_line;   /* Current line */
+   struct file_line * prev_line;  /* Entry with prev_line->next = cur_line */
+   jb_err rval;
+
+   assert(fp);
+   assert(pfile);
+
+   *pfile = NULL;
+
+   cur_line = first_line = zalloc(sizeof(struct file_line));
+   if (cur_line == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   cur_line->type = FILE_LINE_UNPROCESSED;
+
+   rval = edit_read_line(fp, &cur_line->raw, &cur_line->prefix, &cur_line->unprocessed, newline, NULL);
+   if (rval)
+   {
+      /* Out of memory or empty file. */
+      /* Note that empty file is not an error we propogate up */
+      free(cur_line);
+      return ((rval == JB_ERR_FILE) ? JB_ERR_OK : rval);
+   }
+
+   do
+   {
+      prev_line = cur_line;
+      cur_line = prev_line->next = zalloc(sizeof(struct file_line));
+      if (cur_line == NULL)
+      {
+         /* Out of memory */
+         edit_free_file_lines(first_line);
+         return JB_ERR_MEMORY;
+      }
+
+      cur_line->type = FILE_LINE_UNPROCESSED;
+
+      rval = edit_read_line(fp, &cur_line->raw, &cur_line->prefix, &cur_line->unprocessed, newline, NULL);
+      if ((rval != JB_ERR_OK) && (rval != JB_ERR_FILE))
+      {
+         /* Out of memory */
+         edit_free_file_lines(first_line);
+         return JB_ERR_MEMORY;
+      }
+
+   }
+   while (rval != JB_ERR_FILE);
+
+   /* EOF */
+
+   /* We allocated one too many - free it */
+   prev_line->next = NULL;
+   free(cur_line);
+
+   *pfile = first_line;
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  edit_read_file
+ *
+ * Description :  Read a complete file into memory.
+ *                Handles CGI parameter parsing.  If requested, also
+ *                checks the file's modification timestamp.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  parameters = map of cgi parameters.
+ *          3  :  require_version = true to check "ver" parameter.
+ *          4  :  suffix = File extension, e.g. ".action".
+ *          5  :  pfile = Destination for the file.  Will be set
+ *                        to NULL on error.
+ *
+ * CGI Parameters :
+ *    filename :  The name of the file to read, without the
+ *                path or ".action" extension.
+ *         ver :  (Only if require_version is nonzero)
+ *                Timestamp of the actions file.  If wrong, this
+ *                function fails with JB_ERR_MODIFIED.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if "filename" was not specified
+ *                                  or is not valid.
+ *                JB_ERR_FILE   if the file cannot be opened or
+ *                              contains no data
+ *                JB_ERR_MODIFIED if version checking was requested and
+ *                                failed - the file was modified outside
+ *                                of this CGI editor instance.
+ *
+ *********************************************************************/
+jb_err edit_read_file(struct client_state *csp,
+                      const struct map *parameters,
+                      int require_version,
+                      const char *suffix,
+                      struct editable_file **pfile)
+{
+   struct file_line * lines;
+   FILE * fp;
+   jb_err err;
+   char * filename;
+   const char * identifier;
+   struct editable_file * file;
+   unsigned version = 0;
+   struct stat statbuf[1];
+   char version_buf[22];
+   int newline = NEWLINE_UNKNOWN;
+
+   assert(csp);
+   assert(parameters);
+   assert(pfile);
+
+   *pfile = NULL;
+
+   err = get_file_name_param(csp, parameters, "f", suffix,
+                             &filename, &identifier);
+   if (err)
+   {
+      return err;
+   }
+
+   if (stat(filename, statbuf) < 0)
+   {
+      /* Error, probably file not found. */
+      free(filename);
+      return JB_ERR_FILE;
+   }
+   version = (unsigned) statbuf->st_mtime;
+
+   if (require_version)
+   {
+      unsigned specified_version;
+      err = get_number_param(csp, parameters, "v", &specified_version);
+      if (err)
+      {
+         free(filename);
+         return err;
+      }
+
+      if (version != specified_version)
+      {
+         return JB_ERR_MODIFIED;
+      }
+   }
+
+   if (NULL == (fp = fopen(filename,"rb")))
+   {
+      free(filename);
+      return JB_ERR_FILE;
+   }
+
+   err = edit_read_file_lines(fp, &lines, &newline);
+
+   fclose(fp);
+
+   if (err)
+   {
+      free(filename);
+      return err;
+   }
+
+   file = (struct editable_file *) zalloc(sizeof(*file));
+   if (err)
+   {
+      free(filename);
+      edit_free_file_lines(lines);
+      return err;
+   }
+
+   file->lines = lines;
+   file->newline = newline;
+   file->filename = filename;
+   file->version = version;
+   file->identifier = url_encode(identifier);
+
+   if (file->identifier == NULL)
+   {
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   /* Correct file->version_str */
+   freez(file->version_str);
+   snprintf(version_buf, 22, "%u", file->version);
+   version_buf[21] = '\0';
+   file->version_str = strdup(version_buf);
+   if (version_buf == NULL)
+   {
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   *pfile = file;
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  edit_read_actions_file
+ *
+ * Description :  Read a complete actions file into memory.
+ *                Handles CGI parameter parsing.  If requested, also
+ *                checks the file's modification timestamp.
+ *
+ *                If this function detects an error in the categories
+ *                JB_ERR_FILE, JB_ERR_MODIFIED, or JB_ERR_PARSE,
+ *                then it handles it by filling in the specified
+ *                response structure and returning JB_ERR_FILE.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = HTTP response.  Only filled in on error.
+ *          2  :  parameters = map of cgi parameters.
+ *          3  :  require_version = true to check "ver" parameter.
+ *          4  :  pfile = Destination for the file.  Will be set
+ *                        to NULL on error.
+ *
+ * CGI Parameters :
+ *    filename :  The name of the actions file to read, without the
+ *                path or ".action" extension.
+ *         ver :  (Only if require_version is nonzero)
+ *                Timestamp of the actions file.  If wrong, this
+ *                function fails with JB_ERR_MODIFIED.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if "filename" was not specified
+ *                                  or is not valid.
+ *                JB_ERR_FILE  if the file does not contain valid data,
+ *                             or if file cannot be opened or
+ *                             contains no data, or if version
+ *                             checking was requested and failed.
+ *
+ *********************************************************************/
+jb_err edit_read_actions_file(struct client_state *csp,
+                              struct http_response *rsp,
+                              const struct map *parameters,
+                              int require_version,
+                              struct editable_file **pfile)
+{
+   jb_err err;
+   struct editable_file *file;
+
+   assert(csp);
+   assert(parameters);
+   assert(pfile);
+
+   *pfile = NULL;
+
+   err = edit_read_file(csp, parameters, require_version, ".action", &file);
+   if (err)
+   {
+      /* Try to handle if possible */
+      if (err == JB_ERR_FILE)
+      {
+         err = cgi_error_file(csp, rsp, lookup(parameters, "f"));
+      }
+      else if (err == JB_ERR_MODIFIED)
+      {
+         err = cgi_error_modified(csp, rsp, lookup(parameters, "f"));
+      }
+      if (err == JB_ERR_OK)
+      {
+         /*
+          * Signal to higher-level CGI code that there was a problem but we
+          * handled it, they should just return JB_ERR_OK.
+          */
+         err = JB_ERR_FILE;
+      }
+      return err;
+   }
+
+   err = edit_parse_actions_file(file);
+   if (err)
+   {
+      if (err == JB_ERR_PARSE)
+      {
+         err = cgi_error_parse(csp, rsp, file);
+         if (err == JB_ERR_OK)
+         {
+            /*
+             * Signal to higher-level CGI code that there was a problem but we
+             * handled it, they should just return JB_ERR_OK.
+             */
+            err = JB_ERR_FILE;
+         }
+      }
+      edit_free_file(file);
+      return err;
+   }
+
+   *pfile = file;
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_file_name_param
+ *
+ * Description :  Get the name of the file to edit from the parameters
+ *                passed to a CGI function.  This function handles
+ *                security checks such as blocking urls containing
+ *                "/" or ".", prepending the config file directory,
+ *                and adding the specified suffix.
+ *
+ *                (This is an essential security check, otherwise
+ *                users may be able to pass "../../../etc/passwd"
+ *                and overwrite the password file [linux], "prn:"
+ *                and print random data [Windows], etc...)
+ *
+ *                This function only allows filenames contining the
+ *                characters '-', '_', 'A'-'Z', 'a'-'z', and '0'-'9'.
+ *                That's probably too restrictive but at least it's
+ *                secure.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  parameters = map of cgi parameters
+ *          3  :  param_name = The name of the parameter to read
+ *          4  :  suffix = File extension, e.g. ".actions"
+ *          5  :  pfilename = destination for full filename.  Caller
+ *                free()s.  Set to NULL on error.
+ *          6  :  pparam = destination for partial filename,
+ *                suitable for use in another URL.  Allocated as part
+ *                of the map "parameters", so don't free it.
+ *                Set to NULL if not specified.
+ *
+ * Returns     :  JB_ERR_OK         on success
+ *                JB_ERR_MEMORY     on out-of-memory
+ *                JB_ERR_CGI_PARAMS if "filename" was not specified
+ *                                  or is not valid.
+ *
+ *********************************************************************/
+static jb_err get_file_name_param(struct client_state *csp,
+                                  const struct map *parameters,
+                                  const char *param_name,
+                                  const char *suffix,
+                                  char **pfilename,
+                                  const char **pparam)
+{
+   const char *param;
+   const char *s;
+   char *name;
+   char *fullpath;
+   char ch;
+   int len;
+
+   assert(csp);
+   assert(parameters);
+   assert(suffix);
+   assert(pfilename);
+   assert(pparam);
+
+   *pfilename = NULL;
+   *pparam = NULL;
+
+   param = lookup(parameters, param_name);
+   if (!*param)
+   {
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   *pparam = param;
+
+   len = strlen(param);
+   if (len >= FILENAME_MAX)
+   {
+      /* Too long. */
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* Check every character to see if it's legal */
+   s = param;
+   while ((ch = *s++) != '\0')
+   {
+      if ( ((ch < 'A') || (ch > 'Z'))
+        && ((ch < 'a') || (ch > 'z'))
+        && ((ch < '0') || (ch > '9'))
+        && (ch != '-')
+        && (ch != '_') )
+      {
+         /* Probable hack attempt. */
+         return JB_ERR_CGI_PARAMS;
+      }
+   }
+
+   /* Append extension */
+   name = malloc(len + strlen(suffix) + 1);
+   if (name == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+   strcpy(name, param);
+   strcpy(name + len, suffix);
+
+   /* Prepend path */
+   fullpath = make_path(csp->config->confdir, name);
+   free(name);
+
+   if (fullpath == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   /* Success */
+   *pfilename = fullpath;
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_url_spec_param
+ *
+ * Description :  Get a URL pattern from the parameters
+ *                passed to a CGI function.  Removes leading/trailing
+ *                spaces and validates it.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  parameters = map of cgi parameters
+ *          3  :  name = Name of CGI parameter to read
+ *          4  :  pvalue = destination for value.  Will be malloc()'d.
+ *                         Set to NULL on error.
+ *
+ * Returns     :  JB_ERR_OK         on success
+ *                JB_ERR_MEMORY     on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the parameter was not specified
+ *                                  or is not valid.
+ *
+ *********************************************************************/
+static jb_err get_url_spec_param(struct client_state *csp,
+                                 const struct map *parameters,
+                                 const char *name,
+                                 char **pvalue)
+{
+   const char *orig_param;
+   char *param;
+   char *s;
+   struct url_spec compiled[1];
+   jb_err err;
+
+   assert(csp);
+   assert(parameters);
+   assert(name);
+   assert(pvalue);
+
+   *pvalue = NULL;
+
+   orig_param = lookup(parameters, name);
+   if (!*orig_param)
+   {
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* Copy and trim whitespace */
+   param = strdup(orig_param);
+   if (param == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+   chomp(param);
+
+   /* Must be non-empty, and can't allow 1st character to be '{' */
+   if (param[0] == '\0' || param[0] == '{')
+   {
+      free(param);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* Check for embedded newlines */
+   for (s = param; *s != '\0'; s++)
+   {
+      if ((*s == '\r') || (*s == '\n'))
+      {
+         free(param);
+         return JB_ERR_CGI_PARAMS;
+      }
+   }
+
+   /* Check that regex is valid */
+   s = strdup(param);
+   if (s == NULL)
+   {
+      free(param);
+      return JB_ERR_MEMORY;
+   }
+   err = create_url_spec(compiled, s);
+   free(s);
+   if (err)
+   {
+      free(param);
+      return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS;
+   }
+   free_url_spec(compiled);
+
+   if (param[strlen(param) - 1] == '\\')
+   {
+      /*
+       * Must protect trailing '\\' from becoming line continuation character.
+       * Two methods: 1) If it's a domain only, add a trailing '/'.
+       * 2) For path, add the do-nothing PCRE expression (?:) to the end
+       */
+      if (strchr(param, '/') == NULL)
+      {
+         err = string_append(&param, "/");
+      }
+      else
+      {
+         err = string_append(&param, "(?:)");
+      }
+      if (err)
+      {
+         return err;
+      }
+
+      /* Check that the modified regex is valid */
+      s = strdup(param);
+      if (s == NULL)
+      {
+         free(param);
+         return JB_ERR_MEMORY;
+      }
+      err = create_url_spec(compiled, s);
+      free(s);
+      if (err)
+      {
+         free(param);
+         return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS;
+      }
+      free_url_spec(compiled);
+   }
+
+   *pvalue = param;
+   return JB_ERR_OK;
+}
+
+/*********************************************************************
+ *
+ * Function    :  map_radio
+ *
+ * Description :  Map a set of radio button values.  E.g. if you have
+ *                3 radio buttons, declare them as:
+ *                  <option type="radio" name="xyz" @xyz-a@>
+ *                  <option type="radio" name="xyz" @xyz-b@>
+ *                  <option type="radio" name="xyz" @xyz-c@>
+ *                Then map one of the @xyz-?@ variables to "checked"
+ *                and all the others to empty by calling:
+ *                map_radio(exports, "xyz", "abc", sel)
+ *                Where 'sel' is 'a', 'b', or 'c'.
+ *
+ * Parameters  :
+ *          1  :  exports = Exports map to modify.
+ *          2  :  optionname = name for map
+ *          3  :  values = null-terminated list of values;
+ *          4  :  value = Selected value.
+ *
+ * CGI Parameters : None
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *
+ *********************************************************************/
+static jb_err map_radio(struct map * exports,
+                        const char * optionname,
+                        const char * values,
+                        int value)
+{
+   size_t len;
+   char * buf;
+   char * p;
+   char c;
+
+   assert(exports);
+   assert(optionname);
+   assert(values);
+
+   len = strlen(optionname);
+   buf = malloc(len + 3);
+   if (buf == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   strcpy(buf, optionname);
+   p = buf + len;
+   *p++ = '-';
+   p[1] = '\0';
+
+   while ((c = *values++) != '\0')
+   {
+      if (c != value)
+      {
+         *p = c;
+         if (map(exports, buf, 1, "", 1))
+         {
+            return JB_ERR_MEMORY;
+         }
+      }
+   }
+
+   *p = value;
+   return map(exports, buf, 0, "checked", 1);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_modified
+ *
+ * Description :  CGI function that is called when a file is modified
+ *                outside the CGI editor.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  filename = The file that was modified.
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_error_modified(struct client_state *csp,
+                          struct http_response *rsp,
+                          const char *filename)
+{
+   struct map *exports;
+   jb_err err;
+
+   assert(csp);
+   assert(rsp);
+   assert(filename);
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   err = map(exports, "f", 1, html_encode(filename), 0);
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "cgi-error-modified", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_parse
+ *
+ * Description :  CGI function that is called when a file cannot
+ *                be parsed by the CGI editor.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  file = The file that was modified.
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_error_parse(struct client_state *csp,
+                       struct http_response *rsp,
+                       struct editable_file *file)
+{
+   struct map *exports;
+   jb_err err;
+   struct file_line *cur_line;
+
+   assert(csp);
+   assert(rsp);
+   assert(file);
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   err = map(exports, "f", 1, file->identifier, 1);
+   if (!err) err = map(exports, "parse-error", 1, html_encode(file->parse_error_text), 0);
+
+   cur_line = file->parse_error;
+   assert(cur_line);
+
+   if (!err) err = map(exports, "line-raw", 1, html_encode(cur_line->raw), 0);
+   if (!err) err = map(exports, "line-data", 1, html_encode(cur_line->unprocessed), 0);
+
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "cgi-error-parse", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_file
+ *
+ * Description :  CGI function that is called when a file cannot be
+ *                opened by the CGI editor.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  filename = The file that was modified.
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_error_file(struct client_state *csp,
+                      struct http_response *rsp,
+                      const char *filename)
+{
+   struct map *exports;
+   jb_err err;
+
+   assert(csp);
+   assert(rsp);
+   assert(filename);
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   err = map(exports, "f", 1, html_encode(filename), 0);
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "cgi-error-file", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_file
+ *
+ * Description :  CGI function that is called when a file cannot be
+ *                opened for writing by the CGI editor.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  filename = The file that we can't write to
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_error_file_read_only(struct client_state *csp,
+                                struct http_response *rsp,
+                                const char *filename)
+{
+   struct map *exports;
+   jb_err err;
+
+   assert(csp);
+   assert(rsp);
+   assert(filename);
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   err = map(exports, "f", 1, html_encode(filename), 0);
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "cgi-error-file-read-only", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_disabled
+ *
+ * Description :  CGI function that is called if the actions editor
+ *                is called although it's disabled in config
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_error_disabled(struct client_state *csp,
+                          struct http_response *rsp)
+{
+   struct map *exports;
+
+   assert(csp);
+   assert(rsp);
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   return template_fill_for_cgi(csp, "cgi-error-disabled", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions
+ *
+ * Description :  CGI function that allows the user to choose which
+ *                actions file to edit.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : None
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions(struct client_state *csp,
+                        struct http_response *rsp,
+                        const struct map *parameters)
+{
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   /* FIXME: Incomplete */
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+   if (enlist_unique_header(rsp->headers, "Location",
+      CGI_PREFIX "edit-actions-list?f=default"))
+   {
+      free(rsp->status);
+      rsp->status = NULL;
+      return JB_ERR_MEMORY;
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_list
+ *
+ * Description :  CGI function that edits the actions list.
+ *                FIXME: This function shouldn't FATAL ever.
+ *                FIXME: This function doesn't check the retval of map()
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : filename
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_FILE   if the file cannot be opened or
+ *                              contains no data
+ *                JB_ERR_CGI_PARAMS if "filename" was not specified
+ *                                  or is not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_list(struct client_state *csp,
+                             struct http_response *rsp,
+                             const struct map *parameters)
+{
+   char * section_template;
+   char * url_template;
+   char * sections;
+   char * urls;
+   char buf[150];
+   char * s;
+   struct map * exports;
+   struct map * section_exports;
+   struct map * url_exports;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number = 0;
+   unsigned prev_section_line_number = ((unsigned) (-1));
+   int i, url_1_2;
+   struct file_list * fl;
+   struct url_actions * b;
+   char * buttons = NULL;
+   jb_err err;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   /* Load actions file */
+   err = edit_read_actions_file(csp, rsp, parameters, 0, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   /* Find start of actions in file */
+   cur_line = file->lines;
+   line_number = 1;
+   while ((cur_line != NULL) && (cur_line->type != FILE_LINE_ACTION))
+   {
+      cur_line = cur_line->next;
+      line_number++;
+   }
+
+   /*
+    * Conventional actions files should have a match all block
+    * at the start:
+    * cur_line             = {...global actions...}
+    * cur_line->next       = /
+    * cur_line->next->next = {...actions...} or EOF
+    */
+   if ( (cur_line != NULL)
+     && (cur_line->type == FILE_LINE_ACTION)
+     && (cur_line->next != NULL)
+     && (cur_line->next->type == FILE_LINE_URL)
+     && (0 == strcmp(cur_line->next->unprocessed, "/"))
+     && ( (cur_line->next->next == NULL)
+       || (cur_line->next->next->type != FILE_LINE_URL)
+      ) )
+   {
+      /*
+       * Generate string with buttons to set actions for "/" to
+       * any predefined set of actions (named standard.*, probably
+       * residing in standard.action).
+       */
+
+      err = template_load(csp, &section_template, "edit-actions-list-button", 0);
+      if (err)
+      {
+         edit_free_file(file);
+         free_map(exports);
+         if (err == JB_ERR_FILE)
+         {
+            return cgi_error_no_template(csp, rsp, "edit-actions-list-button");
+         }
+         return err;
+      }
+
+      err = template_fill(&section_template, exports);
+      if (err)
+      {
+         edit_free_file(file);
+         free_map(exports);
+         return err;
+      }
+
+      buttons = strdup("");
+      for (i = 0; i < MAX_ACTION_FILES; i++)
+      {
+         if (((fl = csp->actions_list[i]) != NULL) && ((b = fl->f) != NULL))
+         {
+            for (b = b->next; NULL != b; b = b->next)
+            {
+               if (!strncmp(b->url->spec, "standard.", 9) && *(b->url->spec + 9) != '\0')
+               {
+                  if (err || (NULL == (section_exports = new_map())))
+                  {
+                     freez(buttons);
+                     free(section_template);
+                     edit_free_file(file);
+                     free_map(exports);
+                     return JB_ERR_MEMORY;
+                  }
+
+                  err = map(section_exports, "button-name", 1, b->url->spec + 9, 1);
+
+                  if (err || (NULL == (s = strdup(section_template))))
+                  {
+                     free_map(section_exports);
+                     freez(buttons);
+                     free(section_template);
+                     edit_free_file(file);
+                     free_map(exports);
+                     return JB_ERR_MEMORY;
+                  }
+
+                  if (!err) err = template_fill(&s, section_exports);
+                  free_map(section_exports);
+                  if (!err) err = string_join(&buttons, s);
+               }
+            }
+         }
+      }
+      freez(section_template);
+      if (!err) err = map(exports, "all-urls-buttons", 1, buttons, 0);
+
+      /*
+       * Conventional actions file, supply extra editing help.
+       * (e.g. don't allow them to make it an unconventional one).
+       */
+      if (!err) err = map_conditional(exports, "all-urls-present", 1);
+
+      snprintf(buf, 150, "%d", line_number);
+      if (!err) err = map(exports, "all-urls-s", 1, buf, 1);
+      snprintf(buf, 150, "%d", line_number + 2);
+      if (!err) err = map(exports, "all-urls-s-next", 1, buf, 1);
+      if (!err) err = map(exports, "all-urls-actions", 1,
+                          actions_to_html(csp, cur_line->data.action), 0);
+
+       /* Skip the 2 lines */
+      cur_line = cur_line->next->next;
+      line_number += 2;
+
+      /*
+       * Note that prev_section_line_number is NOT set here.
+       * This is deliberate and not a bug.  It stops a "Move up"
+       * option appearing on the next section.  Clicking "Move
+       * up" would make the actions file unconventional, which
+       * we don't want, so we hide this option.
+       */
+   }
+   else
+   {
+      /*
+       * Non-standard actions file - does not begin with
+       * the "All URLs" section.
+       */
+      if (!err) err = map_conditional(exports, "all-urls-present", 0);
+   }
+
+   /* Set up global exports */
+
+   if (!err) err = map(exports, "f", 1, file->identifier, 1);
+   if (!err) err = map(exports, "v", 1, file->version_str, 1);
+
+   /* Discourage private additions to default.action */
+
+   if (!err) err = map_conditional(exports, "default-action",
+                                   (strcmp("default", lookup(parameters, "f")) == 0));
+   if (err)
+   {
+      edit_free_file(file);
+      free_map(exports);
+      return err;
+   }
+
+   /* Should do all global exports above this point */
+
+   /* Load templates */
+
+   err = template_load(csp, &section_template, "edit-actions-list-section", 0);
+   if (err)
+   {
+      edit_free_file(file);
+      free_map(exports);
+      if (err == JB_ERR_FILE)
+      {
+         return cgi_error_no_template(csp, rsp, "edit-actions-list-section");
+      }
+      return err;
+   }
+
+   err = template_load(csp, &url_template, "edit-actions-list-url", 0);
+   if (err)
+   {
+      free(section_template);
+      edit_free_file(file);
+      free_map(exports);
+      if (err == JB_ERR_FILE)
+      {
+         return cgi_error_no_template(csp, rsp, "edit-actions-list-url");
+      }
+      return err;
+   }
+
+   err = template_fill(&section_template, exports);
+   if (err)
+   {
+      free(url_template);
+      edit_free_file(file);
+      free_map(exports);
+      free(url_template);
+      return err;
+   }
+
+   err = template_fill(&url_template, exports);
+   if (err)
+   {
+      free(section_template);
+      edit_free_file(file);
+      free_map(exports);
+      return err;
+   }
+
+   if (NULL == (sections = strdup("")))
+   {
+      free(section_template);
+      free(url_template);
+      edit_free_file(file);
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+
+   while ((cur_line != NULL) && (cur_line->type == FILE_LINE_ACTION))
+   {
+      if (NULL == (section_exports = new_map()))
+      {
+         free(sections);
+         free(section_template);
+         free(url_template);
+         edit_free_file(file);
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+
+      snprintf(buf, 150, "%d", line_number);
+      err = map(section_exports, "s", 1, buf, 1);
+      if (!err) err = map(section_exports, "actions", 1,
+                          actions_to_html(csp, cur_line->data.action), 0);
+
+      if ( (!err)
+        && (cur_line->next != NULL)
+        && (cur_line->next->type == FILE_LINE_URL))
+      {
+         /* This section contains at least one URL, don't allow delete */
+         err = map_block_killer(section_exports, "empty-section");
+      }
+      else
+      {
+         if (!err) err = map_block_keep(section_exports, "empty-section");
+      }
+
+      if (prev_section_line_number != ((unsigned)(-1)))
+      {
+         /* Not last section */
+         snprintf(buf, 150, "%d", prev_section_line_number);
+         if (!err) err = map(section_exports, "s-prev", 1, buf, 1);
+         if (!err) err = map_block_keep(section_exports, "s-prev-exists");
+      }
+      else
+      {
+         /* Last section */
+         if (!err) err = map_block_killer(section_exports, "s-prev-exists");
+      }
+      prev_section_line_number = line_number;
+
+      if (err)
+      {
+         free(sections);
+         free(section_template);
+         free(url_template);
+         edit_free_file(file);
+         free_map(exports);
+         free_map(section_exports);
+         return err;
+      }
+
+      /* Should do all section-specific exports above this point */
+
+      if (NULL == (urls = strdup("")))
+      {
+         free(sections);
+         free(section_template);
+         free(url_template);
+         edit_free_file(file);
+         free_map(exports);
+         free_map(section_exports);
+         return JB_ERR_MEMORY;
+      }
+
+      url_1_2 = 2;
+
+      cur_line = cur_line->next;
+      line_number++;
+
+      while ((cur_line != NULL) && (cur_line->type == FILE_LINE_URL))
+      {
+         if (NULL == (url_exports = new_map()))
+         {
+            free(urls);
+            free(sections);
+            free(section_template);
+            free(url_template);
+            edit_free_file(file);
+            free_map(exports);
+            free_map(section_exports);
+            return JB_ERR_MEMORY;
+         }
+
+         snprintf(buf, 150, "%d", line_number);
+         err = map(url_exports, "p", 1, buf, 1);
+
+         snprintf(buf, 150, "%d", url_1_2);
+         if (!err) err = map(url_exports, "url-1-2", 1, buf, 1);
+
+         if (!err) err = map(url_exports, "url-html", 1,
+                             html_encode(cur_line->unprocessed), 0);
+         if (!err) err = map(url_exports, "url", 1,
+                             url_encode(cur_line->unprocessed), 0);
+
+         if (err)
+         {
+            free(urls);
+            free(sections);
+            free(section_template);
+            free(url_template);
+            edit_free_file(file);
+            free_map(exports);
+            free_map(section_exports);
+            free_map(url_exports);
+            return err;
+         }
+
+         if (NULL == (s = strdup(url_template)))
+         {
+            free(urls);
+            free(sections);
+            free(section_template);
+            free(url_template);
+            edit_free_file(file);
+            free_map(exports);
+            free_map(section_exports);
+            free_map(url_exports);
+            return JB_ERR_MEMORY;
+         }
+
+         err = template_fill(&s, section_exports);
+         if (!err) err = template_fill(&s, url_exports);
+         if (!err) err = string_append(&urls, s);
+
+         free_map(url_exports);
+         freez(s);
+
+         if (err)
+         {
+            freez(urls);
+            free(sections);
+            free(section_template);
+            free(url_template);
+            edit_free_file(file);
+            free_map(exports);
+            free_map(section_exports);
+            return err;
+         }
+
+         url_1_2 = 3 - url_1_2;
+
+         cur_line = cur_line->next;
+         line_number++;
+      }
+
+      err = map(section_exports, "urls", 1, urls, 0);
+
+      /* Could also do section-specific exports here, but it wouldn't be as fast */
+
+      if ( (cur_line != NULL)
+        && (cur_line->type == FILE_LINE_ACTION))
+      {
+         /* Not last section */
+         snprintf(buf, 150, "%d", line_number);
+         if (!err) err = map(section_exports, "s-next", 1, buf, 1);
+         if (!err) err = map_block_keep(section_exports, "s-next-exists");
+      }
+      else
+      {
+         /* Last section */
+         if (!err) err = map_block_killer(section_exports, "s-next-exists");
+      }
+
+      if (err)
+      {
+         free(sections);
+         free(section_template);
+         free(url_template);
+         edit_free_file(file);
+         free_map(exports);
+         free_map(section_exports);
+         return err;
+      }
+
+      if (NULL == (s = strdup(section_template)))
+      {
+         free(sections);
+         free(section_template);
+         free(url_template);
+         edit_free_file(file);
+         free_map(exports);
+         free_map(section_exports);
+         return JB_ERR_MEMORY;
+      }
+
+      err = template_fill(&s, section_exports);
+      if (!err) err = string_append(&sections, s);
+
+      freez(s);
+      free_map(section_exports);
+
+      if (err)
+      {
+         freez(sections);
+         free(section_template);
+         free(url_template);
+         edit_free_file(file);
+         free_map(exports);
+         return err;
+      }
+   }
+
+   edit_free_file(file);
+   free(section_template);
+   free(url_template);
+
+   err = map(exports, "sections", 1, sections, 0);
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   /* Could also do global exports here, but it wouldn't be as fast */
+
+   return template_fill_for_cgi(csp, "edit-actions-list", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_for_url
+ *
+ * Description :  CGI function that edits the Actions list.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : None
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_for_url(struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters)
+{
+   struct map * exports;
+   unsigned sectionid;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number;
+   jb_err err;
+   struct file_list *filter_file;
+   struct re_filterfile_spec *filter_group;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "s", &sectionid);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   cur_line = file->lines;
+
+   for (line_number = 1; (cur_line != NULL) && (line_number < sectionid); line_number++)
+   {
+      cur_line = cur_line->next;
+   }
+
+   if ( (cur_line == NULL)
+     || (line_number != sectionid)
+     || (sectionid < 1)
+     || (cur_line->type != FILE_LINE_ACTION))
+   {
+      /* Invalid "sectionid" parameter */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   err = map(exports, "f", 1, file->identifier, 1);
+   if (!err) err = map(exports, "v", 1, file->version_str, 1);
+   if (!err) err = map(exports, "s", 1, url_encode(lookup(parameters, "s")), 0);
+
+   if (!err) err = actions_to_radio(exports, cur_line->data.action);
+
+   filter_file = csp->rlist;
+   filter_group = ((filter_file != NULL) ? filter_file->f : NULL);
+
+   if (!err) err = map_conditional(exports, "any-filters-defined", (filter_group != NULL));
+
+   if (err)
+   {
+      edit_free_file(file);
+      free_map(exports);
+      return err;
+   }
+
+   if (filter_group == NULL)
+   {
+      err = map(exports, "filter-params", 1, "", 1);
+   }
+   else
+   {
+      /* We have some entries in the filter list */
+      char * result;
+      int index = 0;
+      char * filter_template;
+
+      err = template_load(csp, &filter_template, "edit-actions-for-url-filter", 0);
+      if (err)
+      {
+         edit_free_file(file);
+         free_map(exports);
+         if (err == JB_ERR_FILE)
+         {
+            return cgi_error_no_template(csp, rsp, "edit-actions-for-url-filter");
+         }
+         return err;
+      }
+
+      err = template_fill(&filter_template, exports);
+
+      result = strdup("");
+
+      for (;(!err) && (filter_group != NULL); filter_group = filter_group->next)
+      {
+         char current_mode = 'x';
+         struct list_entry *filter_name;
+         char * this_line;
+         struct map *line_exports;
+         char number[20];
+
+         filter_name = cur_line->data.action->multi_add[ACTION_MULTI_FILTER]->first;
+         while ((filter_name != NULL)
+             && (0 != strcmp(filter_group->name, filter_name->str)))
+         {
+              filter_name = filter_name->next;
+         }
+
+         if (filter_name != NULL)
+         {
+            current_mode = 'y';
+         }
+         else
+         {
+            filter_name = cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]->first;
+            while ((filter_name != NULL)
+                && (0 != strcmp(filter_group->name, filter_name->str)))
+            {
+                 filter_name = filter_name->next;
+            }
+            if (filter_name != NULL)
+            {
+               current_mode = 'n';
+            }
+         }
+
+         /* Generate a unique serial number */
+         snprintf(number, sizeof(number), "%x", index++);
+         number[sizeof(number) - 1] = '\0';
+
+         line_exports = new_map();
+         if (line_exports == NULL)
+         {
+            err = JB_ERR_MEMORY;
+            freez(result);
+         }
+         else
+         {
+            if (!err) err = map(line_exports, "index", 1, number, 1);
+            if (!err) err = map(line_exports, "name",  1, filter_group->name, 1);
+            if (!err) err = map(line_exports, "description",  1, filter_group->description, 1);
+            if (!err) err = map_radio(line_exports, "this-filter", "ynx", current_mode);
+
+            this_line = NULL;
+            if (!err)
+            {
+               this_line = strdup(filter_template);
+               if (this_line == NULL) err = JB_ERR_MEMORY;
+            }
+            if (!err) err = template_fill(&this_line, line_exports);
+            string_join(&result, this_line);
+
+            free_map(line_exports);
+         }
+      }
+
+      freez(filter_template);
+
+      if (!err)
+      {
+         err = map(exports, "filter-params", 1, result, 0);
+      }
+      else
+      {
+         freez(result);
+      }
+   }
+
+   if (!err) err = map_radio(exports, "filter-all", "nx",
+      (cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] ? 'n' : 'x'));
+
+   edit_free_file(file);
+
+   if (err)
+   {
+      free_map(exports);
+      return err;
+   }
+
+   return template_fill_for_cgi(csp, "edit-actions-for-url", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_submit
+ *
+ * Description :  CGI function that actually edits the Actions list.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : None
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_submit(struct client_state *csp,
+                               struct http_response *rsp,
+                               const struct map *parameters)
+{
+   unsigned sectionid;
+   char * actiontext;
+   char * newtext;
+   size_t len;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number;
+   char * target;
+   jb_err err;
+   int index;
+   const char * action_set_name;
+   char ch;
+   struct file_list * fl;
+   struct url_actions * b;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "s", &sectionid);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   cur_line = file->lines;
+
+   for (line_number = 1; (cur_line != NULL) && (line_number < sectionid); line_number++)
+   {
+      cur_line = cur_line->next;
+   }
+
+   if ( (cur_line == NULL)
+     || (line_number != sectionid)
+     || (sectionid < 1)
+     || (cur_line->type != FILE_LINE_ACTION))
+   {
+      /* Invalid "sectionid" parameter */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   get_string_param(parameters, "p", &action_set_name);
+   if (action_set_name != NULL)
+   {
+      for (index = 0; index < MAX_ACTION_FILES; index++)
+      {
+         if (((fl = csp->actions_list[index]) != NULL) && ((b = fl->f) != NULL))
+         {
+            for (b = b->next; NULL != b; b = b->next)
+            {
+               if (!strncmp(b->url->spec, "standard.", 9) && !strcmp(b->url->spec + 9, action_set_name))
+               {
+                  copy_action(cur_line->data.action, b->action); 
+                  goto found;
+               }
+            }
+         }
+      }
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+
+      found: ;
+   }
+   else
+   {
+      err = actions_from_radio(parameters, cur_line->data.action);
+   }
+
+   if(err)
+   {
+      /* Out of memory */
+      edit_free_file(file);
+      return err;
+   }
+
+   ch = get_char_param(parameters, "filter_all");
+   if (ch == 'N')
+   {
+      list_remove_all(cur_line->data.action->multi_add[ACTION_MULTI_FILTER]);
+      list_remove_all(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]);
+      cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] = 1;
+   }
+   else if (ch == 'X')
+   {
+      cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] = 0;
+   }
+
+   for (index = 0; !err; index++)
+   {
+      char key_value[30];
+      char key_name[30];
+      const char *name;
+      char value;
+
+      /* Generate the keys */
+      snprintf(key_value, sizeof(key_value), "filter_r%x", index);
+      key_value[sizeof(key_value) - 1] = '\0';
+      snprintf(key_name, sizeof(key_name), "filter_n%x", index);
+      key_name[sizeof(key_name) - 1] = '\0';
+
+      err = get_string_param(parameters, key_name, &name);
+      if (err) break;
+
+      if (name == NULL)
+      {
+         /* End of list */
+         break;
+      }
+
+      value = get_char_param(parameters, key_value);
+      if (value == 'Y')
+      {
+         list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
+         if (!err) err = enlist(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
+         list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
+      }
+      else if (value == 'N')
+      {
+         list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
+         if (!cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER])
+         {
+            list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
+            if (!err) err = enlist(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
+         }
+      }
+      else if (value == 'X')
+      {
+         list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name);
+         list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name);
+      }
+   }
+
+   if(err)
+   {
+      /* Out of memory */
+      edit_free_file(file);
+      return err;
+   }
+
+   if (NULL == (actiontext = actions_to_text(cur_line->data.action)))
+   {
+      /* Out of memory */
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   len = strlen(actiontext);
+   if (len == 0)
+   {
+      /*
+       * Empty action - must special-case this.
+       * Simply setting len to 1 is sufficient...
+       */
+      len = 1;
+   }
+
+   if (NULL == (newtext = malloc(len + 2)))
+   {
+      /* Out of memory */
+      free(actiontext);
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+   strcpy(newtext, actiontext);
+   free(actiontext);
+   newtext[0]       = '{';
+   newtext[len]     = '}';
+   newtext[len + 1] = '\0';
+
+   freez(cur_line->raw);
+   freez(cur_line->unprocessed);
+   cur_line->unprocessed = newtext;
+
+   err = edit_write_file(file);
+   if (err)
+   {
+      /* Error writing file */
+      if (err == JB_ERR_FILE)
+      {
+         /* Read-only file. */
+         err = cgi_error_file_read_only(csp, rsp, file->identifier);
+      }
+      edit_free_file(file);
+      return err;
+   }
+
+   target = strdup(CGI_PREFIX "edit-actions-list?f=");
+   string_append(&target, file->identifier);
+   string_join(&target, section_target(sectionid));
+
+
+   edit_free_file(file);
+
+   if (target == NULL)
+   {
+      /* Out of memory */
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      free(target);
+      return JB_ERR_MEMORY;
+   }
+   err = enlist_unique_header(rsp->headers, "Location", target);
+   free(target);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_url
+ *
+ * Description :  CGI function that actually edits a URL pattern in
+ *                an actions file.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *    filename : Identifies the file to edit
+ *         ver : File's last-modified time
+ *     section : Line number of section to edit
+ *     pattern : Line number of pattern to edit
+ *      newval : New value for pattern
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_url(struct client_state *csp,
+                            struct http_response *rsp,
+                            const struct map *parameters)
+{
+   unsigned patternid;
+   char * new_pattern;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number;
+   unsigned section_start_line_number = 0;
+   char * target;
+   jb_err err;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "p", &patternid);
+   if (err)
+   {
+      return err;
+   }
+   if (patternid < 1U)
+   {
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   err = get_url_spec_param(csp, parameters, "u", &new_pattern);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      free(new_pattern);
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   line_number = 1;
+   cur_line = file->lines;
+
+   while ((cur_line != NULL) && (line_number < patternid))
+   {
+      if (cur_line->type == FILE_LINE_ACTION)
+      {
+         section_start_line_number = line_number;
+      }      
+      cur_line = cur_line->next;
+      line_number++;
+   }
+
+   if ( (cur_line == NULL)
+     || (cur_line->type != FILE_LINE_URL))
+   {
+      /* Invalid "patternid" parameter */
+      free(new_pattern);
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* At this point, the line to edit is in cur_line */
+
+   freez(cur_line->raw);
+   freez(cur_line->unprocessed);
+   cur_line->unprocessed = new_pattern;
+
+   err = edit_write_file(file);
+   if (err)
+   {
+      /* Error writing file */
+      if (err == JB_ERR_FILE)
+      {
+         /* Read-only file. */
+         err = cgi_error_file_read_only(csp, rsp, file->identifier);
+      }
+      edit_free_file(file);
+      return err;
+   }
+
+   target = strdup(CGI_PREFIX "edit-actions-list?f=");
+   string_append(&target, file->identifier);
+   string_join(&target, section_target(section_start_line_number));
+
+   edit_free_file(file);
+
+   if (target == NULL)
+   {
+      /* Out of memory */
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      free(target);
+      return JB_ERR_MEMORY;
+   }
+   err = enlist_unique_header(rsp->headers, "Location", target);
+   free(target);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_add_url
+ *
+ * Description :  CGI function that actually adds a URL pattern to
+ *                an actions file.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *    filename : Identifies the file to edit
+ *         ver : File's last-modified time
+ *     section : Line number of section to edit
+ *      newval : New pattern
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_add_url(struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters)
+{
+   unsigned sectionid;
+   char * new_pattern;
+   struct file_line * new_line;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number;
+   char * target;
+   jb_err err;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "s", &sectionid);
+   if (err)
+   {
+      return err;
+   }
+   if (sectionid < 1U)
+   {
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   err = get_url_spec_param(csp, parameters, "u", &new_pattern);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      free(new_pattern);
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   line_number = 1;
+   cur_line = file->lines;
+
+   while ((cur_line != NULL) && (line_number < sectionid))
+   {
+      cur_line = cur_line->next;
+      line_number++;
+   }
+
+   if ( (cur_line == NULL)
+     || (cur_line->type != FILE_LINE_ACTION))
+   {
+      /* Invalid "sectionid" parameter */
+      free(new_pattern);
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* At this point, the section header is in cur_line - add after this. */
+
+   /* Allocate the new line */
+   new_line = (struct file_line *)zalloc(sizeof(*new_line));
+   if (new_line == NULL)
+   {
+      free(new_pattern);
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   /* Fill in the data members of the new line */
+   new_line->raw = NULL;
+   new_line->prefix = NULL;
+   new_line->unprocessed = new_pattern;
+   new_line->type = FILE_LINE_URL;
+
+   /* Link new_line into the list, after cur_line */
+   new_line->next = cur_line->next;
+   cur_line->next = new_line;
+
+   /* Done making changes, now commit */
+
+   err = edit_write_file(file);
+   if (err)
+   {
+      /* Error writing file */
+      if (err == JB_ERR_FILE)
+      {
+         /* Read-only file. */
+         err = cgi_error_file_read_only(csp, rsp, file->identifier);
+      }
+      edit_free_file(file);
+      return err;
+   }
+
+   target = strdup(CGI_PREFIX "edit-actions-list?f=");
+   string_append(&target, file->identifier);
+   string_join(&target, section_target(sectionid));
+
+   edit_free_file(file);
+
+   if (target == NULL)
+   {
+      /* Out of memory */
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      free(target);
+      return JB_ERR_MEMORY;
+   }
+   err = enlist_unique_header(rsp->headers, "Location", target);
+   free(target);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_remove_url
+ *
+ * Description :  CGI function that actually removes a URL pattern from
+ *                the actions file.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *           f : (filename) Identifies the file to edit
+ *           v : (version) File's last-modified time
+ *           p : (pattern) Line number of pattern to remove
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_remove_url(struct client_state *csp,
+                                   struct http_response *rsp,
+                                   const struct map *parameters)
+{
+   unsigned patternid;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   struct file_line * prev_line;
+   unsigned line_number;
+   unsigned section_start_line_number = 0;
+   char * target;
+   jb_err err;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "p", &patternid);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   line_number = 1;
+   prev_line = NULL;
+   cur_line = file->lines;
+
+   while ((cur_line != NULL) && (line_number < patternid))
+   {
+      if (cur_line->type == FILE_LINE_ACTION)
+      {
+         section_start_line_number = line_number;
+      }
+      prev_line = cur_line;
+      cur_line = cur_line->next;
+      line_number++;
+   }
+
+   if ( (cur_line == NULL)
+     || (prev_line == NULL)
+     || (cur_line->type != FILE_LINE_URL))
+   {
+      /* Invalid "patternid" parameter */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* At this point, the line to remove is in cur_line, and the previous
+    * one is in prev_line
+    */
+
+   /* Unlink cur_line */
+   prev_line->next = cur_line->next;
+   cur_line->next = NULL;
+
+   /* Free cur_line */
+   edit_free_file_lines(cur_line);
+
+   err = edit_write_file(file);
+   if (err)
+   {
+      /* Error writing file */
+      if (err == JB_ERR_FILE)
+      {
+         /* Read-only file. */
+         err = cgi_error_file_read_only(csp, rsp, file->identifier);
+      }
+      edit_free_file(file);
+      return err;
+   }
+
+   target = strdup(CGI_PREFIX "edit-actions-list?f=");
+   string_append(&target, file->identifier);
+   string_join(&target, section_target(section_start_line_number));
+
+   edit_free_file(file);
+
+   if (target == NULL)
+   {
+      /* Out of memory */
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      free(target);
+      return JB_ERR_MEMORY;
+   }
+   err = enlist_unique_header(rsp->headers, "Location", target);
+   free(target);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_section_remove
+ *
+ * Description :  CGI function that actually removes a whole section from
+ *                the actions file.  The section must be empty first
+ *                (else JB_ERR_CGI_PARAMS).
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *           f : (filename) Identifies the file to edit
+ *           v : (version) File's last-modified time
+ *           s : (section) Line number of section to edit
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_section_remove(struct client_state *csp,
+                                       struct http_response *rsp,
+                                       const struct map *parameters)
+{
+   unsigned sectionid;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   struct file_line * prev_line;
+   unsigned line_number;
+   char * target;
+   jb_err err;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "s", &sectionid);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   line_number = 1;
+   cur_line = file->lines;
+
+   prev_line = NULL;
+   while ((cur_line != NULL) && (line_number < sectionid))
+   {
+      prev_line = cur_line;
+      cur_line = cur_line->next;
+      line_number++;
+   }
+
+   if ( (cur_line == NULL)
+     || (cur_line->type != FILE_LINE_ACTION) )
+   {
+      /* Invalid "sectionid" parameter */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   if ( (cur_line->next != NULL)
+     && (cur_line->next->type == FILE_LINE_URL) )
+   {
+      /* Section not empty. */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* At this point, the line to remove is in cur_line, and the previous
+    * one is in prev_line
+    */
+
+   /* Unlink cur_line */
+   if (prev_line == NULL)
+   {
+      /* Removing the first line from the file */
+      file->lines = cur_line->next;
+   }
+   else
+   {
+      prev_line->next = cur_line->next;
+   }
+   cur_line->next = NULL;
+
+   /* Free cur_line */
+   edit_free_file_lines(cur_line);
+
+   err = edit_write_file(file);
+   if (err)
+   {
+      /* Error writing file */
+      if (err == JB_ERR_FILE)
+      {
+         /* Read-only file. */
+         err = cgi_error_file_read_only(csp, rsp, file->identifier);
+      }
+      edit_free_file(file);
+      return err;
+   }
+
+   target = strdup(CGI_PREFIX "edit-actions-list?f=");
+   string_append(&target, file->identifier);
+
+   edit_free_file(file);
+
+   if (target == NULL)
+   {
+      /* Out of memory */
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      free(target);
+      return JB_ERR_MEMORY;
+   }
+   err = enlist_unique_header(rsp->headers, "Location", target);
+   free(target);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_section_add
+ *
+ * Description :  CGI function that adds a new empty section to
+ *                an actions file.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *           f : (filename) Identifies the file to edit
+ *           v : (version) File's last-modified time
+ *           s : (section) Line number of section to add after, 0 for
+ *               start of file.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_section_add(struct client_state *csp,
+                                    struct http_response *rsp,
+                                    const struct map *parameters)
+{
+   unsigned sectionid;
+   struct file_line * new_line;
+   char * new_text;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   unsigned line_number;
+   char * target;
+   jb_err err;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "s", &sectionid);
+   if (err)
+   {
+      return err;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   line_number = 1;
+   cur_line = file->lines;
+
+   if (sectionid < 1U)
+   {
+      /* Add to start of file */
+      if (cur_line != NULL)
+      {
+         /* There's something in the file, find the line before the first
+          * action.
+          */
+         while ( (cur_line->next != NULL)
+              && (cur_line->next->type != FILE_LINE_ACTION) )
+         {
+            cur_line = cur_line->next;
+            line_number++;
+         }
+      }
+   }
+   else
+   {
+      /* Add after stated section. */
+      while ((cur_line != NULL) && (line_number < sectionid))
+      {
+         cur_line = cur_line->next;
+         line_number++;
+      }
+
+      if ( (cur_line == NULL)
+        || (cur_line->type != FILE_LINE_ACTION))
+      {
+         /* Invalid "sectionid" parameter */
+         edit_free_file(file);
+         return JB_ERR_CGI_PARAMS;
+      }
+
+      /* Skip through the section to find the last line in it. */
+      while ( (cur_line->next != NULL)
+           && (cur_line->next->type != FILE_LINE_ACTION) )
+      {
+         cur_line = cur_line->next;
+         line_number++;
+      }
+   }
+
+   /* At this point, the last line in the previous section is in cur_line
+    * - add after this.  (Or if we need to add as the first line, cur_line
+    * will be NULL).
+    */
+
+   new_text = strdup("{}");
+   if (NULL == new_text)
+   {
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   /* Allocate the new line */
+   new_line = (struct file_line *)zalloc(sizeof(*new_line));
+   if (new_line == NULL)
+   {
+      free(new_text);
+      edit_free_file(file);
+      return JB_ERR_MEMORY;
+   }
+
+   /* Fill in the data members of the new line */
+   new_line->raw = NULL;
+   new_line->prefix = NULL;
+   new_line->unprocessed = new_text;
+   new_line->type = FILE_LINE_ACTION;
+
+   if (cur_line != NULL)
+   {
+      /* Link new_line into the list, after cur_line */
+      new_line->next = cur_line->next;
+      cur_line->next = new_line;
+   }
+   else
+   {
+      /* Link new_line into the list, as first line */
+      new_line->next = file->lines;
+      file->lines = new_line;
+   }
+
+   /* Done making changes, now commit */
+
+   err = edit_write_file(file);
+   if (err)
+   {
+      /* Error writing file */
+      if (err == JB_ERR_FILE)
+      {
+         /* Read-only file. */
+         err = cgi_error_file_read_only(csp, rsp, file->identifier);
+      }
+      edit_free_file(file);
+      return err;
+   }
+
+   target = strdup(CGI_PREFIX "edit-actions-list?f=");
+   string_append(&target, file->identifier);
+
+   edit_free_file(file);
+
+   if (target == NULL)
+   {
+      /* Out of memory */
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      free(target);
+      return JB_ERR_MEMORY;
+   }
+   err = enlist_unique_header(rsp->headers, "Location", target);
+   free(target);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_edit_actions_section_swap
+ *
+ * Description :  CGI function that swaps the order of two sections
+ *                in the actions file.  Note that this CGI can actually
+ *                swap any two arbitrary sections, but the GUI interface
+ *                currently only allows consecutive sections to be
+ *                specified.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *           f : (filename) Identifies the file to edit
+ *           v : (version) File's last-modified time
+ *          s1 : (section1) Line number of first section to swap
+ *          s2 : (section2) Line number of second section to swap
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_CGI_PARAMS if the CGI parameters are not
+ *                                  specified or not valid.
+ *
+ *********************************************************************/
+jb_err cgi_edit_actions_section_swap(struct client_state *csp,
+                                     struct http_response *rsp,
+                                     const struct map *parameters)
+{
+   unsigned section1;
+   unsigned section2;
+   struct editable_file * file;
+   struct file_line * cur_line;
+   struct file_line * prev_line;
+   struct file_line * line_before_section1;
+   struct file_line * line_start_section1;
+   struct file_line * line_end_section1;
+   struct file_line * line_after_section1;
+   struct file_line * line_before_section2;
+   struct file_line * line_start_section2;
+   struct file_line * line_end_section2;
+   struct file_line * line_after_section2;
+   unsigned line_number;
+   char * target;
+   jb_err err;
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   err = get_number_param(csp, parameters, "s1", &section1);
+   if (!err) err = get_number_param(csp, parameters, "s2", &section2);
+   if (err)
+   {
+      return err;
+   }
+
+   if (section1 > section2)
+   {
+      unsigned temp = section2;
+      section2 = section1;
+      section1 = temp;
+   }
+
+   err = edit_read_actions_file(csp, rsp, parameters, 1, &file);
+   if (err)
+   {
+      /* No filename specified, can't read file, modified, or out of memory. */
+      return (err == JB_ERR_FILE ? JB_ERR_OK : err);
+   }
+
+   /* Start at the beginning... */
+   line_number = 1;
+   cur_line = file->lines;
+   prev_line = NULL;
+
+   /* ... find section1 ... */
+   while ((cur_line != NULL) && (line_number < section1))
+   {
+      prev_line = cur_line;
+      cur_line = cur_line->next;
+      line_number++;
+   }
+
+   if ( (cur_line == NULL)
+     || (cur_line->type != FILE_LINE_ACTION) )
+   {
+      /* Invalid "section1" parameter */
+      edit_free_file(file);
+      return JB_ERR_CGI_PARAMS;
+   }
+
+   /* If no-op, we've validated params and can skip the rest. */
+   if (section1 != section2)
+   {
+      /* ... find the end of section1 ... */
+      line_before_section1 = prev_line;
+      line_start_section1 = cur_line;
+      do
+      {
+         prev_line = cur_line;
+         cur_line = cur_line->next;
+         line_number++;
+      }
+      while ((cur_line != NULL) && (cur_line->type == FILE_LINE_URL));
+      line_end_section1 = prev_line;
+      line_after_section1 = cur_line;
+
+      /* ... find section2 ... */
+      while ((cur_line != NULL) && (line_number < section2))
+      {
+         prev_line = cur_line;
+         cur_line = cur_line->next;
+         line_number++;
+      }
+
+      if ( (cur_line == NULL)
+        || (cur_line->type != FILE_LINE_ACTION) )
+      {
+         /* Invalid "section2" parameter */
+         edit_free_file(file);
+         return JB_ERR_CGI_PARAMS;
+      }
+
+      /* ... find the end of section2 ... */
+      line_before_section2 = prev_line;
+      line_start_section2 = cur_line;
+      do
+      {
+         prev_line = cur_line;
+         cur_line = cur_line->next;
+         line_number++;
+      }
+      while ((cur_line != NULL) && (cur_line->type == FILE_LINE_URL));
+      line_end_section2 = prev_line;
+      line_after_section2 = cur_line;
+
+      /* Now have all the pointers we need. Do the swap. */
+
+      /* Change the pointer to section1 to point to section2 instead */
+      if (line_before_section1 == NULL)
+      {
+         file->lines = line_start_section2;
+      }
+      else
+      {
+         line_before_section1->next = line_start_section2;
+      }
+
+      if (line_before_section2 == line_end_section1)
+      {
+         /* Consecutive sections */
+         line_end_section2->next = line_start_section1;
+      }
+      else
+      {
+         line_end_section2->next = line_after_section1;
+         line_before_section2->next = line_start_section1;
+      }
+
+      /* Set the pointer from the end of section1 to the rest of the file */
+      line_end_section1->next = line_after_section2;
+
+      err = edit_write_file(file);
+      if (err)
+      {
+         /* Error writing file */
+         if (err == JB_ERR_FILE)
+         {
+            /* Read-only file. */
+            err = cgi_error_file_read_only(csp, rsp, file->identifier);
+         }
+         edit_free_file(file);
+         return err;
+      }
+   } /* END if (section1 != section2) */
+
+   target = strdup(CGI_PREFIX "edit-actions-list?f=");
+   string_append(&target, file->identifier);
+
+   edit_free_file(file);
+
+   if (target == NULL)
+   {
+      /* Out of memory */
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("302 Local Redirect from Privoxy");
+   if (rsp->status == NULL)
+   {
+      free(target);
+      return JB_ERR_MEMORY;
+   }
+   err = enlist_unique_header(rsp->headers, "Location", target);
+   free(target);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_toggle
+ *
+ * Description :  CGI function that adds a new empty section to
+ *                an actions file.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *         set : If present, how to change toggle setting:
+ *               "enable", "disable", "toggle", or none (default).
+ *        mini : If present, use mini reply template.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *
+ *********************************************************************/
+jb_err cgi_toggle(struct client_state *csp,
+                  struct http_response *rsp,
+                  const struct map *parameters)
+{
+   struct map *exports;
+   char mode;
+   const char *template_name;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_TOGGLE))
+   {
+      return cgi_error_disabled(csp, rsp);
+   }
+
+   mode = get_char_param(parameters, "set");
+
+   if (mode == 'E')
+   {
+      /* Enable */
+      g_bToggleIJB = 1;
+   }
+   else if (mode == 'D')
+   {
+      /* Disable */
+      g_bToggleIJB = 0;
+   }
+   else if (mode == 'T')
+   {
+      /* Toggle */
+      g_bToggleIJB = !g_bToggleIJB;
+   }
+
+   if (NULL == (exports = default_exports(csp, "toggle")))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   template_name = (get_char_param(parameters, "mini")
+                 ? "toggle-mini"
+                 : "toggle");
+
+   return template_fill_for_cgi(csp, template_name, exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  javascriptify
+ *
+ * Description :  Converts a string into a form JavaScript will like.
+ *
+ *                Netscape 4's JavaScript sucks - it doesn't use 
+ *                "id" parameters, so you have to set the "name"
+ *                used to submit a form element to something JavaScript
+ *                will like.  (Or access the elements by index in an
+ *                array.  That array contains >60 elements and will
+ *                be changed whenever we add a new action to the
+ *                editor, so I'm NOT going to use indexes that have
+ *                to be figured out by hand.)
+ *
+ *                Currently the only thing we have to worry about
+ *                is "-" ==> "_" conversion.
+ *
+ *                This is a length-preserving operation so it is
+ *                carried out in-place, no memory is allocated
+ *                or freed.
+ *
+ * Parameters  :
+ *          1  :  identifier = String to make JavaScript-friendly.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void javascriptify(char * identifier)
+{
+   char * p = identifier;
+   while (NULL != (p = strchr(p, '-')))
+   {
+      *p++ = '_';
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  actions_to_radio
+ *
+ * Description :  Converts a actionsfile entry into settings for
+ *                radio buttons and edit boxes on a HTML form.
+ *
+ * Parameters  :
+ *          1  :  exports = List of substitutions to add to.
+ *          2  :  action  = Action to read
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *
+ *********************************************************************/
+static jb_err actions_to_radio(struct map * exports,
+                               const struct action_spec *action)
+{
+   unsigned mask = action->mask;
+   unsigned add  = action->add;
+   int mapped_param;
+   int checked;
+   char current_mode;
+
+   assert(exports);
+   assert(action);
+
+   mask = action->mask;
+   add  = action->add;
+
+   /* sanity - prevents "-feature +feature" */
+   mask |= add;
+
+
+#define DEFINE_ACTION_BOOL(name, bit)                 \
+   if (!(mask & bit))                                 \
+   {                                                  \
+      current_mode = 'n';                             \
+   }                                                  \
+   else if (add & bit)                                \
+   {                                                  \
+      current_mode = 'y';                             \
+   }                                                  \
+   else                                               \
+   {                                                  \
+      current_mode = 'x';                             \
+   }                                                  \
+   if (map_radio(exports, name, "ynx", current_mode)) \
+   {                                                  \
+      return JB_ERR_MEMORY;                           \
+   }
+
+#define DEFINE_ACTION_STRING(name, bit, index)        \
+   DEFINE_ACTION_BOOL(name, bit);                     \
+   mapped_param = 0;
+
+#define DEFINE_CGI_PARAM_RADIO(name, bit, index, value, is_default)  \
+   if (add & bit)                                                    \
+   {                                                                 \
+      checked = !strcmp(action->string[index], value);               \
+   }                                                                 \
+   else                                                              \
+   {                                                                 \
+      checked = is_default;                                          \
+   }                                                                 \
+   mapped_param |= checked;                                          \
+   if (map(exports, name "-param-" value, 1, (checked ? "checked" : ""), 1)) \
+   {                                                                 \
+      return JB_ERR_MEMORY;                                          \
+   }
+
+#define DEFINE_CGI_PARAM_CUSTOM(name, bit, index, default_val)       \
+   if (map(exports, name "-param-custom", 1,                         \
+           ((!mapped_param) ? "checked" : ""), 1))                   \
+   {                                                                 \
+      return JB_ERR_MEMORY;                                          \
+   }                                                                 \
+   if (map(exports, name "-param", 1,                                \
+           (((add & bit) && !mapped_param) ?                         \
+           action->string[index] : default_val), 1))                 \
+   {                                                                 \
+      return JB_ERR_MEMORY;                                          \
+   }
+
+#define DEFINE_CGI_PARAM_NO_RADIO(name, bit, index, default_val)     \
+   if (map(exports, name "-param", 1,                                \
+           ((add & bit) ? action->string[index] : default_val), 1))  \
+   {                                                                 \
+      return JB_ERR_MEMORY;                                          \
+   }
+
+#define DEFINE_ACTION_MULTI(name, index)              \
+   if (action->multi_add[index]->first)               \
+   {                                                  \
+      current_mode = 'y';                             \
+   }                                                  \
+   else if (action->multi_remove_all[index])          \
+   {                                                  \
+      current_mode = 'n';                             \
+   }                                                  \
+   else if (action->multi_remove[index]->first)       \
+   {                                                  \
+      current_mode = 'y';                             \
+   }                                                  \
+   else                                               \
+   {                                                  \
+      current_mode = 'x';                             \
+   }                                                  \
+   if (map_radio(exports, name, "ynx", current_mode)) \
+   {                                                  \
+      return JB_ERR_MEMORY;                           \
+   }
+
+#define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
+
+#include "actionlist.h"
+
+#undef DEFINE_ACTION_MULTI
+#undef DEFINE_ACTION_STRING
+#undef DEFINE_ACTION_BOOL
+#undef DEFINE_ACTION_ALIAS
+#undef DEFINE_CGI_PARAM_CUSTOM
+#undef DEFINE_CGI_PARAM_RADIO
+#undef DEFINE_CGI_PARAM_NO_RADIO
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  actions_from_radio
+ *
+ * Description :  Converts a map of parameters passed to a CGI function
+ *                into an actionsfile entry.
+ *
+ * Parameters  :
+ *          1  :  parameters = parameters to the CGI call
+ *          2  :  action  = Action to change.  Must be valid before
+ *                          the call, actions not specified will be
+ *                          left unchanged.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *
+ *********************************************************************/
+static jb_err actions_from_radio(const struct map * parameters,
+                                 struct action_spec *action)
+{
+   static int first_time = 1;
+   const char * param;
+   char * param_dup;
+   char ch;
+   const char * js_name;
+   jb_err err = JB_ERR_OK;
+
+   assert(parameters);
+   assert(action);
+
+   /* Statics are generally a potential race condition,
+    * but in this case we're safe and don't need semaphores.
+    * Be careful if you modify this function.
+    * - Jon
+    */
+
+#define JAVASCRIPTIFY(dest_var, string)               \
+   {                                                  \
+      static char js_name_arr[] = string;             \
+      if (first_time)                                 \
+      {                                               \
+         javascriptify(js_name_arr);                  \
+      }                                               \
+      dest_var = js_name_arr;                         \
+   }                                                  \
+
+#define DEFINE_ACTION_BOOL(name, bit)                 \
+   JAVASCRIPTIFY(js_name, name);                      \
+   ch = get_char_param(parameters, js_name);          \
+   if (ch == 'Y')                                     \
+   {                                                  \
+      action->add  |= bit;                            \
+      action->mask |= bit;                            \
+   }                                                  \
+   else if (ch == 'N')                                \
+   {                                                  \
+      action->add  &= ~bit;                           \
+      action->mask &= ~bit;                           \
+   }                                                  \
+   else if (ch == 'X')                                \
+   {                                                  \
+      action->add  &= ~bit;                           \
+      action->mask |= bit;                            \
+   }                                                  \
+
+#define DEFINE_ACTION_STRING(name, bit, index)                 \
+   JAVASCRIPTIFY(js_name, name);                               \
+   ch = get_char_param(parameters, js_name);                   \
+   if (ch == 'Y')                                              \
+   {                                                           \
+      param = NULL;                                            \
+      JAVASCRIPTIFY(js_name, name "-mode");                    \
+      if (!err) err = get_string_param(parameters, js_name, &param);    \
+      if ((param == NULL) || (0 == strcmp(param, "CUSTOM")))            \
+      {                                                                 \
+         JAVASCRIPTIFY(js_name, name "-param");                         \
+         if (!err) err = get_string_param(parameters, js_name, &param); \
+      }                                                        \
+      if (param != NULL)                                       \
+      {                                                        \
+         if (NULL == (param_dup = strdup(param)))              \
+         {                                                     \
+            return JB_ERR_MEMORY;                              \
+         }                                                     \
+         freez(action->string[index]);                         \
+         action->add  |= bit;                                  \
+         action->mask |= bit;                                  \
+         action->string[index] = param_dup;                    \
+      }                                                        \
+   }                                                           \
+   else if (ch == 'N')                                         \
+   {                                                           \
+      if (action->add & bit)                                   \
+      {                                                        \
+         freez(action->string[index]);                         \
+      }                                                        \
+      action->add  &= ~bit;                                    \
+      action->mask &= ~bit;                                    \
+   }                                                           \
+   else if (ch == 'X')                                         \
+   {                                                           \
+      if (action->add & bit)                                   \
+      {                                                        \
+         freez(action->string[index]);                         \
+      }                                                        \
+      action->add  &= ~bit;                                    \
+      action->mask |= bit;                                     \
+   }                                                           \
+
+#define DEFINE_ACTION_MULTI(name, index)                       \
+   JAVASCRIPTIFY(js_name, name);                               \
+   ch = get_char_param(parameters, js_name);                   \
+   if (ch == 'Y')                                              \
+   {                                                           \
+      /* FIXME */                                              \
+   }                                                           \
+   else if (ch == 'N')                                         \
+   {                                                           \
+      list_remove_all(action->multi_add[index]);               \
+      list_remove_all(action->multi_remove[index]);            \
+      action->multi_remove_all[index] = 1;                     \
+   }                                                           \
+   else if (ch == 'X')                                         \
+   {                                                           \
+      list_remove_all(action->multi_add[index]);               \
+      list_remove_all(action->multi_remove[index]);            \
+      action->multi_remove_all[index] = 0;                     \
+   }                                                           \
+
+#define DEFINE_ACTION_ALIAS 0 /* No aliases for URL parsing */
+
+#include "actionlist.h"
+
+#undef DEFINE_ACTION_MULTI
+#undef DEFINE_ACTION_STRING
+#undef DEFINE_ACTION_BOOL
+#undef DEFINE_ACTION_ALIAS
+#undef JAVASCRIPTIFY
+
+   first_time = 0;
+
+   return err;
+}
+
+
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
+
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/cgiedit.h b/cgiedit.h
new file mode 100644 (file)
index 0000000..72721c2
--- /dev/null
+++ b/cgiedit.h
@@ -0,0 +1,154 @@
+#ifndef CGIEDIT_H_INCLUDED
+#define CGIEDIT_H_INCLUDED
+#define CGIEDIT_H_VERSION "$Id: cgiedit.h,v 1.6 2002/03/24 13:25:43 swa Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/cgiedit.h,v $
+ *
+ * Purpose     :  CGI-based actionsfile editor.
+ *                
+ *                Functions declared include:
+ * 
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: cgiedit.h,v $
+ *    Revision 1.6  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.5  2002/01/22 23:24:48  jongfoster
+ *    Adding edit-actions-section-swap
+ *
+ *    Revision 1.4  2001/11/13 00:28:51  jongfoster
+ *    Adding new CGIs for use by non-JavaScript browsers:
+ *      edit-actions-url-form
+ *      edit-actions-add-url-form
+ *      edit-actions-remove-url-form
+ *
+ *    Revision 1.3  2001/10/23 21:48:19  jongfoster
+ *    Cleaning up error handling in CGI functions - they now send back
+ *    a HTML error page and should never cause a FATAL error.  (Fixes one
+ *    potential source of "denial of service" attacks).
+ *
+ *    CGI actions file editor that works and is actually useful.
+ *
+ *    Ability to toggle JunkBuster remotely using a CGI call.
+ *
+ *    You can turn off both the above features in the main configuration
+ *    file, e.g. if you are running a multi-user proxy.
+ *
+ *    Revision 1.2  2001/10/14 22:12:49  jongfoster
+ *    New version of CGI-based actionsfile editor.
+ *    Major changes, including:
+ *    - Completely new file parser and file output routines
+ *    - edit-actions CGI renamed edit-actions-for-url
+ *    - All CGIs now need a filename parameter, except for...
+ *    - New CGI edit-actions which doesn't need a filename,
+ *      to allow you to start the editor up.
+ *    - edit-actions-submit now works, and now automatically
+ *      redirects you back to the main edit-actions-list handler.
+ *
+ *    Revision 1.1  2001/09/16 15:47:37  jongfoster
+ *    First version of CGI-based edit interface.  This is very much a
+ *    work-in-progress, and you can't actually use it to edit anything
+ *    yet.  You must #define FEATURE_CGI_EDIT_ACTIONS for these changes
+ *    to have any effect.
+ *
+ *
+ **********************************************************************/
+\f
+
+#include "project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CGI functions
+ */
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+extern jb_err cgi_edit_actions        (struct client_state *csp,
+                                       struct http_response *rsp,
+                                       const struct map *parameters);
+extern jb_err cgi_edit_actions_for_url(struct client_state *csp,
+                                       struct http_response *rsp,
+                                       const struct map *parameters);
+extern jb_err cgi_edit_actions_list   (struct client_state *csp,
+                                       struct http_response *rsp,
+                                       const struct map *parameters);
+extern jb_err cgi_edit_actions_submit (struct client_state *csp,
+                                       struct http_response *rsp,
+                                       const struct map *parameters);
+extern jb_err cgi_edit_actions_url    (struct client_state *csp,
+                                       struct http_response *rsp,
+                                       const struct map *parameters);
+extern jb_err cgi_edit_actions_url_form(struct client_state *csp,
+                                        struct http_response *rsp,
+                                        const struct map *parameters);
+extern jb_err cgi_edit_actions_add_url(struct client_state *csp,
+                                       struct http_response *rsp,
+                                       const struct map *parameters);
+extern jb_err cgi_edit_actions_add_url_form(struct client_state *csp,
+                                            struct http_response *rsp,
+                                            const struct map *parameters);
+extern jb_err cgi_edit_actions_remove_url    (struct client_state *csp,
+                                              struct http_response *rsp,
+                                              const struct map *parameters);
+extern jb_err cgi_edit_actions_remove_url_form(struct client_state *csp,
+                                            struct http_response *rsp,
+                                            const struct map *parameters);
+extern jb_err cgi_edit_actions_section_remove(struct client_state *csp,
+                                              struct http_response *rsp,
+                                              const struct map *parameters);
+extern jb_err cgi_edit_actions_section_add   (struct client_state *csp,
+                                              struct http_response *rsp,
+                                              const struct map *parameters);
+extern jb_err cgi_edit_actions_section_swap  (struct client_state *csp,
+                                              struct http_response *rsp,
+                                              const struct map *parameters);
+extern jb_err cgi_toggle(struct client_state *csp,
+                         struct http_response *rsp,
+                         const struct map *parameters);
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
+
+
+/* Revision control strings from this header and associated .c file */
+extern const char cgiedit_rcs[];
+extern const char cgiedit_h_rcs[];
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef CGI_H_INCLUDED */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/cgisimple.c b/cgisimple.c
new file mode 100644 (file)
index 0000000..a985f47
--- /dev/null
@@ -0,0 +1,1416 @@
+const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.34 2002/04/30 12:06:12 oes Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/cgisimple.c,v $
+ *
+ * Purpose     :  Simple CGIs to get information about Privoxy's
+ *                status.
+ *                
+ *                Functions declared include:
+ * 
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: cgisimple.c,v $
+ *    Revision 1.34  2002/04/30 12:06:12  oes
+ *    Deleted unused code from default_cgi
+ *
+ *    Revision 1.33  2002/04/30 11:14:52  oes
+ *    Made csp the first parameter in *action_to_html
+ *
+ *    Revision 1.32  2002/04/26 18:29:13  jongfoster
+ *    Fixing this Visual C++ warning:
+ *    cgisimple.c(775) : warning C4018: '<' : signed/unsigned mismatch
+ *
+ *    Revision 1.31  2002/04/26 12:54:36  oes
+ *     - Kill obsolete REDIRECT_URL code
+ *     - Error handling fixes
+ *     - Style sheet related HTML snipplet changes
+ *     - cgi_show_url_info:
+ *       - Matches now in table, actions on single lines,
+ *         linked to help
+ *       - standard.action suppressed
+ *       - Buttons to View and Edit AFs
+ *
+ *    Revision 1.30  2002/04/24 02:18:08  oes
+ *     - show-status is now the starting point for editing
+ *       the actions files, generate list of all AFs with buttons
+ *       for viewing and editing, new look for file list (Jon:
+ *       buttons now aligned ;-P ), view mode now supports multiple
+ *       AFs, name changes, no view links for unspecified files,
+ *       no edit link for standard.action.
+ *
+ *     - Jon's multiple AF patch: cgi_show_url_info now uses all
+ *       AFs and marks the output accordingly
+ *
+ *    Revision 1.29  2002/04/10 13:38:35  oes
+ *    load_template signature changed
+ *
+ *    Revision 1.28  2002/04/07 15:42:12  jongfoster
+ *    Fixing send-banner?type=auto when the image-blocker is
+ *    a redirect to send-banner
+ *
+ *    Revision 1.27  2002/04/05 15:50:48  oes
+ *    added send-stylesheet CGI
+ *
+ *    Revision 1.26  2002/04/04 00:36:36  gliptak
+ *    always use pcre for matching
+ *
+ *    Revision 1.25  2002/04/03 22:28:03  gliptak
+ *    Removed references to gnu_regex
+ *
+ *    Revision 1.24  2002/04/02 16:12:47  oes
+ *    Fix: moving misplaced lines into #ifdef FEATURE_FORCE
+ *
+ *    Revision 1.23  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.22  2002/03/24 16:18:15  jongfoster
+ *    Removing old logo
+ *
+ *    Revision 1.21  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.20  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.19  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.18  2002/03/12 01:44:49  oes
+ *    Changed default for "blocked" image from jb logo to checkboard pattern
+ *
+ *    Revision 1.17  2002/03/08 16:43:18  oes
+ *    Added choice beween GIF and PNG built-in images
+ *
+ *    Revision 1.16  2002/03/07 03:48:38  oes
+ *     - Changed built-in images from GIF to PNG
+ *       (with regard to Unisys patent issue)
+ *     - Added a 4x4 pattern PNG which is less intrusive
+ *       than the logo but also clearly marks the deleted banners
+ *
+ *    Revision 1.15  2002/03/06 22:54:35  jongfoster
+ *    Automated function-comment nitpicking.
+ *
+ *    Revision 1.14  2002/03/02 04:14:50  david__schmidt
+ *    Clean up a little CRLF unpleasantness that suddenly appeared
+ *
+ *    Revision 1.13  2002/02/21 00:10:37  jongfoster
+ *    Adding send-banner?type=auto option
+ *
+ *    Revision 1.12  2002/01/23 01:03:32  jongfoster
+ *    Fixing gcc [CygWin] compiler warnings
+ *
+ *    Revision 1.11  2002/01/23 00:01:04  jongfoster
+ *    Adding cgi_transparent_gif() for http://i.j.b/t
+ *    Adding missing html_encode() to many CGI functions.
+ *    Adding urlmatch.[ch] to http://i.j.b/show-version
+ *
+ *    Revision 1.10  2002/01/17 21:10:37  jongfoster
+ *    Changes to cgi_show_url_info to use new matching code from urlmatch.c.
+ *    Also fixing a problem in the same function with improperly quoted URLs
+ *    in output HTML, and adding code to handle https:// URLs correctly.
+ *
+ *    Revision 1.9  2001/11/30 23:09:15  jongfoster
+ *    Now reports on FEATURE_CGI_EDIT_ACTIONS
+ *    Removing FEATURE_DENY_GZIP from template
+ *
+ *    Revision 1.8  2001/11/13 00:14:07  jongfoster
+ *    Fixing stupid bug now I've figured out what || means.
+ *    (It always returns 0 or 1, not one of it's paramaters.)
+ *
+ *    Revision 1.7  2001/10/23 21:48:19  jongfoster
+ *    Cleaning up error handling in CGI functions - they now send back
+ *    a HTML error page and should never cause a FATAL error.  (Fixes one
+ *    potential source of "denial of service" attacks).
+ *
+ *    CGI actions file editor that works and is actually useful.
+ *
+ *    Ability to toggle JunkBuster remotely using a CGI call.
+ *
+ *    You can turn off both the above features in the main configuration
+ *    file, e.g. if you are running a multi-user proxy.
+ *
+ *    Revision 1.6  2001/10/14 22:00:32  jongfoster
+ *    Adding support for a 404 error when an invalid CGI page is requested.
+ *
+ *    Revision 1.5  2001/10/07 15:30:41  oes
+ *    Removed FEATURE_DENY_GZIP
+ *
+ *    Revision 1.4  2001/10/02 15:31:12  oes
+ *    Introduced show-request cgi
+ *
+ *    Revision 1.3  2001/09/22 16:34:44  jongfoster
+ *    Removing unneeded #includes
+ *
+ *    Revision 1.2  2001/09/19 18:01:11  oes
+ *    Fixed comments; cosmetics
+ *
+ *    Revision 1.1  2001/09/16 17:08:54  jongfoster
+ *    Moving simple CGI functions from cgi.c to new file cgisimple.c
+ *
+ *
+ **********************************************************************/
+\f
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#endif /* def _WIN32 */
+
+#include "project.h"
+#include "cgi.h"
+#include "cgisimple.h"
+#include "list.h"
+#include "encode.h"
+#include "jcc.h"
+#include "filters.h"
+#include "actions.h"
+#include "miscutil.h"
+#include "loadcfg.h"
+#include "parsers.h"
+#include "urlmatch.h"
+#include "errlog.h"
+
+const char cgisimple_h_rcs[] = CGISIMPLE_H_VERSION;
+
+
+static char *show_rcs(void);
+static jb_err show_defines(struct map *exports);
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_default
+ *
+ * Description :  CGI function that is called for the CGI_SITE_1_HOST
+ *                and CGI_SITE_2_HOST/CGI_SITE_2_PATH base URLs.
+ *                Boring - only exports the default exports.
+ *               
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *
+ *********************************************************************/
+jb_err cgi_default(struct client_state *csp,
+                   struct http_response *rsp,
+                   const struct map *parameters)
+{
+   struct map *exports;
+
+   assert(csp);
+   assert(rsp);
+
+   if (NULL == (exports = default_exports(csp, "")))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   return template_fill_for_cgi(csp, "default", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_error_404
+ *
+ * Description :  CGI function that is called if an unknown action was
+ *                given.
+ *               
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_error_404(struct client_state *csp,
+                     struct http_response *rsp,
+                     const struct map *parameters)
+{
+   struct map *exports;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (NULL == (exports = default_exports(csp, NULL)))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->status = strdup("404 Privoxy configuration page not found");
+   if (rsp->status == NULL)
+   {
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+
+   return template_fill_for_cgi(csp, "cgi-error-404", exports, rsp);
+}
+
+
+#ifdef FEATURE_GRACEFUL_TERMINATION
+/*********************************************************************
+ *
+ * Function    :  cgi_die
+ *
+ * Description :  CGI function to shut down Privoxy.
+ *                NOTE: Turning this on in a production build
+ *                would be a BAD idea.  An EXTREMELY BAD idea.
+ *                In short, don't do it.
+ *               
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_die (struct client_state *csp,
+                struct http_response *rsp,
+                const struct map *parameters)
+{
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   /* quit */
+   g_terminate = 1;
+
+   /*
+    * I don't really care what gets sent back to the browser.
+    * Take the easy option - "out of memory" page.
+    */
+
+   return JB_ERR_MEMORY;
+}
+#endif /* def FEATURE_GRACEFUL_TERMINATION */
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_show_request
+ *
+ * Description :  Show the client's request and what sed() would have
+ *                made of it.
+ *               
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_show_request(struct client_state *csp,
+                        struct http_response *rsp,
+                        const struct map *parameters)
+{
+   char *p;
+   struct map *exports;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (NULL == (exports = default_exports(csp, "show-request")))
+   {
+      return JB_ERR_MEMORY;
+   }
+   
+   /*
+    * Repair the damage done to the IOB by get_header()
+    */
+   for (p = csp->iob->buf; p < csp->iob->eod; p++)
+   {
+      if (*p == '\0') *p = '\n';
+   }
+
+   /*
+    * Export the original client's request and the one we would
+    * be sending to the server if this wasn't a CGI call
+    */
+
+   if (map(exports, "client-request", 1, html_encode(csp->iob->buf), 0))
+   {
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+
+   if (map(exports, "processed-request", 1, html_encode_and_free_original(
+      sed(client_patterns, add_client_headers, csp)), 0))
+   {
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+
+   return template_fill_for_cgi(csp, "show-request", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_send_banner
+ *
+ * Description :  CGI function that returns a banner. 
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *           type : Selects the type of banner between "trans", "logo",
+ *                  and "auto". Defaults to "logo" if absent or invalid.
+ *                  "auto" means to select as if we were image-blocking.
+ *                  (Only the first character really counts).
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_send_banner(struct client_state *csp,
+                       struct http_response *rsp,
+                       const struct map *parameters)
+{
+   char imagetype = lookup(parameters, "type")[0];
+
+   if (imagetype == 'a') /* auto */
+   {
+      /* Default to pattern */
+      imagetype = 'p';
+#ifdef FEATURE_IMAGE_BLOCKING
+      if ((csp->action->flags & ACTION_IMAGE_BLOCKER) != 0)
+      {
+         static const char prefix1[] = CGI_PREFIX "send-banner?type=";
+         static const char prefix2[] = "http://" CGI_SITE_1_HOST "/send-banner?type=";
+
+         /* determine HOW images should be blocked */
+         const char * p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER];
+
+         /* and handle accordingly: */
+         if (p == NULL)
+         {
+            /* Use default - nothing to do here. */
+         }
+         else if (0 == strcmpic(p, "blank"))
+         {
+            imagetype = 'b';
+         }
+         else if (0 == strcmpic(p, "pattern"))
+         {
+            imagetype = 'p';
+         }
+         else if (0 == strncmpic(p, prefix1, sizeof(prefix1) - 1))
+         {
+            imagetype = p[sizeof(prefix1) - 1];
+         }
+         else if (0 == strncmpic(p, prefix2, sizeof(prefix2) - 1))
+         {
+            imagetype = p[sizeof(prefix2) - 1];
+         }
+      }
+#endif /* def FEATURE_IMAGE_BLOCKING */
+   }
+      
+   if ((imagetype == 'b') || (imagetype == 't')) /* blank / transparent */
+   {
+      rsp->body = bindup(image_blank_data, image_blank_length);
+      rsp->content_length = image_blank_length;
+
+   }
+   else /* pattern */
+   {
+      rsp->body = bindup(image_pattern_data, image_pattern_length);
+      rsp->content_length = image_pattern_length;
+   }   
+
+   if (rsp->body == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   if (enlist(rsp->headers, "Content-Type: " BUILTIN_IMAGE_MIMETYPE))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->is_static = 1;
+
+   return JB_ERR_OK;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_transparent_image
+ *
+ * Description :  CGI function that sends a 1x1 transparent image.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : None
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_transparent_image(struct client_state *csp,
+                             struct http_response *rsp,
+                             const struct map *parameters)
+{
+   rsp->body = bindup(image_blank_data, image_blank_length);
+   rsp->content_length = image_blank_length;
+
+   if (rsp->body == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   if (enlist(rsp->headers, "Content-Type: " BUILTIN_IMAGE_MIMETYPE))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   rsp->is_static = 1;
+
+   return JB_ERR_OK;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_send_stylesheet
+ *
+ * Description :  CGI function that sends a css stylesheet found
+ *                in the cgi-style.css template
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : None
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_send_stylesheet(struct client_state *csp,
+                           struct http_response *rsp,
+                           const struct map *parameters)
+{
+   jb_err err;
+   
+   assert(csp);
+   assert(rsp);
+
+   err = template_load(csp, &rsp->body, "cgi-style.css", 0);
+
+   if (err == JB_ERR_FILE)
+   {
+      /*
+       * No way to tell user; send empty stylesheet
+       */
+      log_error(LOG_LEVEL_ERROR, "Could not find cgi-style.css template");
+   }
+   else if (err)
+   {
+      return err; /* JB_ERR_MEMORY */
+   }
+
+   if (enlist(rsp->headers, "Content-Type: text/css"))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   return JB_ERR_OK;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_show_version
+ *
+ * Description :  CGI function that returns a a web page describing the
+ *                file versions of Privoxy.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : none
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_show_version(struct client_state *csp,
+                        struct http_response *rsp,
+                        const struct map *parameters)
+{
+   struct map *exports;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (NULL == (exports = default_exports(csp, "show-version")))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   if (map(exports, "sourceversions", 1, show_rcs(), 0))
+   {
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+
+   return template_fill_for_cgi(csp, "show-version", exports, rsp);
+}
+
+/*********************************************************************
+ *
+ * Function    :  cgi_show_status
+ *
+ * Description :  CGI function that returns a a web page describing the
+ *                current status of Privoxy.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *        file :  Which file to show.  Only first letter is checked,
+ *                valid values are:
+ *                - "p"ermissions (actions) file
+ *                - "r"egex
+ *                - "t"rust
+ *                Default is to show menu and other information.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_show_status(struct client_state *csp,
+                       struct http_response *rsp,
+                       const struct map *parameters)
+{
+   char *s = NULL;
+   unsigned i;
+   int j;
+
+   FILE * fp;
+   char buf[BUFFER_SIZE];
+   const char * filename = NULL;
+   char * file_description = NULL;
+#ifdef FEATURE_STATISTICS
+   float perc_rej;   /* Percentage of http requests rejected */
+   int local_urls_read;
+   int local_urls_rejected;
+#endif /* ndef FEATURE_STATISTICS */
+   struct file_list * fl;
+   struct url_actions * b;
+   jb_err err = JB_ERR_OK;
+
+   struct map *exports;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (NULL == (exports = default_exports(csp, "show-status")))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   switch (*(lookup(parameters, "file")))
+   {
+   case 'a':
+      if (!get_number_param(csp, parameters, "index", &i) && i < MAX_ACTION_FILES && csp->actions_list[i])
+      {
+         filename = csp->actions_list[i]->filename;
+         file_description = "Actions File";
+      }
+      break;
+
+   case 'f':
+      if (csp->rlist)
+      {
+         filename = csp->rlist->filename;
+         file_description = "Filter File";
+      }
+      break;
+
+#ifdef FEATURE_TRUST
+   case 't':
+      if (csp->tlist)
+      {
+         filename = csp->tlist->filename;
+         file_description = "Trust File";
+      }
+      break;
+#endif /* def FEATURE_TRUST */
+   }
+
+   if (NULL != filename)
+   {
+      if ( map(exports, "file-description", 1, file_description, 1)
+        || map(exports, "filepath", 1, html_encode(filename), 0) )
+      {
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+
+      if ((fp = fopen(filename, "r")) == NULL)
+      {
+         if (map(exports, "content", 1, "<h1>ERROR OPENING FILE!</h1>", 1))
+         {
+            free_map(exports);
+            return JB_ERR_MEMORY;
+         }
+      }
+      else
+      {
+         s = strdup("");
+         while ((s != NULL) && fgets(buf, sizeof(buf), fp))
+         {
+            string_join  (&s, html_encode(buf));
+         }
+         fclose(fp);
+
+         if (map(exports, "contents", 1, s, 0))
+         {
+            free_map(exports);
+            return JB_ERR_MEMORY;
+         }
+      }
+
+      return template_fill_for_cgi(csp, "show-status-file", exports, rsp);
+   }
+
+   s = strdup("");
+   for (j = 0; (s != NULL) && (j < Argc); j++)
+   {
+      if (!err) err = string_join  (&s, html_encode(Argv[j]));
+      if (!err) err = string_append(&s, " ");
+   }
+   if (!err) err = map(exports, "invocation", 1, s, 0);
+
+   if (!err) err = map(exports, "options", 1, csp->config->proxy_args, 1);
+   if (!err) err = show_defines(exports);
+
+   if (err) 
+   {
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+
+#ifdef FEATURE_STATISTICS
+   local_urls_read     = urls_read;
+   local_urls_rejected = urls_rejected;
+
+   /*
+    * Need to alter the stats not to include the fetch of this
+    * page.
+    *
+    * Can't do following thread safely! doh!
+    *
+    * urls_read--;
+    * urls_rejected--; * This will be incremented subsequently *
+    */
+
+   if (local_urls_read == 0)
+   {
+      if (!err) err = map_block_killer(exports, "have-stats");
+   }
+   else
+   {
+      if (!err) err = map_block_killer(exports, "have-no-stats");
+
+      perc_rej = (float)local_urls_rejected * 100.0F /
+            (float)local_urls_read;
+
+      sprintf(buf, "%d", local_urls_read);
+      if (!err) err = map(exports, "requests-received", 1, buf, 1);
+
+      sprintf(buf, "%d", local_urls_rejected);
+      if (!err) err = map(exports, "requests-blocked", 1, buf, 1);
+
+      sprintf(buf, "%6.2f", perc_rej);
+      if (!err) err = map(exports, "percent-blocked", 1, buf, 1);
+   }
+
+#else /* ndef FEATURE_STATISTICS */
+   err = err || map_block_killer(exports, "statistics");
+#endif /* ndef FEATURE_STATISTICS */
+   
+   /* 
+    * List all action files in use, together with view and edit links,
+    * except for standard.action, which should only be viewable. (Not
+    * enforced in the editor itself)
+    * FIXME: Shouldn't include hardwired HTML here, use line template instead!
+    */
+   s = strdup("");
+   for (i = 0; i < MAX_ACTION_FILES; i++)
+   {
+      if (((fl = csp->actions_list[i]) != NULL) && ((b = fl->f) != NULL))
+      {
+         if (!err) err = string_append(&s, "<tr><td>");
+         if (!err) err = string_join(&s, html_encode(csp->actions_list[i]->filename));
+         snprintf(buf, 100, "</td><td class=\"buttons\"><a href=\"/show-status?file=actions&index=%d\">View</a> ", i);
+         if (!err) err = string_append(&s, buf);
+
+         if (NULL == strstr(csp->actions_list[i]->filename, "standard.action") && NULL != csp->config->actions_file_short[i])
+         {
+            snprintf(buf, 100, "<a href=\"/edit-actions-list?f=%s\">Edit</a>", csp->config->actions_file_short[i]);
+            if (!err) err = string_append(&s, buf);
+         }
+
+         if (!err) err = string_append(&s, "</td></tr>\n");
+      }
+   }
+   if (*s != '\0')   
+   {
+      if (!err) err = map(exports, "actions-filenames", 1, s, 0);
+   }
+   else
+   {
+      if (!err) err = map(exports, "actions-filenames", 1, "<tr><td>None specified</td></tr>", 1);
+   }
+
+   if (csp->rlist)
+   {
+      if (!err) err = map(exports, "re-filter-filename", 1, html_encode(csp->rlist->filename), 0);
+   }
+   else
+   {
+      if (!err) err = map(exports, "re-filter-filename", 1, "None specified", 1);
+      if (!err) err = map_block_killer(exports, "have-filterfile");
+   }
+
+#ifdef FEATURE_TRUST
+   if (csp->tlist)
+   {
+      if (!err) err = map(exports, "trust-filename", 1, html_encode(csp->tlist->filename), 0);
+   }
+   else
+   {
+      if (!err) err = map(exports, "trust-filename", 1, "None specified", 1);
+      if (!err) err = map_block_killer(exports, "have-trustfile");
+   }
+#else
+   if (!err) err = map_block_killer(exports, "trust-support");
+#endif /* ndef FEATURE_TRUST */
+
+   if (err)
+   {
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+
+   return template_fill_for_cgi(csp, "show-status", exports, rsp);
+}
+
+/*********************************************************************
+ *
+ * Function    :  cgi_show_url_info
+ *
+ * Description :  CGI function that determines and shows which actions
+ *                Privoxy will perform for a given url, and which
+ *                matches starting from the defaults have lead to that.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters :
+ *            url : The url whose actions are to be determined.
+ *                  If url is unset, the url-given conditional will be
+ *                  set, so that all but the form can be suppressed in
+ *                  the template.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_show_url_info(struct client_state *csp,
+                         struct http_response *rsp,
+                         const struct map *parameters)
+{
+   char *url_param;
+   struct map *exports;
+   char buf[150];
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   if (NULL == (exports = default_exports(csp, "show-url-info")))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   /*
+    * Get the url= parameter (if present) and remove any leading/trailing spaces.
+    */
+   url_param = strdup(lookup(parameters, "url"));
+   if (url_param == NULL)
+   {
+      free_map(exports);
+      return JB_ERR_MEMORY;
+   }
+   chomp(url_param);
+
+   /*
+    * Handle prefixes.  4 possibilities:
+    * 1) "http://" or "https://" prefix present and followed by URL - OK
+    * 2) Only the "http://" or "https://" part is present, no URL - change
+    *    to empty string so it will be detected later as "no URL".
+    * 3) Parameter specified but doesn't contain "http(s?)://" - add a
+    *    "http://" prefix.
+    * 4) Parameter not specified or is empty string - let this fall through
+    *    for now, next block of code will handle it.
+    */
+   if (0 == strncmp(url_param, "http://", 7))
+   {
+      if (url_param[7] == '\0')
+      {
+         /*
+          * Empty URL (just prefix).
+          * Make it totally empty so it's caught by the next if()
+          */
+         url_param[0] = '\0';
+      }
+   }
+   else if (0 == strncmp(url_param, "https://", 8))
+   {
+      if (url_param[8] == '\0')
+      {
+         /*
+          * Empty URL (just prefix).
+          * Make it totally empty so it's caught by the next if()
+          */
+         url_param[0] = '\0';
+      }
+   }
+   else if (url_param[0] != '\0')
+   {
+      /*
+       * Unknown prefix - assume http://
+       */
+      char * url_param_prefixed = malloc(7 + 1 + strlen(url_param));
+      if (NULL == url_param_prefixed)
+      {
+         free(url_param);
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+      strcpy(url_param_prefixed, "http://");
+      strcpy(url_param_prefixed + 7, url_param);
+      free(url_param);
+      url_param = url_param_prefixed;
+   }
+
+
+   if (url_param[0] == '\0')
+   {
+      /* URL paramater not specified, display query form only. */
+      free(url_param);
+      if (map_block_killer(exports, "url-given")
+        || map(exports, "url", 1, "", 1))
+      {
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+   }
+   else
+   {
+      /* Given a URL, so query it. */
+      jb_err err;
+      char *matches;
+      char *s;
+      int hits = 0;
+      struct file_list *fl;
+      struct url_actions *b;
+      struct http_request url_to_query[1];
+      struct current_action_spec action[1];
+      int i;
+      
+      if (map(exports, "url", 1, html_encode(url_param), 0))
+      {
+         free(url_param);
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+
+      init_current_action(action);
+
+      if (map(exports, "default", 1, current_action_to_html(csp, action), 0))
+      {
+         free_current_action(action);
+         free(url_param);
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+
+      err = parse_http_url(url_param, url_to_query, csp);
+
+      free(url_param);
+
+      if (err == JB_ERR_MEMORY)
+      {
+         free_current_action(action);
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+      else if (err)
+      {
+         /* Invalid URL */
+
+         err = map(exports, "matches", 1, "<b>[Invalid URL specified!]</b>" , 1);
+         if (!err) err = map(exports, "final", 1, lookup(exports, "default"), 1);
+
+         free_current_action(action);
+
+         if (err)
+         {
+            free_map(exports);
+            return JB_ERR_MEMORY;
+         }
+
+         return template_fill_for_cgi(csp, "show-url-info", exports, rsp);
+      }
+
+      /*
+       * We have a warning about SSL paths.  Hide it for insecure sites.
+       */
+      if (!url_to_query->ssl)
+      {
+         if (map_block_killer(exports, "https"))
+         {
+            free_current_action(action);
+            free_map(exports);
+            return JB_ERR_MEMORY;
+         }
+      }
+
+      matches = strdup("<table class=\"transparent\">");
+
+      for (i = 0; i < MAX_ACTION_FILES; i++)
+      {
+         if (NULL == csp->config->actions_file_short[i]
+             || !strcmp(csp->config->actions_file_short[i], "standard")) continue;
+
+         b = NULL;
+         hits = 1;
+         if ((fl = csp->actions_list[i]) != NULL)
+         {
+            if ((b = fl->f) != NULL)
+            {
+               /* FIXME: Hardcoded HTML! */
+               string_append(&matches, "<tr><th>In file: ");
+               string_join  (&matches, html_encode(csp->config->actions_file_short[i]));
+               snprintf(buf, 150, ".action <a class=\"cmd\" href=\"/show-status?file=actions&index=%d\">", i);
+               string_append(&matches, buf);
+               string_append(&matches, "View</a> <a class=\"cmd\" href=\"/edit-actions-list?f=");
+               string_join  (&matches, html_encode(csp->config->actions_file_short[i]));
+               string_append(&matches, "\">Edit</a></th></tr>\n");
+
+               hits = 0;
+               b = b->next;
+            }
+         }
+
+         for (; (b != NULL) && (matches != NULL); b = b->next)
+         {
+            if (url_match(b->url, url_to_query))
+            {
+               string_append(&matches, "<tr><td>{");
+               string_join  (&matches, actions_to_html(csp, b->action));
+               string_append(&matches, " }</b><br>\n<code>");
+               string_join  (&matches, html_encode(b->url->spec));
+               string_append(&matches, "</code></td></tr>\n");
+
+               if (merge_current_action(action, b->action))
+               {
+                  freez(matches);
+                  free_http_request(url_to_query);
+                  free_current_action(action);
+                  free_map(exports);
+                  return JB_ERR_MEMORY;
+               }
+               hits++;
+            }
+         }
+
+         if (!hits)
+         {
+            string_append(&matches, "<tr><td>(no matches in this file)</td></tr>\n");
+         }
+      }
+      string_append(&matches, "</table>\n");
+
+      free_http_request(url_to_query);
+
+      if (matches == NULL)
+      {
+         free_current_action(action);
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+
+      if (map(exports, "matches", 1, matches , 0))
+      {
+         free_current_action(action);
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+
+      s = current_action_to_html(csp, action);
+
+      free_current_action(action);
+
+      if (map(exports, "final", 1, s, 0))
+      {
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+   }
+
+   return template_fill_for_cgi(csp, "show-url-info", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_robots_txt
+ *
+ * Description :  CGI function to return "/robots.txt".
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : None
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+jb_err cgi_robots_txt(struct client_state *csp,
+                      struct http_response *rsp,
+                      const struct map *parameters)
+{
+   char buf[100];
+   jb_err err;
+
+   rsp->body = strdup(
+      "# This is the Privoxy control interface.\n"
+      "# It isn't very useful to index it, and you're likely to break stuff.\n"
+      "# So go away!\n"
+      "\n"
+      "User-agent: *\n"
+      "Disallow: /\n"
+      "\n");
+   if (rsp->body == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   err = enlist_unique(rsp->headers, "Content-Type: text/plain", 13);
+
+   rsp->is_static = 1;
+
+   get_http_time(7 * 24 * 60 * 60, buf); /* 7 days into future */
+   if (!err) err = enlist_unique_header(rsp->headers, "Expires", buf);
+
+   return (err ? JB_ERR_MEMORY : JB_ERR_OK);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  show_defines
+ *
+ * Description :  Add to a map the state od all conditional #defines
+ *                used when building
+ *
+ * Parameters  :
+ *          1  :  exports = map to extend
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.  
+ *
+ *********************************************************************/
+static jb_err show_defines(struct map *exports)
+{
+   jb_err err = JB_ERR_OK;
+
+#ifdef FEATURE_ACL
+   if (!err) err = map_conditional(exports, "FEATURE_ACL", 1);
+#else /* ifndef FEATURE_ACL */
+   if (!err) err = map_conditional(exports, "FEATURE_ACL", 0);
+#endif /* ndef FEATURE_ACL */
+
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+   if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 1);
+#else /* ifndef FEATURE_COOKIE_JAR */
+   if (!err) err = map_conditional(exports, "FEATURE_CGI_EDIT_ACTIONS", 0);
+#endif /* ndef FEATURE_COOKIE_JAR */
+
+#ifdef FEATURE_COOKIE_JAR
+   if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 1);
+#else /* ifndef FEATURE_COOKIE_JAR */
+   if (!err) err = map_conditional(exports, "FEATURE_COOKIE_JAR", 0);
+#endif /* ndef FEATURE_COOKIE_JAR */
+
+#ifdef FEATURE_FAST_REDIRECTS
+   if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 1);
+#else /* ifndef FEATURE_FAST_REDIRECTS */
+   if (!err) err = map_conditional(exports, "FEATURE_FAST_REDIRECTS", 0);
+#endif /* ndef FEATURE_FAST_REDIRECTS */
+
+#ifdef FEATURE_FORCE_LOAD
+   if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 1);
+   if (!err) err = map(exports, "FORCE_PREFIX", 1, FORCE_PREFIX, 1);
+#else /* ifndef FEATURE_FORCE_LOAD */
+   if (!err) err = map_conditional(exports, "FEATURE_FORCE_LOAD", 0);
+   if (!err) err = map(exports, "FORCE_PREFIX", 1, "(none - disabled)", 1);
+#endif /* ndef FEATURE_FORCE_LOAD */
+
+#ifdef FEATURE_IMAGE_BLOCKING
+   if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 1);
+#else /* ifndef FEATURE_IMAGE_BLOCKING */
+   if (!err) err = map_conditional(exports, "FEATURE_IMAGE_BLOCKING", 0);
+#endif /* ndef FEATURE_IMAGE_BLOCKING */
+
+#ifdef FEATURE_IMAGE_DETECT_MSIE
+   if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 1);
+#else /* ifndef FEATURE_IMAGE_DETECT_MSIE */
+   if (!err) err = map_conditional(exports, "FEATURE_IMAGE_DETECT_MSIE", 0);
+#endif /* ndef FEATURE_IMAGE_DETECT_MSIE */
+
+#ifdef FEATURE_KILL_POPUPS
+   if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 1);
+#else /* ifndef FEATURE_KILL_POPUPS */
+   if (!err) err = map_conditional(exports, "FEATURE_KILL_POPUPS", 0);
+#endif /* ndef FEATURE_KILL_POPUPS */
+
+#ifdef FEATURE_NO_GIFS
+   if (!err) err = map_conditional(exports, "FEATURE_NO_GIFS", 1);
+#else /* ifndef FEATURE_NO_GIFS */
+   if (!err) err = map_conditional(exports, "FEATURE_NO_GIFS", 0);
+#endif /* ndef FEATURE_NO_GIFS */
+
+#ifdef FEATURE_PTHREAD
+   if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 1);
+#else /* ifndef FEATURE_PTHREAD */
+   if (!err) err = map_conditional(exports, "FEATURE_PTHREAD", 0);
+#endif /* ndef FEATURE_PTHREAD */
+
+#ifdef FEATURE_STATISTICS
+   if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 1);
+#else /* ifndef FEATURE_STATISTICS */
+   if (!err) err = map_conditional(exports, "FEATURE_STATISTICS", 0);
+#endif /* ndef FEATURE_STATISTICS */
+
+#ifdef FEATURE_TOGGLE
+   if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 1);
+#else /* ifndef FEATURE_TOGGLE */
+   if (!err) err = map_conditional(exports, "FEATURE_TOGGLE", 0);
+#endif /* ndef FEATURE_TOGGLE */
+
+#ifdef FEATURE_TRUST
+   if (!err) err = map_conditional(exports, "FEATURE_TRUST", 1);
+#else /* ifndef FEATURE_TRUST */
+   if (!err) err = map_conditional(exports, "FEATURE_TRUST", 0);
+#endif /* ndef FEATURE_TRUST */
+
+#ifdef STATIC_PCRE
+   if (!err) err = map_conditional(exports, "STATIC_PCRE", 1);
+#else /* ifndef STATIC_PCRE */
+   if (!err) err = map_conditional(exports, "STATIC_PCRE", 0);
+#endif /* ndef STATIC_PCRE */
+
+#ifdef STATIC_PCRS
+   if (!err) err = map_conditional(exports, "STATIC_PCRS", 1);
+#else /* ifndef STATIC_PCRS */
+   if (!err) err = map_conditional(exports, "STATIC_PCRS", 0);
+#endif /* ndef STATIC_PCRS */
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  show_rcs
+ *
+ * Description :  Create a string with the rcs info for all sourcefiles
+ *
+ * Parameters  :  None
+ *
+ * Returns     :  A string, or NULL on out-of-memory.
+ *
+ *********************************************************************/
+static char *show_rcs(void)
+{
+   char *result = strdup("");
+   char buf[BUFFER_SIZE];
+
+   /* Instead of including *all* dot h's in the project (thus creating a
+    * tremendous amount of dependencies), I will concede to declaring them
+    * as extern's.  This forces the developer to add to this list, but oh well.
+    */
+
+#define SHOW_RCS(__x)              \
+   {                               \
+      extern const char __x[];     \
+      sprintf(buf, "%s\n", __x);   \
+      string_append(&result, buf); \
+   }
+
+   /* In alphabetical order */
+   SHOW_RCS(actions_h_rcs)
+   SHOW_RCS(actions_rcs)
+#ifdef AMIGA
+   SHOW_RCS(amiga_h_rcs)
+   SHOW_RCS(amiga_rcs)
+#endif /* def AMIGA */
+   SHOW_RCS(cgi_h_rcs)
+   SHOW_RCS(cgi_rcs)
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+   SHOW_RCS(cgiedit_h_rcs)
+   SHOW_RCS(cgiedit_rcs)
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
+   SHOW_RCS(cgisimple_h_rcs)
+   SHOW_RCS(cgisimple_rcs)
+#ifdef __MINGW32__
+   SHOW_RCS(cygwin_h_rcs)
+#endif
+   SHOW_RCS(deanimate_h_rcs)
+   SHOW_RCS(deanimate_rcs)
+   SHOW_RCS(encode_h_rcs)
+   SHOW_RCS(encode_rcs)
+   SHOW_RCS(errlog_h_rcs)
+   SHOW_RCS(errlog_rcs)
+   SHOW_RCS(filters_h_rcs)
+   SHOW_RCS(filters_rcs)
+   SHOW_RCS(gateway_h_rcs)
+   SHOW_RCS(gateway_rcs)
+   SHOW_RCS(jbsockets_h_rcs)
+   SHOW_RCS(jbsockets_rcs)
+   SHOW_RCS(jcc_h_rcs)
+   SHOW_RCS(jcc_rcs)
+#ifdef FEATURE_KILL_POPUPS
+   SHOW_RCS(killpopup_h_rcs)
+   SHOW_RCS(killpopup_rcs)
+#endif /* def FEATURE_KILL_POPUPS */
+   SHOW_RCS(list_h_rcs)
+   SHOW_RCS(list_rcs)
+   SHOW_RCS(loadcfg_h_rcs)
+   SHOW_RCS(loadcfg_rcs)
+   SHOW_RCS(loaders_h_rcs)
+   SHOW_RCS(loaders_rcs)
+   SHOW_RCS(miscutil_h_rcs)
+   SHOW_RCS(miscutil_rcs)
+   SHOW_RCS(parsers_h_rcs)
+   SHOW_RCS(parsers_rcs)
+   SHOW_RCS(pcrs_rcs)
+   SHOW_RCS(pcrs_h_rcs)
+   SHOW_RCS(project_h_rcs)
+   SHOW_RCS(ssplit_h_rcs)
+   SHOW_RCS(ssplit_rcs)
+   SHOW_RCS(urlmatch_h_rcs)
+   SHOW_RCS(urlmatch_rcs)
+#ifdef _WIN32
+#ifndef _WIN_CONSOLE
+   SHOW_RCS(w32log_h_rcs)
+   SHOW_RCS(w32log_rcs)
+   SHOW_RCS(w32res_h_rcs)
+   SHOW_RCS(w32taskbar_h_rcs)
+   SHOW_RCS(w32taskbar_rcs)
+#endif /* ndef _WIN_CONSOLE */
+   SHOW_RCS(win32_h_rcs)
+   SHOW_RCS(win32_rcs)
+#endif /* def _WIN32 */
+
+#undef SHOW_RCS
+
+   return result;
+
+}
+
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/cgisimple.h b/cgisimple.h
new file mode 100644 (file)
index 0000000..88501d7
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef CGISIMPLE_H_INCLUDED
+#define CGISIMPLE_H_INCLUDED
+#define CGISIMPLE_H_VERSION "$Id: cgisimple.h,v 1.10 2002/03/26 22:29:54 swa Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/cgisimple.h,v $
+ *
+ * Purpose     :  Declares functions to intercept request, generate
+ *                html or gif answers, and to compose HTTP resonses.
+ *                
+ *                Functions declared include:
+ * 
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: cgisimple.h,v $
+ *    Revision 1.10  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.9  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.8  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.7  2002/03/08 16:43:59  oes
+ *    Renamed cgi_transparent_png to cgi_transparent_image
+ *
+ *    Revision 1.6  2002/03/07 03:48:59  oes
+ *     - Changed built-in images from GIF to PNG
+ *       (with regard to Unisys patent issue)
+ *
+ *    Revision 1.5  2002/01/22 23:26:03  jongfoster
+ *    Adding cgi_transparent_gif() for http://i.j.b/t
+ *
+ *    Revision 1.4  2001/10/23 21:48:19  jongfoster
+ *    Cleaning up error handling in CGI functions - they now send back
+ *    a HTML error page and should never cause a FATAL error.  (Fixes one
+ *    potential source of "denial of service" attacks).
+ *
+ *    CGI actions file editor that works and is actually useful.
+ *
+ *    Ability to toggle JunkBuster remotely using a CGI call.
+ *
+ *    You can turn off both the above features in the main configuration
+ *    file, e.g. if you are running a multi-user proxy.
+ *
+ *    Revision 1.3  2001/10/14 22:00:32  jongfoster
+ *    Adding support for a 404 error when an invalid CGI page is requested.
+ *
+ *    Revision 1.2  2001/10/02 15:31:20  oes
+ *    Introduced show-request cgi
+ *
+ *    Revision 1.1  2001/09/16 17:08:54  jongfoster
+ *    Moving simple CGI functions from cgi.c to new file cgisimple.c
+ *
+ *
+ **********************************************************************/
+\f
+
+#include "project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CGI functions
+ */
+extern jb_err cgi_default      (struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_error_404    (struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_robots_txt   (struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_send_banner  (struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_show_status  (struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_show_url_info(struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_show_version (struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_show_request (struct client_state *csp,
+                                struct http_response *rsp,
+                                const struct map *parameters);
+extern jb_err cgi_transparent_image (struct client_state *csp,
+                                     struct http_response *rsp,
+                                     const struct map *parameters);
+extern jb_err cgi_send_stylesheet(struct client_state *csp,
+                                  struct http_response *rsp,
+                                  const struct map *parameters);
+
+#ifdef FEATURE_GRACEFUL_TERMINATION
+extern jb_err cgi_die (struct client_state *csp,
+                       struct http_response *rsp,
+                       const struct map *parameters);
+#endif
+
+/* Revision control strings from this header and associated .c file */
+extern const char cgisimple_rcs[];
+extern const char cgisimple_h_rcs[];
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef CGISIMPLE_H_INCLUDED */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/config b/config
index 3ba741b..173b330 100644 (file)
--- a/config
+++ b/config
-#  Sample Configuration file for the Internet Junkbuster 2.0
+#  Sample Configuration file for Privoxy
+#
+# $Id: config,v 1.38 2002/05/03 03:59:25 hal9 Exp $
+#
+###################################################################
+#                                                                 #
+#                     Table of Contents                           #
+#                                                                 #
+#       I. INTRODUCTION                                           #
+#      II. FORMAT OF THE CONFIGURATION FILE                       #
+#                                                                 #
+#       1. CONFIGURATION AND LOG FILE LOCATIONS                   #
+#       2. LOCAL SET-UP DOCUMENTATION                             #
+#       3. DEBUGGING                                              #
+#       4. ACCESS CONTROL AND SECURITY                            #
+#       5. FORWARDING                                             #
+#       6. WINDOWS GUI OPTIONS                                    #
+#                                                                 #
+###################################################################
 
+#  I. INTRODUCTION
+#  ===============
 #
-# $Id: config,v 1.2 2001/04/30 03:05:11 rodney Exp $
+#  This file holds the Privoxy configuration.  If you modify this
+#  file, you will need to send a couple of requests to the proxy
+#  before any changes take effect.
+#
+#  When starting Privoxy on Unix systems, give the name of this
+#  file as an argument.  On Windows systems, Privoxy will look for
+#  this file with the name 'config.txt' in the same directory where
+#  Privoxy is installed.
 #
 
+#  II. FORMAT OF THE CONFIGURATION FILE
+#  ====================================
+#
+#  Configuration lines consist of an initial keyword followed by a list
+#  of values, all separated by whitespace (any number of spaces or
+#  tabs).  For example,
+#
+#  actionsfile default.action
+#
+#  Indicates that the actionsfile is named 'default.action'.
+#
+#  The '#' indicates a comment.  Any part of a line following a '#' is
+#  ignored, except if the '#' is preceded by a '\'.
 #
+#  Thus, by placing a # at the start of an existing configuration line,
+#  you can make it a comment and it will be treated as if it weren't there. 
+#  This is called "commenting out" an option and can be useful.
 #
-# Copyright 1997-8 Junkbusters Corp.  For distribution, modification and use
-# under the GNU General Public License. These files come with NO WARRANTY.
-# See http://www.junkbusters.com/ht/en/gpl.html or README file for details.
+#  Note that commenting out and option and leaving it at its default
+#  are two completely different things! Most options behave very
+#  differently when unset. See the the "Effect if unset" explanation
+#  in each option's description for details.
+#
+#  Long lines can be continued on the next line by using a `\' as
+#  the last character.
 #
-# When starting the proxy, give the name of this file as an argument.
-# Any changes made to this file are *not* automatically loaded; you have 
-# to stop and restart the proxy.
 
-# For information see http://www.junkbusters.com/ht/en/ijbman.html
-# or the documentation that came with the release
+#   1. CONFIGURATION AND LOG FILE LOCATIONS
+#   =======================================
+#
+#  Privoxy can (and normally does) use a number of other files for
+#  additional configuration and logging. This section of the
+#  configuration file tells Privoxy where to find those other files.
+#
+#  The user running Privoxy, must have read permission for all 
+#  configuration files, and write permission to any files that would 
+#  be modified, such as log files.
 
-# Lines beginning with a # character are comments; they are ignored.
-# Many example lines are provided here commented out
+#  1.1. user-manual
+#  ================
+# 
+#  Specifies:
+#    
+#      Location of the Privoxy User Manual.
+#     
+#  Type of value:
+#    
+#      A fully qualified URI
+#    
+#  Default value:
+#    
+#      http://www.privoxy.org/user-manual/
+#    
+#  Effect if unset:
+#    
+#      The default will be used.
+#    
+#  Notes:
+#    
+#     The User Manual is used for help hints from some of the internal
+#     CGI pages. It is normally packaged with the binary distributions,
+#     and would make more sense to have this pointed at a locally
+#     installed copy.
+#    
+#     A more useful example (Unix):
+#    
+#       user-manual  file:///usr/share/doc/privoxy-2.9.14/user-manual/
+#     
+#   +-----------------------------------------------------------------+
+#   |                             Warning                             |
+#   |-----------------------------------------------------------------|
+#   |If this option is defined, it must come first! It is needed      |
+#   |before the rest of config is read.                               |
+#   +-----------------------------------------------------------------+
+# 
+#    
+#user-manual http://www.privoxy.org/user-manual/
 
-# the blockfile contains patterns to be blocked by the proxy
-blockfile      ./blocklist # comments are OK here, too
+#  1.2. confdir
+#  ============
+# 
+#  Specifies:
+#     
+#      The directory where the other configuration files are located
+#     
+#  Type of value:
+#     
+#      Path name
+#     
+#  Default value:
+#     
+#      /etc/privoxy (Unix) or Privoxy installation dir (Windows)
+#     
+#  Effect if unset:
+#     
+#      Mandatory
+#     
+#  Notes:
+#     
+#      No trailing "/", please
+#     
+#      When development goes modular and multi-user, the blocker,
+#      filter, and per-user config will be stored in subdirectories of
+#      "confdir". For now, the configuration directory structure is
+#      flat, except for confdir/templates, where the HTML templates for
+#      CGI output reside (e.g. Privoxy's 404 error page).
+#  
+confdir .
 
-# the imagefile contains patterns to detect blocked images
-imagefile      ./imagelist
 
-# the popfile contains patterns of servers where javascript popups are disabled
+#  1.3. logdir
+#  ===========
+#  
+#  Specifies:
+#     
+#      The directory where all logging takes place (i.e. where logfile
+#      and jarfile are located)
+#     
+#  Type of value:
+#     
+#      Path name
+#     
+#  Default value:
+#     
+#      /var/log/privoxy (Unix) or Privoxy installation dir (Windows)
+#     
+#  Effect if unset:
+#     
+#      Mandatory
+#     
+#  Notes:
+#    
+#      No trailing "/", please
 #
-# if the next line is not commented out, all javascript popups from the sites 
-# that match the patterns in popup will be blocked
-# popupfile     ./popup
+logdir .
 
-# File containing content modification rules
-#re_filterfile   ./re_filterfile
 
-# Uncomment to filter *all* traffic. Default is to
-# filter only if we wouldn't send a cookie either.
+#  1.4. actionsfile
+#  ================ 
+#  
+#  Specifies:
+#     
+#      The actions file to use
+#     
+#  Type of value:
+#     
+#      File name, relative to confdir, without the .action (Unix)
+#      or .action.txt (Windows) extension.
+#     
+#  Default values:
+#      standard  # Internal purpose, recommended
+#      default   # Main actions file
+#      user      # User customizations
+#     
+#  Effect if unset:
+#     
+#      No action is taken at all. Simple neutral proxying.
+#     
+#  Notes:
+#      Multiple actionsfile lines are OK and are in fact recommended!
 #
-#re_filter_all
+#      The default values include standard.action, which is used for
+#      internal purposes and should be loaded, default.action, which
+#      is the "main" actions file maintained by the developers, and
+#      user.action, where you can make your personal additions.
+#     
+#      There is no point in using Privoxy without an actions file.
+#
+actionsfile standard  # Internal purpose, recommended
+actionsfile default   # Main actions file
+actionsfile user      # User customizations
 
 
-# the cookiefile contains patterns to specify the cookie management policy
-#
-cookiefile     ./cookiefile
+#  1.5. filterfile
+#  ===============
+#  
+#  Specifies:
+#     
+#      The filter file to use
+#     
+#  Type of value:
+#     
+#      File name, relative to confdir
+#     
+#  Default value:
+#     
+#      default.filter (Unix) or default.filter.txt (Windows)
+#    
+#  Effect if unset:
+#     
+#      No textual content filtering takes place, i.e. all +filter{name}
+#      actions in the actions file are turned off
+#     
+#  Notes:
+#     
+#      The "default.filter" file contains content modification rules
+#      that use "regular expressions". These rules permit powerful
+#      changes on the content of Web pages, e.g., you could disable your
+#      favorite JavaScript annoyances, re-write the actual displayed
+#      text, or just have some fun replacing "Microsoft" with
+#      "MicroSuck" wherever it appears on a Web page.
+# 
+filterfile default.filter
 
-# the logfile is where all logging and error messages are written
-#
-logfile        ./junkbuster.log
 
-# the jarfile is where cookies can be stored
-#
-#jarfile    ./jarfile
+#  1.6. logfile
+#  ============
+#  
+#  Specifies:
+#     
+#      The log file to use
+#     
+#  Type of value:
+#     
+#      File name, relative to logdir
+#     
+#  Default value:
+#     
+#      logfile (Unix) or privoxy.log (Windows)
+#     
+#  Effect if unset:
+#     
+#      No log file is used, all log messages go to the console
+#      (stderr).
+#     
+#  Notes:
+#     
+#      The windows version will additionally log to the console.
+#     
+#      The logfile is where all logging and error messages are written.
+#      The level of detail and number of messages are set with the debug
+#      option (see below). The logfile can be useful for tracking down a
+#      problem with Privoxy (e.g., it's not blocking an ad you think it
+#      should block) but in most cases you probably will never look at
+#      it.
+#     
+#      Your logfile will grow indefinitely, and you will probably want
+#      to periodically remove it. On Unix systems, you can do this with
+#      a cron job (see "man cron"). For Red Hat, a logrotate script has
+#      been included.
+#    
+#      On SuSE Linux systems, you can place a line like
+#      "/var/log/privoxy.* +1024k 644 nobody.nogroup" in /etc/logfiles,
+#      with the effect that cron.daily will automatically archive, gzip,
+#      and empty the log, when it exceeds 1M size.
+#    
+#      Any log files must be writable by whatever user Privoxy is being 
+#      run as (default on UNIX, user id is "privoxy").
+# 
+logfile logfile
 
-# the forwardfile defines domain-specific routing
-#
-#forwardfile    ./forward
 
-# file which lists and into which trusted domains are written
-#
-#trustfile     ./trust
-# files specify locations of "for information about trusted referers, see.."
-# multiple trust_info_url lines are OK
-#
-# trust_info_url     http://internet.junkbuster.com/
-# trust_info_url     http://www.yoursite.com/our_trust_policy.html
-#
+#  1.7. jarfile
+#  ============
+#  
+#  Specifies:
+#     
+#      The file to store intercepted cookies in
+#     
+#  Type of value:
+#     
+#      File name, relative to logdir
+#     
+#  Default value:
+#     
+#      jarfile (Unix) or privoxy.jar (Windows)
+#     
+#  Effect if unset:
+#     
+#      Intercepted cookies are not stored at all.
+#     
+#  Notes:
+#     
+#      The jarfile may grow to ridiculous sizes over time.
+# 
+jarfile jarfile
 
-# The access control list file can be used to restrict IP addresses
-# that are permitted to use the proxy (see warnings in the FAQ).
-#
-#aclfile ./aclfile
 
-# add an "X-Forwarded-For:" specification to each request header
-#
-#add-forwarded-header
+#  1.8. trustfile
+#  ==============
+#  
+#  Specifies:
+#     
+#      The trust file to use
+#     
+#  Type of value:
+#     
+#      File name, relative to confdir
+#     
+#  Default value:
+#     
+#      Unset (commented out). When activated: trust (Unix) or trust.txt
+#      (Windows)
+#     
+#  Effect if unset:
+#    
+#      The whole trust mechanism is turned off.
+#     
+#  Notes:
+#     
+#      The trust mechanism is an experimental feature for building
+#      white-lists and should be used with care. It is NOT recommended
+#      for the casual user.
+#     
+#      If you specify a trust file, Privoxy will only allow access to
+#      sites that are named in the trustfile. You can also mark sites as
+#      trusted referrers (with +), with the effect that access to
+#      untrusted sites will be granted, if a link from a trusted
+#      referrer was used. The link target will then be added to the
+#      "trustfile". Possible applications include limiting Internet
+#      access for children.
+#     
+#      If you use + operator in the trust file, it may grow considerably
+#      over time.
+#  
+#trustfile trust
 
-# if logging cookies into a jarfile, and no other wafers were
-# explicity set, then by default a vanilla wafer is sent with
-# each request.
-#
-# setting 'suppress-vanilla-wafer' stops this vanilla wafer from
-# being sent.
-#
-suppress-vanilla-wafer
 
-# add these wafers to each request header
-# multiple wafer lines are OK
+#  2. LOCAL SET-UP DOCUMENTATION
+#  =============================
+#  
+#  If you intend to operate Privoxy for more users that just yourself,
+#  it might be a good idea to let them know how to reach you, what you
+#  block and why you do that, your policies etc.
+#  
 #
-#wafer    NOTE=Like most people, I want my browsing to be anonymous.
-#wafer    WARNING=Please do not attempt to track me.
+#  2.1. trust-info-url
+#  ===================
+#  
+#  Specifies:
+#     
+#      A URL to be displayed in the error page that users will see if
+#      access to an untrusted page is denied.
+#     
+#  Type of value:
+#     
+#      URL
+#     
+#  Default value:
+#     
+#      Two example URL are provided
+#     
+#  Effect if unset:
+#     
+#      No links are displayed on the "untrusted" error page.
+#     
+#  Notes:
+#    
+#      The value of this option only matters if the experimental trust
+#      mechanism has been activated. (See trustfile above.)
+#     
+#      If you use the trust mechanism, it is a good idea to write up
+#      some on-line documentation about your trust policy and to specify
+#      the URL(s) here. Use multiple times for multiple URLs.
+#     
+#      The URL(s) should be added to the trustfile as well, so users
+#      don't end up locked out from the information on why they were
+#      locked out in the first place!
+#    
+trust-info-url http://www.example.com/why_we_block.html
+trust-info-url http://www.example.com/what_we_allow.html
 
-# Anything can be added to the request headers. Please don't litter.
-# multiple add-header lines are OK
+
+#  2.2. admin-address
+#  ==================
+#  
+#  Specifies:
+#     
+#      An email address to reach the proxy administrator.
+#     
+#  Type of value:
+#     
+#      Email address
+#     
+#  Default value:
+#     
+#      Unset
+#     
+#  Effect if unset:
+#     
+#      No email address is displayed on error pages and the CGI user
+#      interface.
+#     
+#  Notes:
+#     
+#      Highly recommended for multi-user installations.
+#
+#      If both admin-address and proxy-info-url are unset, the whole
+#      "Local Privoxy Support" box on all generated pages will not be
+#      shown.
 #
-#add-header     Forwarded: by http://stay-out-of-my-backyard.net
-#add-header    Forwarded: by http://pro-privacy-isp.net
-#add-header    Proxy-Connection: Keep-Alive
+#admin-address privoxy-admin@example.com
 
-# listen-address specifies where the Junkbuster will listen for connections
-# Specifying a port is optional; if unspecified the defaults is 8000.
-# Before Version 2.0.2 the default was to bind to all IP addresses (INADDR_ANY)
-# This has been restricted to localhost to avoid unintended security breaches.
-# To open the proxy to all, uncomment the following line:
-#listen-address      :8000
-# other example usage:
-#listen-address      124.207.250.245:8080
-# to explicitly state what is now the default:
-#listen-address      localhost
-# or equivalently:
-listen-address    127.0.0.1:8000
 
-# user-agent specifies treatment of the "User-Agent:" (and "UA-*:") header(s)
-# default: Forge the "User-Agent:" 
-# 'text' : Always send <text> as the "User-Agent:"
-# .      : Pass the "User-Agent:" unchanged
-# @      : Pass the "User-Agent:" if the server is in the cookie file,
-#          forge the "User-Agent:" otherwise
-#user-agent     @
+#  2.3. proxy-info-url
+#  ===================
+#  
+#  Specifies:
+#     
+#      A URL to documentation about the local Privoxy setup,
+#      configuration or policies.
+#     
+#  Type of value:
+#     
+#      URL
+#     
+#  Default value:
+#     
+#      Unset
+#     
+#  Effect if unset:
+#     
+#      No link to local documentation is displayed on error pages and
+#      the CGI user interface.
+#     
+#  Notes:
+#     
+#      If both admin-address and proxy-info-url are unset, the whole
+#      "Local Privoxy Support" box on all generated pages will not be
+#      shown.
+#     
+#      This URL shouldn't be blocked ;-)
+#  
+#proxy-info-url http://www.example.com/proxy-service.html
 
-# note: Russian browsers may be confused if user agent misidentifies
-# the operating system (Mac vs Windows); see FAQ
-user-agent    .
 
-# referer specifies treatment of the "Referer:" header
-# New option by "Andreas S. Oesterhelt" <oes@paradis.rhein.de>
-#
-# default: Kill the referrer-header from the client
-# 'text' : Always send <text> as the referrer
-# .      : Pass the referrer unchanged
-# @      : Pass the referrer if the server is in the cookie file,
-#          kill the referrer otherwise
-# Â§      : Pass the referrer if the server is in the cookie file,
-#       send a forged referrer that points to the root-diretory URL
-#       of the current request otherwise
-referer     Â§
+#  3. DEBUGGING
+#  ============
+#  
+#  These options are mainly useful when tracing a problem. Note that you
+#  might also want to invoke Privoxy with the --no-daemon command line
+#  option when debugging.
+# 
+# 
+#  3.1. debug
+#  ==========
+#  
+#  Specifies:
+#     
+#      Key values that determine what information gets logged.
+#     
+#  Type of value:
+#     
+#      Integer values
+#     
+#  Default value:
+#     
+#      12289 (i.e.: URLs plus warnings and errors)
+#     
+#  Effect if unset:
+#     
+#      Nothing gets logged.
+#     
+#  Notes:
+#     
+#      The available debug levels are:
+#     
+#        debug         1 # show each GET/POST/CONNECT request             
+#        debug         2 # show each connection status                    
+#        debug         4 # show I/O status                                
+#        debug         8 # show header parsing                            
+#        debug        16 # log all data into the logfile                  
+#        debug        32 # debug force feature                            
+#        debug        64 # debug regular expression filter                
+#        debug       128 # debug fast redirects                           
+#        debug       256 # debug GIF de-animation                         
+#        debug       512 # Common Log Format                              
+#        debug      1024 # debug kill pop-ups                             
+#        debug      4096 # Startup banner and warnings               
+#        debug      8192 # Non-fatal errors                               
+#                                                                         
+#     
+#      To select multiple debug levels, you can either add them or use
+#      multiple debug lines.
+#    
+#      A debug level of 1 is informative because it will show you each
+#      request as it happens. 1, 4096 and 8192 are highly recommended so
+#      that you will notice when things go wrong. The other levels are
+#      probably only of interest if you are hunting down a specific
+#      problem. They can produce a hell of an output (especially 16).
+#     
+#      The reporting of fatal errors (i.e. ones which crash Privoxy) is
+#      always on and cannot be disabled.
+#     
+#      If you want to use CLF (Common Log Format), you should set "debug
+#      512" ONLY and not enable anything else.
+#  
+debug   1    # show each GET/POST/CONNECT request
+debug   4096 # Startup banner and warnings
+debug   8192 # Errors - *we highly recommended enabling this*
 
-# from specifies value to be subsituted if browser provides a "From:" header
-#
-#from        spam-me-senseless@sittingduck.net
 
-# tinygif allows you to change the appearance of blocked images
-#
-# tinygif      0  # Show a "broken icon"
-# tinygif      1  # Show a GIF of one transparent pixel
-# tinygif      2  # Show a GIF with the word "JUNKBUSTER"
-tinygif     2
-# tinygif  3 http://localhost/1x1.gif   # Temporary redirect to this URL
+#  3.2. single-threaded
+#  ====================
+#  
+#  Specifies:
+#     
+#      Whether to run only one server thread
+#     
+#  Type of value:
+#     
+#      None
+#     
+#  Default value:
+#    
+#      Unset
+#    
+#  Effect if unset:
+#     
+#      Multi-threaded (or, where unavailable: forked) operation, i.e.
+#      the ability to serve multiple requests simultaneously.
+#     
+#  Notes:
+#     
+#      This option is only there for debug purposes and you should never
+#      need to use it. It will drastically reduce performance.
+#    
+#single-threaded
 
-# Andrew <anw@tirana.freewire.co.uk> added
-# The following can be used to suppress display of the block lists when the
-# page http://x.x/show-proxy-args is displayed. With a long block list this
-# accelerates loading of the configuration page and also hides the contents of
-# the block lists (for whatever reason). Maintainers of junkbuster proxies for 
-# multiple use can specify a message for any use who wants to know what is in
-# these files.
-#
-#suppress-blocklists Contact sysadmin@example.com for details.
-# suppress-blocklists
 
-# debug sets the level of debugging information to log in the logfile
-#
-# debug         1 # GPC  = show each GET/POST/CONNECT request
-# debug         2 # CONN = show each connection status
-# debug         4 # IO   = show I/O status
-# debug         8 # HDR  = show header parsing
-# debug        16 # LOG  = log all data into the logfile
-# debug        32 # FRC  = debug force feature
-# debug        64 # REF  = debug regular expression filter 
-#
-# multiple "debug" directives, are OK - they're logical-OR'd together
-#
-#debug         15 # same as setting the first 4 listed above
-debug 1
-#debug 255
-
-# single-threaded operation (i.e. disallows multiple threads or processes)
-# This is most often used for debugging because it keeps the
-# debugging output "in order" for easy reading.
-#
-#single-threaded
+#  4. ACCESS CONTROL AND SECURITY
+#  ==============================
+#  
+#  This section of the config file controls the security-relevant
+#  aspects of Privoxy's configuration.
+# 
+# 
+#  4.1. listen-address
+#  ===================
+#  
+#  Specifies:
+#     
+#      The IP address and TCP port on which Privoxy will listen for
+#      client requests.
+#     
+#  Type of value:
+#     
+#      [IP-Address]:Port
+#     
+#  Default value:
+#     
+#      127.0.0.1:8118
+#     
+#  Effect if unset:
+#     
+#      Bind to 127.0.0.1 (localhost), port 8118. This is suitable and
+#      recommended for home users who run Privoxy on the same machine as
+#      their browser.
+#    
+#  Notes:
+#     
+#      You will need to configure your browser(s) to this proxy address
+#      and port.
+#     
+#      If you already have another service running on port 8118, or if
+#      you want to serve requests from other machines (e.g. on your
+#      local network) as well, you will need to override the default.
+#     
+#      If you leave out the IP address, Privoxy will bind to all
+#      interfaces (addresses) on your machine and may become reachable
+#      from the Internet. In that case, consider using access control
+#      lists (acl's) (see "ACLs" below), or a firewall.
+#     
+#  Example:
+#     
+#      Suppose you are running Privoxy on a machine which has the
+#      address 192.168.0.1 on your local private network (192.168.0.0)
+#      and has another outside connection with a different address. You
+#      want it to serve requests from inside only:
+#     
+#        listen-address  192.168.0.1:8118                                 
+#                                                                        
+listen-address 127.0.0.1:8118
 
-# Toggle flag.  0 => disabled, anything else (ie. 1) => enabled
+#  4.2. toggle
+#  ===========
+#  
+#  Specifies:
+#     
+#      Initial state of "toggle" status
+#     
+#  Type of value:
+#     
+#      1 or 0
+#     
+#  Default value:
+#     
+#      1
+#     
+#  Effect if unset:
+#     
+#      Act as if toggled on
+#     
+#  Notes:
+#    
+#      If set to 0, Privoxy will start in "toggled off" mode, i.e.
+#      behave like a normal, content-neutral proxy. See
+#      enable-remote-toggle below. This is not really useful anymore,
+#      since toggling is much easier via the web interface then via
+#      editing the conf file.
+#     
+#      The windows version will only display the toggle icon in the
+#      system tray if this option is present.
+#    
+# 
 toggle 1
 
 
-# Win32 GUI specific options.  Moved here from ijbw32.ini
-# in hopes of keep all of our config settings together.
+#  4.3. enable-remote-toggle
+#  =========================
+#  
+#  Specifies:
+#     
+#      Whether or not the web-based toggle feature may be used
+#     
+#  Type of value:
+#     
+#      0 or 1
+#     
+#  Default value:
+#     
+#      1
+#     
+#  Effect if unset:
+#     
+#      The web-based toggle feature is disabled.
+#     
+#  Notes:
+#     
+#      When toggled off, Privoxy acts like a normal, content-neutral
+#      proxy, i.e. it acts as if none of the actions applied to any
+#      URL.
+#     
+#      For the time being, access to the toggle feature can not be
+#      controlled separately by "ACLs" or HTTP authentication, so that
+#      everybody who can access Privoxy (see "ACLs" and listen-address
+#      above) can toggle it for all users. So this option is not
+#      recommended for multi-user environments with untrusted users.
+#     
+#      Note that you must have compiled Privoxy with support for this
+#      feature, otherwise this option has no effect.
+#    
+enable-remote-toggle 1
+
+
+#  4.4. enable-edit-actions
+#  ========================
+#  
+#  Specifies:
+#     
+#      Whether or not the web-based actions file editor may be used
+#     
+#  Type of value:
+#     
+#      0 or 1
+#     
+#  Default value:
+#     
+#      1
+#     
+#  Effect if unset:
+#     
+#      The web-based actions file editor is disabled.
+#     
+#  Notes:
+#     
+#      For the time being, access to the editor can not be controlled
+#      separately by "ACLs" or HTTP authentication, so that everybody
+#      who can access Privoxy (see "ACLs" and listen-address above) can
+#      modify its configuration for all users. So this option is not
+#      recommended for multi-user environments with untrusted users.
+#     
+#      Note that you must have compiled Privoxy with support for this
+#      feature, otherwise this option has no effect.
+#    
+enable-edit-actions 1
+
+
+#  4.5. ACLs: permit-access and deny-access
+#  ========================================
+#  
+#  Specifies:
+#     
+#      Who can access what.
+#     
+#  Type of value:
+#     
+#      src_addr[/src_masklen] [dst_addr[/dst_masklen]]
+#     
+#      Where src_addr and dst_addr are IP addresses in dotted decimal
+#      notation or valid DNS names, and src_masklen and dst_masklen are
+#      subnet masks in CIDR notation, i.e. integer values from 2 to 32
+#      representing the length (in bits) of the network address. The
+#      masks and the whole destination part are optional.
+#    
+#  Default value:
+#     
+#      Unset
+#     
+#  Effect if unset:
+#     
+#      Don't restrict access further than implied by listen-address
+#     
+#  Notes:
+#     
+#      Access controls are included at the request of ISPs and systems
+#      administrators, and are not usually needed by individual users.
+#      For a typical home user, it will normally suffice to ensure that
+#      Privoxy only listens on the localhost or internal (home) network
+#      address by means of the listen-address option.
+#     
+#      Please see the warnings in the FAQ that this proxy is not
+#      intended to be a substitute for a firewall or to encourage anyone
+#      to defer addressing basic security weaknesses.
+#     
+#      Multiple ACL lines are OK. If any ACLs are specified, then the
+#      Privoxy talks only to IP addresses that match at least one
+#      permit-access line and don't match any subsequent deny-access
+#      line. In other words, the last match wins, with the default being
+#      deny-access.
+#     
+#      If Privoxy is using a forwarder (see forward below) for a
+#      particular destination URL, the dst_addr that is examined is the
+#      address of the forwarder and NOT the address of the ultimate
+#      target. This is necessary because it may be impossible for the
+#      local Privoxy to determine the IP address of the ultimate target
+#      (that's often what gateways are used for).
+#     
+#      You should prefer using IP addresses over DNS names, because the
+#      address lookups take time. All DNS names must resolve! You can
+#      not use domain patterns like "*.org" or partial domain names. If
+#      a DNS name resolves to multiple IP addresses, only the first one
+#      is used.
+#     
+#      Denying access to particular sites by ACL may have undesired side
+#      effects if the site in question is hosted on a machine which also
+#      hosts other sites.
+#     
+#  Examples:
+#     
+#      Explicitly define the default behavior if no ACL and
+#      listen-address are set: "localhost" is OK. The absence of a
+#      dst_addr implies that all destination addresses are OK:
+#     
+#        permit-access  localhost                                         
+#                                                                        
+#    
+#      Allow any host on the same class C subnet as www.privoxy.org
+#      access to nothing but www.example.com:
+#     
+#        permit-access  www.privoxy.org/24 www.example.com/32             
+#                                                                         
+#     
+#      Allow access from any host on the 26-bit subnet 192.168.45.64 to
+#      anywhere, with the exception that 192.168.45.73 may not access
+#      www.dirty-stuff.example.com:
+#     
+#        permit-access  192.168.45.64/26                                  
+#        deny-access    192.168.45.73    www.dirty-stuff.example.com      
+#                                                                        
+
 
-activity-animation      1
-log-messages            1
-log-highlight-messages  1
-log-buffer-size         1
-log-max-lines           200
-log-font-name           Comic Sans MS
-log-font-size           8
-show-on-task-bar        0
-close-button-minimizes  1
+#  4.6. buffer-limit
+#  =================
+#  
+#  Specifies:
+#     
+#      Maximum size of the buffer for content filtering.
+#     
+#  Type of value:
+#     
+#      Size in Kbytes
+#     
+#  Default value:
+#     
+#      4096
+#     
+#  Effect if unset:
+#     
+#      Use a 4MB (4096 KB) limit.
+#     
+#  Notes:
+#     
+#      For content filtering, i.e. the +filter and +deanimate-gif
+#      actions, it is necessary that Privoxy buffers the entire document
+#      body. This can be potentially dangerous, since a server could
+#      just keep sending data indefinitely and wait for your RAM to
+#      exhaust -- with nasty consequences. Hence this option.
+#     
+#      When a document buffer size reaches the buffer-limit, it is
+#      flushed to the client unfiltered and no further attempt to filter
+#      the rest of the document is made. Remember that there may be
+#      multiple threads running, which might require up to buffer-limit
+#      Kbytes each, unless you have enabled "single-threaded" above.
+#    
+buffer-limit 4096
 
-# hide-console is used only on Win32 console mode. It instructs
-# the Internet Junkbuster to disconnect from and hide the
-# command console.
+
+#  5. FORWARDING
+#  =============
+#  
+#  This feature allows routing of HTTP requests through a chain of
+#  multiple proxies. It can be used to better protect privacy and
+#  confidentiality when accessing specific domains by routing requests
+#  to those domains through an anonymous public proxy (see e.g.
+#  http://www.multiproxy.org/anon_list.htm) Or to use a caching proxy to
+#  speed up browsing. Or chaining to a parent proxy may be necessary
+#  because the machine that Privoxy runs on has no direct Internet
+#  access.
+#  
+#  Also specified here are SOCKS proxies. Privoxy supports the SOCKS 4
+#  and SOCKS 4A protocols.
+# 
+
+
+#  5.1. forward
+#  ============
 #
-#hide-console
+#  Specifies:
+#     
+#      To which parent HTTP proxy specific requests should be routed.
+#     
+#  Type of value:
+#     
+#      target_domain[:port] http_parent[:port]
+#     
+#      Where target_domain is a domain name pattern (see the chapter on
+#      domain matching in the actions file), http_parent is the address
+#      of the parent HTTP proxy as an IP addresses in dotted decimal
+#      notation or as a valid DNS name (or "." to denote "no
+#      forwarding", and the optional port parameters are TCP ports, i.e.
+#      integer values from 1 to 64535
+#     
+#  Default value:
+#     
+#      Unset
+#     
+#  Effect if unset:
+#     
+#      Don't use parent HTTP proxies.
+#     
+#  Notes:
+#     
+#      If http_parent is ".", then requests are not forwarded to another
+#      HTTP proxy but are made directly to the web servers.
+#     
+#      Multiple lines are OK, they are checked in sequence, and the last
+#      match wins.
+#     
+#  Examples:
+#    
+#      Everything goes to an example anonymizing proxy, except SSL on
+#      port 443 (which it doesn't handle):
+#     
+#        forward   .*     anon-proxy.example.org:8080                     
+#        forward   :443   .                                               
+#                                                                         
+#     
+#      Everything goes to our example ISP's caching proxy, except for
+#      requests to that ISP's sites:
+#     
+#        forward   .*.                caching-proxy.example-isp.net:8000  
+#        forward   .example-isp.net   .                                   
+#                                                                         
+
+
+#  5.2. forward-socks4 and forward-socks4a
+#  =======================================
+#
+#  Specifies:
+#     
+#      Through which SOCKS proxy (and to which parent HTTP proxy)
+#      specific requests should be routed.
+#     
+#  Type of value:
+#     
+#      target_domain[:port] socks_proxy[:port] http_parent[:port]
+#     
+#      Where target_domain is a domain name pattern (see the chapter on
+#      domain matching in the actions file), http_parent and socks_proxy
+#      are IP addresses in dotted decimal notation or valid DNS names
+#      (http_parent may be "." to denote "no HTTP forwarding"), and the
+#      optional port parameters are TCP ports, i.e. integer values from
+#      1 to 64535
+#     
+#  Default value:
+#     
+#      Unset
+#     
+#  Effect if unset:
+#     
+#      Don't use SOCKS proxies.
+#     
+#  Notes:
+#     
+#      Multiple lines are OK, they are checked in sequence, and the last
+#      match wins.
+#     
+#      The difference between forward-socks4 and forward-socks4a is that
+#      in the SOCKS 4A protocol, the DNS resolution of the target
+#      hostname happens on the SOCKS server, while in SOCKS 4 it happens
+#      locally.
+#    
+#      If http_parent is ".", then requests are not forwarded to another
+#      HTTP proxy but are made (HTTP-wise) directly to the web servers,
+#      albeit through a SOCKS proxy.
+#     
+#  Examples:
+#     
+#      From the company example.com, direct connections are made to all
+#      "internal" domains, but everything outbound goes through their
+#      ISP's proxy by way of example.com's corporate SOCKS 4A gateway to
+#      the Internet.
+#     
+#        forward-socks4a   .*.           socks-gw.example.com:1080  www-cache.example-isp.net:8080 
+#        forward           .example.com   .
+#                                                                                                  
+#    
+#      A rule that uses a SOCKS 4 gateway for all destinations but no
+#      HTTP parent looks like this:
+#     
+#        forward-socks4   .*.            socks-gw.example.com:1080  .     
+#                                                                         
+#      See the user manual for more advanced examples.
+#    
+
+
+#  6. WINDOWS GUI OPTIONS
+#  ======================
+#  
+#  Privoxy has a number of options specific to the Windows GUI
+#  interface:
+#  
+#  If "activity-animation" is set to 1, the Privoxy icon will animate
+#  when "Privoxy" is active. To turn off, set to 0.
+# 
+#activity-animation 1
 
+#  If "log-messages" is set to 1, Privoxy will log messages to the
+#  console window:
+# 
+#log-messages 1
+   
+#  If "log-buffer-size" is set to 1, the size of the log buffer, i.e.
+#  the amount of memory used for the log messages displayed in the
+#  console window, will be limited to "log-max-lines" (see below).
+#  
+#  Warning: Setting this to 0 will result in the buffer to grow
+#  infinitely and eat up all your memory!
+# 
+#log-buffer-size 1
 
+#  log-max-lines is the maximum number of lines held in the log buffer.
+#  See above.
+# 
+#log-max-lines 200
+
+#  If "log-highlight-messages" is set to 1, Privoxy will highlight
+#  portions of the log messages with a bold-faced font:
+# 
+#log-highlight-messages 1
+#    
+#  The font used in the console window:
+# 
+#log-font-name Comic Sans MS
+#    
+#  Font size used in the console window:
+# 
+#log-font-size 8
+#    
+#  "show-on-task-bar" controls whether or not Privoxy will appear as a
+#  button on the Task bar when minimized:
+# 
+#show-on-task-bar 0
+#    
+#  If "close-button-minimizes" is set to 1, the Windows close button
+#  will minimize Privoxy instead of closing the program (close with the
+#  exit option on the File menu).
+# 
+#close-button-minimizes 1
+#    
+#  The "hide-console" option is specific to the MS-Win console version
+#  of Privoxy. If this option is used, Privoxy will disconnect from and
+#  hide the command console.
+# 
+#hide-console
+#
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..cd430f6
--- /dev/null
@@ -0,0 +1,1314 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-08-21'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+       for c in cc gcc c89 ; do
+         ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+         if test $? = 0 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       rm -f $dummy.c $dummy.o $dummy.rel ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # Netbsd (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       # Determine the machine/vendor (is the vendor relevant).
+       case "${UNAME_MACHINE}" in
+           amiga) machine=m68k-unknown ;;
+           arm32) machine=arm-unknown ;;
+           atari*) machine=m68k-atari ;;
+           sun3*) machine=m68k-sun ;;
+           mac68k) machine=m68k-apple ;;
+           macppc) machine=powerpc-apple ;;
+           hp3[0-9][05]) machine=m68k-hp ;;
+           ibmrt|romp-ibm) machine=romp-ibm ;;
+           *) machine=${UNAME_MACHINE}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE}" in
+           i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >$dummy.s
+       .data
+\$Lformat:
+       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+       .text
+       .globl main
+       .align 4
+       .ent main
+main:
+       .frame \$30,16,\$26,0
+       ldgp \$29,0(\$27)
+       .prologue 1
+       .long 0x47e03d80 # implver \$0
+       lda \$2,-1
+       .long 0x47e20c21 # amask \$2,\$1
+       lda \$16,\$Lformat
+       mov \$0,\$17
+       not \$1,\$18
+       jsr \$26,printf
+       ldgp \$29,0(\$26)
+       mov 0,\$16
+       jsr \$26,exit
+       .end main
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               case `./$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+                       2-1307)
+                               UNAME_MACHINE="alphaev68"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:NetBSD:*)
+       echo `uname -p`-unknown-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy \
+         && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               eval $set_cc_for_build
+               $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+               rm -f $dummy.c $dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+              case "${HPUX_REV}" in
+                11.[0-9][0-9])
+                  if [ -x /usr/bin/getconf ]; then
+                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                        esac ;;
+                    esac
+                  fi ;;
+              esac
+              if [ "${HP_ARCH}" = "" ]; then
+              sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+       eval $set_cc_for_build
+       (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+       if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+       rm -f $dummy.c $dummy
+       fi ;;
+       esac
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    hppa*:OpenBSD:*:*)
+       echo hppa-unknown-openbsd
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3D:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+         big)    echo mips-unknown-linux-gnu && exit 0 ;;
+         little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+       esac
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       ld_supported_targets=`cd /; ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;               
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-pc-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       echo `uname -p`-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       if test "${UNAME_MACHINE}" = "x86pc"; then
+               UNAME_MACHINE=pc
+       fi
+       echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-[KW]:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+eval $set_cc_for_build
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h b/config.h
deleted file mode 100644 (file)
index 4d71f86..0000000
--- a/config.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* config.h.  Generated automatically by configure.  */
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
-#ifndef _CONFIG_H
-#define _CONFIG_H
-/*********************************************************************
- *
- * File        :  $Source: /home/administrator/cvs/ijb/acconfig.h,v $
- *
- * Purpose     :  This file should be the first thing included in every
- *                .c file.  (Before even system headers).  It contains 
- *                #define statements for various features.  It was
- *                introduced because the compile command line started
- *                getting ludicrously long with feature defines.
- *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
- *
- *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
- *                Junkbusters Corporation.  http://www.junkbusters.com
- *
- *                This program is free software; you can redistribute it 
- *                and/or modify it under the terms of the GNU General
- *                Public License as published by the Free Software
- *                Foundation; either version 2 of the License, or (at
- *                your option) any later version.
- *
- *                This program is distributed in the hope that it will
- *                be useful, but WITHOUT ANY WARRANTY; without even the
- *                implied warranty of MERCHANTABILITY or FITNESS FOR A
- *                PARTICULAR PURPOSE.  See the GNU General Public
- *                License for more details.
- *
- *                The GNU General Public License should be included with
- *                this file.  If not, you can view it at
- *                http://www.gnu.org/copyleft/gpl.html
- *                or write to the Free Software Foundation, Inc., 59
- *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Revisions   :
- *    $Log: acconfig.h,v $
- *
- *********************************************************************/
-\f
-
-/* Define to empty if the keyword does not work.  */
-/* #undef const */
-
-/* Define to `unsigned' if <sys/types.h> doesn't define.  */
-/* #undef size_t */
-
-/* Define if you have the ANSI C header files.  */
-#define STDC_HEADERS 1
-
-/*
- * Version number - Major (X._._)
- */
-#define VERSION_MAJOR 2
-
-/*
- * Version number - Minor (_.X._)
- */
-#define VERSION_MINOR 9
-
-/*
- * Version number - Point (_._.X)
- */
-#define VERSION_POINT 3
-
-/*
- * Version number, as a string
- */
-#define VERSION "2.9.3"
-
-/*
- * Regular expression matching for URLs.  (Highly recommended).  If this is 
- * not defined then you can ony use prefix matching.
- */
-#define REGEX 1
-
-/*
- * Allow JunkBuster to be "disabled" so it is just a normal non-blocking
- * non-anonymizing proxy.  This is useful if you're trying to access a
- * blocked or broken site - just change the setting in the config file
- * and send a SIGHUP (UN*X), or use the handy "Disable" menu option (Windows
- * GUI).
- */
-#define TOGGLE 1
-
-/*
- * Enables arbitrary content modification regexps
- */
-#define PCRS 1
-
-/*
- * If a stream is compressed via gzip (Netscape specific I think), then
- * it cannot be modified with Perl regexps.  This forces it to be 
- * uncompressed.
- */
-#define DENY_GZIP 1
-
-/*
- * Enables statistics function.
- */
-#define STATISTICS 1
-
-/*
- * Bypass filtering for 1 page only
- */
-#define FORCE_LOAD 1
-
-/*
- * Split the show-proxy-args page into a page for each config file.
- */
-#define SPLIT_PROXY_ARGS 1
-
-/*
- * Kills JavaScript popups - window.open, onunload, etc.
- */
-#define KILLPOPUPS 1
-
-/*
- * Support for webDAV - e.g. so Microsoft Outlook can access HotMail e-mail
- */
-#define WEBDAV 1
-
-/*
- * Detect image requests automatically for MSIE.  Will fall back to
- * other image-detection methods (i.e. USE_IMAGE_LIST) for other
- * browsers.
- *
- * It detects the following header pair as an image request:
- *
- * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
- * Accept: * / *
- *
- * And the following as a HTML request:
- *
- * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
- * Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, * / *
- *
- * And no, I haven't got that backwards - IE is being wierd.
- *
- * Known limitations: 
- * 1) If you press shift-reload on a blocked HTML page, you get
- *    the image "blocked" page, not the HTML "blocked" page.
- * 2) Once an image "blocked" page has been sent, viewing it 
- *    in it's own browser window *should* bring up the HTML
- *    "blocked" page, but it doesn't.  You need to clear the 
- *    browser cache to get the HTML version again.
- *
- * These limitations are due to IE making inconsistent choices
- * about which "Accept:" header to send.
- */
-#define DETECT_MSIE_IMAGES 1
-
-/*
- * Use image list to detect images.
- * If you do not define this then everything is treated as HTML.
- *
- * Whatever the setting of this value, DETECT_MSIE_IMAGES will 
- * override it for people using Internet Explorer.
- */
-#define USE_IMAGE_LIST 1
-
-/*
- * Allows the use of ACL files to control access to the proxy by IP address.
- */
-#define ACL_FILES 1
-
-/*
- * Allows the use of trust files.
- */
-#define TRUST_FILES 1
-
-/*
- * Allows the use of jar files to capture cookies.
- */
-#define JAR_FILES 1
-
-/*
- * Use PCRE rather than GNU Regex
- */
-#define PCRE 1
-
-/* Define if you have the bcopy function.  */
-#define HAVE_BCOPY 1
-
-/* Define if you have the memmove function.  */
-#define HAVE_MEMMOVE 1
-
-/* Define if you have the strerror function.  */
-#define HAVE_STRERROR 1
-
-#endif /* _CONFIG_H */
diff --git a/config.h.in b/config.h.in
deleted file mode 100644 (file)
index 930ca66..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
-#ifndef _CONFIG_H
-#define _CONFIG_H
-/*********************************************************************
- *
- * File        :  $Source: /home/administrator/cvs/ijb/acconfig.h,v $
- *
- * Purpose     :  This file should be the first thing included in every
- *                .c file.  (Before even system headers).  It contains 
- *                #define statements for various features.  It was
- *                introduced because the compile command line started
- *                getting ludicrously long with feature defines.
- *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
- *
- *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
- *                Junkbusters Corporation.  http://www.junkbusters.com
- *
- *                This program is free software; you can redistribute it 
- *                and/or modify it under the terms of the GNU General
- *                Public License as published by the Free Software
- *                Foundation; either version 2 of the License, or (at
- *                your option) any later version.
- *
- *                This program is distributed in the hope that it will
- *                be useful, but WITHOUT ANY WARRANTY; without even the
- *                implied warranty of MERCHANTABILITY or FITNESS FOR A
- *                PARTICULAR PURPOSE.  See the GNU General Public
- *                License for more details.
- *
- *                The GNU General Public License should be included with
- *                this file.  If not, you can view it at
- *                http://www.gnu.org/copyleft/gpl.html
- *                or write to the Free Software Foundation, Inc., 59
- *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Revisions   :
- *    $Log: acconfig.h,v $
- *
- *********************************************************************/
-\f
-
-/* Define to empty if the keyword does not work.  */
-#undef const
-
-/* Define to `unsigned' if <sys/types.h> doesn't define.  */
-#undef size_t
-
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
-
-/*
- * Version number - Major (X._._)
- */
-#undef VERSION_MAJOR
-
-/*
- * Version number - Minor (_.X._)
- */
-#undef VERSION_MINOR
-
-/*
- * Version number - Point (_._.X)
- */
-#undef VERSION_POINT
-
-/*
- * Version number, as a string
- */
-#undef VERSION
-
-/*
- * Regular expression matching for URLs.  (Highly recommended).  If this is 
- * not defined then you can ony use prefix matching.
- */
-#undef REGEX
-
-/*
- * Allow JunkBuster to be "disabled" so it is just a normal non-blocking
- * non-anonymizing proxy.  This is useful if you're trying to access a
- * blocked or broken site - just change the setting in the config file
- * and send a SIGHUP (UN*X), or use the handy "Disable" menu option (Windows
- * GUI).
- */
-#undef TOGGLE
-
-/*
- * Enables arbitrary content modification regexps
- */
-#undef PCRS
-
-/*
- * If a stream is compressed via gzip (Netscape specific I think), then
- * it cannot be modified with Perl regexps.  This forces it to be 
- * uncompressed.
- */
-#undef DENY_GZIP
-
-/*
- * Enables statistics function.
- */
-#undef STATISTICS
-
-/*
- * Bypass filtering for 1 page only
- */
-#undef FORCE_LOAD
-
-/*
- * Split the show-proxy-args page into a page for each config file.
- */
-#undef SPLIT_PROXY_ARGS
-
-/*
- * Kills JavaScript popups - window.open, onunload, etc.
- */
-#undef KILLPOPUPS
-
-/*
- * Support for webDAV - e.g. so Microsoft Outlook can access HotMail e-mail
- */
-#undef WEBDAV
-
-/*
- * Detect image requests automatically for MSIE.  Will fall back to
- * other image-detection methods (i.e. USE_IMAGE_LIST) for other
- * browsers.
- *
- * It detects the following header pair as an image request:
- *
- * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
- * Accept: * / *
- *
- * And the following as a HTML request:
- *
- * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
- * Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, * / *
- *
- * And no, I haven't got that backwards - IE is being wierd.
- *
- * Known limitations: 
- * 1) If you press shift-reload on a blocked HTML page, you get
- *    the image "blocked" page, not the HTML "blocked" page.
- * 2) Once an image "blocked" page has been sent, viewing it 
- *    in it's own browser window *should* bring up the HTML
- *    "blocked" page, but it doesn't.  You need to clear the 
- *    browser cache to get the HTML version again.
- *
- * These limitations are due to IE making inconsistent choices
- * about which "Accept:" header to send.
- */
-#undef DETECT_MSIE_IMAGES
-
-/*
- * Use image list to detect images.
- * If you do not define this then everything is treated as HTML.
- *
- * Whatever the setting of this value, DETECT_MSIE_IMAGES will 
- * override it for people using Internet Explorer.
- */
-#undef USE_IMAGE_LIST
-
-/*
- * Allows the use of ACL files to control access to the proxy by IP address.
- */
-#undef ACL_FILES
-
-/*
- * Allows the use of trust files.
- */
-#undef TRUST_FILES
-
-/*
- * Allows the use of jar files to capture cookies.
- */
-#undef JAR_FILES
-
-/*
- * Use PCRE rather than GNU Regex
- */
-#undef PCRE
-
-/* Define if you have the bcopy function.  */
-#undef HAVE_BCOPY
-
-/* Define if you have the memmove function.  */
-#undef HAVE_MEMMOVE
-
-/* Define if you have the strerror function.  */
-#undef HAVE_STRERROR
-
-#endif /* _CONFIG_H */
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..12ebc78
--- /dev/null
@@ -0,0 +1,1410 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-08-13'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+       | c4x | clipper \
+       | d10v | d30v | dsp16xx \
+       | fr30 \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | m32r | m68000 | m68k | m88k | mcore \
+       | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el | mips64vr4300 \
+       | mips64vr4300el | mips64vr5000 | mips64vr5000el \
+       | mipsbe | mipsel | mipsle | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | ns16k | ns32k \
+       | openrisc \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | s390 | s390x \
+       | sh | sh[34] | sh[34]eb | shbe | shle \
+       | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic80 | tron \
+       | v850 \
+       | we32k \
+       | x86 | xscale \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alphapca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armv*-* \
+       | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c54x-* \
+       | clipper-* | cray2-* | cydra-* \
+       | d10v-* | d30v-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | m32r-* \
+       | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | mcore-* \
+       | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+       | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipsel-* \
+       | mipsle-* | mipstx39-* | mipstx39el-* \
+       | none-* | np1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | s390-* | s390x-* \
+       | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
+       | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
+       | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \
+       | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+       | v850-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [cjt]90)
+               basic_machine=${basic_machine}-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i686-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=t3e-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       windows32)
+               basic_machine=i386-pc
+               os=-windows32-msvcrt
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4 | sh3eb | sh4eb)
+               basic_machine=sh-unknown
+               ;;
+       sparc | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       c4x*)
+               basic_machine=c4x-none
+               os=-coff
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto*)
+               os=-nto-qnx
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+       pdp10-*)
+               os=-tops20
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
index 492d6ed..2b697f1 100644 (file)
@@ -1,9 +1,9 @@
 dnl Process this file with autoconf to produce a configure script.
 dnl 
-dnl $Id: configure.in,v 1.2 2001/05/13 22:04:51 administrator Exp $
+dnl $Id: configure.in,v 1.67 2002/05/03 14:33:59 oes Exp $
 dnl 
-dnl Written by and Copyright (C) 2001 the SourceForge
-dnl IJBSWA team.  http://ijbswa.sourceforge.net
+dnl Written by and Copyright (C) 2001, 2002 the SourceForge
+dnl Privoxy team. http://www.privoxy.org/
 dnl
 dnl Based on the Internet Junkbuster originally written
 dnl by and Copyright (C) 1997 Anonymous Coders and 
@@ -28,230 +28,1079 @@ dnl or write to the Free Software Foundation, Inc., 59
 dnl Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 dnl 
 dnl $Log: configure.in,v $
+dnl Revision 1.67  2002/05/03 14:33:59  oes
+dnl Generate doc/soucre/ldp.dsl
+dnl
+dnl Revision 1.66  2002/05/03 00:41:56  oes
+dnl Set version to 2.9.15 to comply with new versioning scheme
+dnl
+dnl Revision 1.65  2002/04/25 19:13:57  morcego
+dnl Removed RPM release number declaration on configure.in
+dnl Changed makefile to use given value for RPM_PACKAGEV when on uploading
+dnl targets (will produce an error, explaining who to do it, if no value
+dnl if provided).
+dnl
+dnl Revision 1.64  2002/04/22 16:32:31  morcego
+dnl configure.in, *.spec: Bumping release to 2 (2.9.14-2)
+dnl -rh.spec: uid and gid are now macros
+dnl -suse.spec: Changing the header Copyright to License (Copyright is
+dnl             deprecable)
+dnl
+dnl Revision 1.63  2002/04/11 11:00:21  oes
+dnl Applied Moritz' fix for socklen_t on Solaris
+dnl
+dnl Revision 1.62  2002/04/11 10:09:20  oes
+dnl Version 2.9.14
+dnl
+dnl Revision 1.61  2002/04/10 18:14:45  morcego
+dnl - (privoxy-rh.spec only) Relisting template files on the %%files section
+dnl - (configure.in, privoxy-rh.spec) Bumped package release to 5
+dnl
+dnl Revision 1.60  2002/04/09 16:38:49  oes
+dnl Added detection of missing config.h.in
+dnl
+dnl Revision 1.59  2002/04/06 20:23:55  jongfoster
+dnl Removing unnessacery tests (C++, ranlib)
+dnl
+dnl Revision 1.58  2002/04/04 20:49:20  swa
+dnl attempt to consolidate the
+dnl different dokbook versions.
+dnl
+dnl Revision 1.57  2002/04/04 00:36:36  gliptak
+dnl always use pcre for matching
+dnl
+dnl Revision 1.56  2002/04/03 22:28:03  gliptak
+dnl Removed references to gnu_regex
+dnl
+dnl Revision 1.55  2002/04/03 03:54:38  gliptak
+dnl Checking pcre version
+dnl
+dnl Revision 1.54  2002/04/01 00:54:24  gliptak
+dnl More changes needed around regex support.
+dnl
+dnl Revision 1.53  2002/03/29 20:09:01  swa
+dnl al's patch
+dnl
+dnl Revision 1.52  2002/03/29 19:51:40  gliptak
+dnl Correcting compile problem with Debian
+dnl
+dnl Revision 1.51  2002/03/28 20:43:00  swa
+dnl set make correctly
+dnl
+dnl Revision 1.50  2002/03/27 03:03:45  hal9
+dnl Add test for man2html
+dnl
+dnl Revision 1.49  2002/03/27 02:19:52  david__schmidt
+dnl More Mac OSX support:
+dnl - Get rid of extraneous, noisy -pthread warnings
+dnl - Define unix so we get oes' unix-tagged changes
+dnl
+dnl Revision 1.48  2002/03/26 22:29:54  swa
+dnl we have a new homepage!
+dnl
+dnl Revision 1.47  2002/03/26 16:41:00  hal9
+dnl Upped RPM Release to 3 (need to build new RH packages)
+dnl
+dnl Revision 1.46  2002/03/24 18:55:06  jongfoster
+dnl Making Docbook work under Windows
+dnl
+dnl Revision 1.45  2002/03/24 14:19:55  swa
+dnl set rpm package release in configure.in. nowhere else.
+dnl
+dnl Revision 1.44  2002/03/24 13:25:43  swa
+dnl name change related issues
+dnl
+dnl Revision 1.43  2002/03/24 12:56:21  swa
+dnl name change related issues.
+dnl
+dnl Revision 1.42  2002/03/22 18:11:37  jongfoster
+dnl Bumping version number to 2.9.12
+dnl
+dnl Revision 1.41  2002/03/19 19:30:04  morcego
+dnl - Fixing stylesheet checking on configure. If it is found, no further checks
+dnl   should be done
+dnl
+dnl - configure will now check for db2html or docbook2html (should work now
+dnl   on SuSe without the docbktls package)
+dnl
+dnl Revision 1.40  2002/03/09 14:33:30  oes
+dnl Fixing the (harmless) AC_CHECK_FILE warnings
+dnl
+dnl Revision 1.39  2002/03/08 16:46:13  oes
+dnl Added --enable-no-gifs
+dnl
+dnl Revision 1.38  2002/03/08 14:13:50  morcego
+dnl Fixing configure, to remove a command not found error.
+dnl
+dnl Revision 1.37  2002/03/08 12:58:21  oes
+dnl Tiny bugfix in AC_ARG_WITH(debug)
+dnl
+dnl Revision 1.36  2002/03/06 23:50:36  morcego
+dnl Will not test for a text browser if we are not using docbook.
+dnl
+dnl Revision 1.35  2002/03/06 21:55:52  morcego
+dnl New configure option: --with-docbook=(yes|no|directory)
+dnl Preliminary new platform detection code included. Will work with the
+dnl old one for now. No use just trowing it away
+dnl
+dnl Revision 1.34  2002/03/06 20:57:00  morcego
+dnl Fixing detection of stylesheets on SuSe.
+dnl
+dnl Revision 1.33  2002/03/05 17:31:11  morcego
+dnl Search for docbook.dsl. Should solve portability problems for SuSe.
+dnl
+dnl Revision 1.32  2002/03/05 14:07:43  morcego
+dnl configure now detects rpm topdir, and change GNUmakefile acordingly
+dnl    (based on sugestion by Sarantis Paskalis)
+dnl
+dnl Revision 1.31  2002/03/05 13:43:28  morcego
+dnl Checking for text browser, so redhat-dok can work.
+dnl
+dnl Revision 1.30  2002/03/04 17:58:01  oes
+dnl Deleted _DEBUG and PID_FILE_PATH
+dnl
+dnl Revision 1.29  2002/02/28 14:20:53  oes
+dnl Fixed detection of gethost*_r functions on Solaris
+dnl
+dnl Revision 1.28  2002/02/27 15:02:38  oes
+dnl Incremented version number
+dnl
+dnl Revision 1.27  2002/01/10 12:35:18  oes
+dnl Added cross-compile defaults to the AC_CHECK_SIZEOF macros
+dnl to silence autoconf warnings. Numbers are for Intel/Linux.
+dnl Is there a better way?
+dnl
+dnl Revision 1.26  2002/01/09 14:29:49  oes
+dnl - Added AC_CHECK_FUNC tests for the availability of
+dnl   gethostbyname_r, gethostbyaddr_r, gmtime_r and
+dnl   localtime_r, as well as AC_TRY_COMPILE tests to
+dnl   determine their signatures.
+dnl
+dnl - Fixed a bug with the init of CFLAGS that was
+dnl   reported by barsnick
+dnl
+dnl Revision 1.25  2002/01/04 15:27:18  oes
+dnl Changed quoting of CODE_STATUS for use in make
+dnl
+dnl Revision 1.24  2001/12/30 14:07:31  steudten
+dnl - Add signal handling (unix)
+dnl - Add SIGHUP handler (unix)
+dnl - Add creation of pidfile (unix)
+dnl - Add action 'top' in rc file (RH)
+dnl - Add entry 'SIGNALS' to manpage
+dnl - Add exit message to logfile (unix)
+dnl
+dnl Revision 1.23  2001/12/09 20:24:42  david__schmidt
+dnl Change from "alpha" to "beta" in configure.in
+dnl
+dnl Revision 1.22  2001/12/01 11:24:01  jongfoster
+dnl Renaming Makefile.in to GNUmakefile.in so that non-GNU versions of
+dnl make break in a more obvious way.
+dnl
+dnl Revision 1.21  2001/11/30 21:35:54  jongfoster
+dnl Bumping version number to 2.9.10
+dnl
+dnl Revision 1.20  2001/10/23 21:24:09  jongfoster
+dnl Support for FEATURE_CGI_EDIT_ACTIONS
+dnl
+dnl Revision 1.19  2001/10/07 15:33:14  oes
+dnl Removed FEATURE_DENY_GZIP
+dnl Bumped up version number
+dnl
+dnl Revision 1.18  2001/09/13 13:10:24  steudten
+dnl
+dnl PreWork for Debug Interface.
+dnl Add new option "--with-debug" to enable debugging (flags aso.)
+dnl
+dnl Revision 1.17  2001/09/12 23:44:55  david__schmidt
+dnl Mac OSX (Darwin) support added.
+dnl
+dnl Revision 1.16  2001/09/12 22:55:45  joergs
+dnl AmigaOS support added.
+dnl
+dnl Revision 1.15  2001/09/12 17:28:59  david__schmidt
+dnl
+dnl OS/2 port: update autoconf'd support for the platform.
+dnl
+dnl Revision 1.14  2001/07/30 22:12:11  jongfoster
+dnl Fixing Solaris build (I hope) and tidying up #defines:
+dnl - All feature #defines are now of the form FEATURE_xxx
+dnl - Permanently turned off WIN_GUI_EDIT
+dnl - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+dnl
+dnl Revision 1.13  2001/07/29 17:09:17  jongfoster
+dnl Major changes to build system in order to fix these bugs:
+dnl - pthreads under Linux was broken - changed -lpthread to -pthread
+dnl - Compiling in MinGW32 mode under CygWin now correctly detects
+dnl   which shared libraries are available
+dnl - Solaris support (?) (Not tested under Solaris yet)
+dnl
+dnl Revision 1.12  2001/07/25 19:16:27  oes
+dnl Bumping version number to 2.9.8
+dnl
+dnl Revision 1.11  2001/07/21 18:00:07  jongfoster
+dnl Bumping version number to 2.9.7
+dnl
+dnl Revision 1.10  2001/07/18 17:25:04  oes
+dnl Fixed a typo
+dnl
+dnl Revision 1.9  2001/07/15 19:45:13  jongfoster
+dnl Added support for linking with POSIX threads library
+dnl
+dnl Revision 1.8  2001/07/15 17:54:29  jongfoster
+dnl Renaming #define STATIC to STATIC_PCRE
+dnl Adding new #define FEATURE_PTHREAD that will be used to enable
+dnl POSIX threads support.
+dnl
+dnl Revision 1.7  2001/07/13 13:58:05  oes
+dnl    Completely reorganized the selection scheme for
+dnl    pcre, pcreposix, pcrs and gnu_regex:
+dnl
+dnl    The presence of shared pcre, pcreposix or pcrs
+dnl    libraried is now autodetected. Additionally, the
+dnl    user can enforce using the built-in static variants
+dnl    by specifying --disable-dynamic-(pcre|pcrs).
+dnl    Care is taken to avoid that pcre is dyn, while pcreposix
+dnl    is static, if both are used and that pcrs is static if
+dnl    pcrs is.
+dnl
+dnl    The choice between pcre, gnu or no regex for actionsfile
+dnl    URL matching is now via
+dnl    --(enable|disable)-regex-matching[=(gnu|pcre|no)] with the
+dnl    default being pcre.
+dnl
+dnl Revision 1.6  2001/06/29 21:56:40  oes
+dnl Version -> 2.9.5
+dnl
+dnl Revision 1.5  2001/06/29 13:26:27  oes
+dnl Introduced #define CODE_STATUS
+dnl
+dnl Revision 1.4  2001/05/29 09:50:24  jongfoster
+dnl Unified blocklist/imagelist/permissionslist.
+dnl File format is still under discussion, but the internal changes
+dnl are (mostly) done.
+dnl
+dnl Also modified interceptor behaviour:
+dnl - We now intercept all URLs beginning with one of the following
+dnl   prefixes (and *only* these prefixes):
+dnl     * http://i.j.b/
+dnl     * http://ijbswa.sf.net/config/
+dnl     * http://ijbswa.sourceforge.net/config/
+dnl - New interceptors "home page" - go to http://i.j.b/ to see it.
+dnl - Internal changes so that intercepted and fast redirect pages
+dnl   are not replaced with an image.
+dnl - Interceptors now have the option to send a binary page direct
+dnl   to the client. (i.e. ijb-send-banner uses this)
+dnl - Implemented show-url-info interceptor.  (Which is why I needed
+dnl   the above interceptors changes - a typical URL is
+dnl   "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+dnl   The previous mechanism would not have intercepted that, and
+dnl   if it had been intercepted then it then it would have replaced
+dnl   it with an image.)
+dnl
+dnl Revision 1.3  2001/05/22 18:46:04  oes
+dnl
+dnl - Enabled filtering banners by size rather than URL
+dnl   by adding patterns that replace all standard banner
+dnl   sizes with the "Junkbuster" gif to the re_filterfile
+dnl
+dnl - Enabled filtering WebBugs by providing a pattern
+dnl   which kills all 1x1 images
+dnl
+dnl - Added support for PCRE_UNGREEDY behaviour to pcrs,
+dnl   which is selected by the (nonstandard and therefore
+dnl   capital) letter 'U' in the option string.
+dnl   It causes the quantifiers to be ungreedy by default.
+dnl   Appending a ? turns back to greedy (!).
+dnl
+dnl - Added a new interceptor ijb-send-banner, which
+dnl   sends back the "Junkbuster" gif. Without imagelist or
+dnl   MSIE detection support, or if tinygif = 1, or the
+dnl   URL isn't recognized as an imageurl, a lame HTML
+dnl   explanation is sent instead.
+dnl
+dnl - Added new feature, which permits blocking remote
+dnl   script redirects and firing back a local redirect
+dnl   to the browser.
+dnl   The feature is conditionally compiled, i.e. it
+dnl   can be disabled with --disable-fast-redirects,
+dnl   plus it must be activated by a "fast-redirects"
+dnl   line in the config file, has its own log level
+dnl   and of course wants to be displayed by show-proxy-args
+dnl   Note: Boy, all the #ifdefs in 1001 locations and
+dnl   all the fumbling with configure.in and acconfig.h
+dnl   were *way* more work than the feature itself :-(
+dnl
+dnl - Because a generic redirect template was needed for
+dnl   this, tinygif = 3 now uses the same.
+dnl
+dnl - Moved GIFs, and other static HTTP response templates
+dnl   to project.h
+dnl
+dnl - Some minor fixes
+dnl
+dnl - Removed some >400 CRs again (Jon, you really worked
+dnl   a lot! ;-)
+dnl
+dnl Revision 1.2  2001/05/20 01:21:20  jongfoster
+dnl Version 2.9.4 checkin.
+dnl - Merged popupfile and cookiefile, and added control over PCRS
+dnl   filtering, in new "permissionsfile".
+dnl - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+dnl   file error you now get a message box (in the Win32 GUI) rather
+dnl   than the program exiting with no explanation.
+dnl - Made killpopup use the PCRS MIME-type checking and HTTP-header
+dnl   skipping.
+dnl - Removed tabs from "config"
+dnl - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+dnl - Bumped up version number.
+dnl
+dnl Revision 1.1.1.1  2001/05/15 13:58:50  oes
+dnl Initial import of version 2.9.3 source tree
+dnl
 dnl 
+
+
+dnl =================================================================
+dnl AutoConf Initialization
+dnl =================================================================
+
+AC_REVISION($Revision: 1.67 $)
 AC_INIT(jcc.c)
-AC_CONFIG_HEADER(config.h)
+
+if test ! -f config.h.in; then
+   echo "You need to run autoheader first. "
+   echo -n "Shall I do this for you now? (y/n) "
+   read answer
+   if test $answer != "y"; then
+      exit 1
+   else
+      autoheader
+  fi
+fi  
+
+AC_CONFIG_HEADER([config.h])
+AC_CANONICAL_HOST
+
+dodk=auto
+DKPREFIX=none
+AC_ARG_WITH(docbook, dnl
+  --with-docbook=[[yes|no|directory]]  
+                           Enable docbook documentation creation 
+                          (default = yes, for gnu and linux),[dnl
+case "$with_docbook" in
+yes) dodk=yes;;
+no) dodk=no;;
+*) 
+       dodk=no
+       DKPREFIX=$withval
+       ;;
+esac
+])
+DB2HTML=false
+AC_ARG_WITH(db2html, dnl
+  --with-db2html=<path/executable>
+                          Set the location of the docbook to html converter
+                          (default = search),[dnl
+DB2HTML=$withval
+])
+
+dnl =================================================================
+dnl Application version number
+dnl =================================================================
 
 VERSION_MAJOR=2
 VERSION_MINOR=9
-VERSION_POINT=3
+VERSION_POINT=15
+CODE_STATUS="beta"
+
+dnl CODE_STATUS can be "alpha", "beta", or "stable", and will be
+dnl used for CGI output
+
+dnl =================================================================
+dnl Substitute the version numbers
+dnl =================================================================
 
 AC_SUBST(VERSION_MAJOR)
 AC_SUBST(VERSION_MINOR)
 AC_SUBST(VERSION_POINT)
+AC_SUBST(CODE_STATUS)
 
+dnl
 AC_DEFINE_UNQUOTED(VERSION_MAJOR,${VERSION_MAJOR})
 AC_DEFINE_UNQUOTED(VERSION_MINOR,${VERSION_MINOR})
 AC_DEFINE_UNQUOTED(VERSION_POINT,${VERSION_POINT})
 AC_DEFINE_UNQUOTED(VERSION,"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_POINT}")
+AC_DEFINE_UNQUOTED(CODE_STATUS,"${CODE_STATUS}")
 
-dnl Checks for programs.
-dnl AC_PROG_CXX
+dnl =================================================================
+dnl Checks for programs needed to build.
+dnl =================================================================
 AC_PROG_CC
 AC_PROG_CPP
-dnl AC_PROG_INSTALL
-dnl AC_PROG_LN_S
-dnl AC_PROG_MAKE_SET
-dnl RANLIB is for PCRE:
-dnl AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
 
-AC_MINGW32
-AC_CYGWIN
-AC_EXEEXT
-AC_OBJEXT
+AC_CHECK_PROG(GDB,gdb,yes,no)
 
-dnl Checks for libraries.
-dnl AC_CHECK_LIB(pcre, pcre_compile)
-dnl AC_CHECK_LIB(pcreposix, regcomp, pcre)
+dnl =================================================================
+dnl debug, gcc and gdb support 
+dnl =================================================================
 
-dnl Checks for header files.
-AC_HEADER_STDC
-dnl AC_HEADER_SYS_WAIT
-dnl AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/time.h unistd.h)
-dnl limits.h is for PCRE:
-dnl AC_CHECK_HEADERS(limits.h)
+AC_ARG_WITH(debug,
+        [  --with-debug            Enable debug mode],
+        [
+                if test "x$withval" != "xno" ; then
+                   if test $ac_cv_prog_cc_g = yes; then
+                     if test "$GCC" = yes; then
+                       if test "$GDB"; then
+                         CFLAGS="-ggdb"
+                       else
+                         CFLAGS="-g"
+                       fi
+                       CFLAGS="$CFLAGS -Wshadow  -Wconversion"
+                     else
+                       CFLAGS="-g"
+                     fi
+                  fi
+                fi
+        ],
+       [
+           if test "X$CFLAGS" = "X"; then # if CFLAGS are unset
+             if test "$GCC" = yes; then
+               CFLAGS="-O2"
+             else
+               CFLAGS=
+             fi
+           fi
+       ]
+)
 
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_TYPE_SIZE_T
+AC_ARG_WITH(user,
+        [  --with-user=privoxy            Set user under which privoxy run],
+        [
+                if test "x$withval" != "xyes"; then
+                    USER=$with_user;
+                  else
+                   AC_MSG_ERROR(We need a user if you give me this parameter)
+                fi
+        ],
+        [
+          USER=privoxy;
+        ]
+)
+AC_SUBST(USER)
 
-dnl Checks for library functions.
-dnl AC_TYPE_SIGNAL
-dnl AC_CHECK_FUNC(strstr)
-dnl bcopy and memmove are for PCRE
-AC_CHECK_FUNCS(strerror bcopy memmove)
+AC_ARG_WITH(group,
+        [  --with-group=privoxy         Set group for privoxy],
+        [
+                if test "x$withval" != "xyes"; then
+                    GROUP=$with_group;
+                  else
+                   AC_MSG_ERROR(We need a group if you give me this parameter)
+                fi
+        ],
+        [
+          GROUP=privoxy;
+        ]
+)
+AC_SUBST(GROUP)
+dnl =================================================================
+dnl additional gcc flags
+dnl =================================================================
+dnl 
+if test "$GCC"; then
+  CFLAGS="-pipe $CFLAGS"
+fi
 
+
+dnl =================================================================
 dnl Build type
+dnl =================================================================
+dnl
+dnl Must do this first.
+dnl
+dnl Reason: This sets CFLAGS in order to switch the Cygwin compiler
+dnl into Cygwin or MinGW32 modes.  Depending on the mode selected,
+dnl the compiler will use completely different sets of library
+dnl and include files.
+dnl 
+dnl =================================================================
+
+AC_MINGW32
+AC_CYGWIN
+
+if test "$MINGW32" = "yes"; then
+  target_type=mingw
+else
+  if test "$CYGWIN" = "yes"; then
+    target_type=cygwin
+  else
+    target_type=unix
+  fi
+fi
+
+if test $dodk = auto; then
+       dodk=no
+       if test $target_type = unix; then
+               case "$host_os" in
+               linux* | gnu*)
+                       dodk=yes
+               ;;
+               esac
+       fi
+fi
+
+dnl Decide what to do based on target_type
+dnl Note: PTHREAD_LIB is always set, even if pthread is disabled.
+dnl This is because we don't know yet whether pthread is enabled.
 
 AC_ARG_ENABLE(mingw32,
 [  --enable-mingw32        Use mingw32 for a Windows GUI],
 [if test $enableval = yes; then
-    WIN_ONLY=
-    CYGWIN_FLAGS="-mwindows -mno-cygwin"
-    echo "Using mingw32 (Win32 GUI)"
-  else
-    WIN_ONLY=#
-    if test "$CYGWIN" = "yes"; then
-      CYGWIN_FLAGS="-mno-win32"
-      echo "Using Cygnus (Win32 command line)"
-    else
-      CYGWIN_FLAGS=
-    fi
-  fi],
-[if test "$MINGW32" = "yes"; then
-    WIN_ONLY=
-    CYGWIN_FLAGS="-mwindows -mno-cygwin"
-    echo "Using mingw32 (Win32 GUI)"
-  else
-    WIN_ONLY=#
-    if test "$CYGWIN" = "yes"; then
-      CYGWIN_FLAGS="-mno-win32"
-      echo "Using Cygnus (Win32 command line)"
-    else
-      CYGWIN_FLAGS=
-    fi
-  fi])
+  target_type=mingw
+fi])
 
+if test $target_type = mingw; then
+  WIN_ONLY=
+  SPECIAL_CFLAGS="-mwindows -mno-cygwin"
+  PTHREAD_LIB=-lpthreadGC
+  echo "Using mingw32 (Win32 GUI)"
+else
+  WIN_ONLY=#
+  if test $target_type = cygwin; then
+    SPECIAL_CFLAGS="-mno-win32"
+    PTHREAD_LIB=
+    echo "Using Cygnus (Win32 command line)"
+  else
+    SPECIAL_CFLAGS=
+    PTHREAD_LIB=-lpthread
+  fi
+fi
 AC_SUBST(WIN_ONLY)
-AC_SUBST(CYGWIN_FLAGS)
 
-SOLARIS_ONLY=#
-AC_SUBST(SOLARIS_ONLY)
+dnl Checking which text html browser we have avaliable
+if test $dodk != no; then
+       AC_CHECK_PROGS(WDUMP,w3m lynx links,false)
+       if test "$WDUMP" = false; then
+               AC_MSG_ERROR(You need some kind of text browser to continue \(w3m, lynx and links are supported\))
+       fi
+       if test $DB2HTML = false; then
+               dnl We need to clean the variable, otherwise AC_CHECK_PROGS
+               dnl will fail   
+               DB2HTML=""
+               AC_CHECK_PROGS(DB2HTML,db2html docbook2html,false)
+       fi
+fi
+AC_SUBST(WDUMP)
+AC_SUBST(DB2HTML)
 
-dnl Features
+dnl If we use rpm, we need to check where %_topdir is
+AC_CHECK_PROGS(RPMBIN,rpm,false)
+if test $RPMBIN != false; then
+               RPM_BASE=`rpm --eval "%{_topdir}"`
+               if test "$RPM_BASE" = ""; then
+                       RPM_BASE=/usr/src/redhat
+               fi
+fi
+AC_SUBST(RPM_BASE)
 
-dnl Regex engine:
+dnl Check for jade, so we can build the documentation
+AC_CHECK_PROGS(JADEBIN,jade openjade,false)
+AC_SUBST(JADEBIN)
 
-GNU_REGEX_ONLY=
-PCRE_REGEX_ONLY=
-NO_REGEX_ONLY=#
+dnl Check for man2html for docs.
+AC_CHECK_PROGS(MAN2HTML,man2html,false)
+AC_SUBST(MAN2HTML)
 
-AC_ARG_ENABLE(regex,
-[  --disable-regex         Don't allow regular expressions in the blockfile],
-[if test $enableval = yes; then
-  AC_DEFINE(REGEX)
-else
-  NO_REGEX_ONLY=
-  GNU_REGEX_ONLY=#
-  PCRE_REGEX_ONLY=#
-fi],AC_DEFINE(REGEX))
+dnl Checking for the docbook.dsl stylesheet file
+dnl It is still not portable (directory slash)
+JADECAT=""
+if test $dodk = yes; then
+  if test $DKPREFIX = none; then
+    for i in /usr/share/sgml/docbook/dsssl-stylesheets /usr/share/sgml/docbkdsl /usr/share/sgml/docbook-dsssl; do
+      echo -n "checking for $i/html/docbook.dsl..."
+      if test -f $i/html/docbook.dsl; then
+        echo "yes"
+        DKPREFIX=$i
+        break
+      else
+        echo "no"
+      fi
+    done
+# where are the catalogs?
+    for i in /usr/share/sgml/CATALOG.docbk30 /usr/share/sgml/CATALOG.docbk31; do
+      echo -n "checking for $i..."
+      if test -f $i; then
+        echo "yes"
+        JADECAT="$JADECAT -c $i"
+      else
+        echo "no"
+      fi
+    done
+  fi
+fi
+AC_SUBST(JADECAT)
+AC_SUBST(DKPREFIX)
 
-AC_ARG_ENABLE(pcre-regex,
-[  --disable-pcre-regex    Use old, slow GNU Regex instead of PCRE.],
-[if test $enableval = yes; then
-  AC_DEFINE(PCRE)
-  GNU_REGEX_ONLY=#
+dnl Save old CFLAGS so we can restore them later, then add SPECIAL_CFLAGS
+old_CFLAGS_nospecial=$CFLAGS
+CFLAGS="$CFLAGS $SPECIAL_CFLAGS"
+
+# Hack to force AutoConf to use the CFLAGS we just set
+dnl Warning: This may break with a future version of Autoconf
+dnl          Tested with autoconf 2.13
+ac_cpp='$CPP $CPPFLAGS $SPECIAL_CFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+
+
+dnl =================================================================
+dnl Thread support
+dnl =================================================================
+
+AC_CHECK_HEADER(pthread.h, [have_pthread=yes], [have_pthread=no])
+
+AC_ARG_ENABLE(pthread,
+[  --disable-pthread       Don't use POSIX threads (pthreads)],
+[if test $enableval = no; then
+  # Disable pthreads
+  have_pthread=no
+fi])
+
+if test $have_pthread = yes; then
+  PTHREAD_ONLY=
+  AC_DEFINE(FEATURE_PTHREAD)
+  echo Using POSIX threads
+  if test "$GCC" = "yes"; then
+    # Set a GCC specific switch:
+    if test "$target_type" = "unix"; then
+      ac_jgf_save_CFLAGS=$CFLAGS
+      CFLAGS="$CFLAGS -pthread"
+      AC_TRY_LINK([#include <pthread.h>],
+        [void *p = pthread_create;],
+        [
+          # This compiler switch makes GCC on Linux thread-safe
+          # However, it's not supported on most other OS.
+          PTHREAD_LIB=
+          SPECIAL_CFLAGS="-pthread"
+        ])
+      CFLAGS=$ac_jgf_save_CFLAGS
+    fi
+  fi
 else
-  PCRE_REGEX_ONLY=#
-fi],[AC_DEFINE(PCRE)
-  GNU_REGEX_ONLY=#
+  PTHREAD_ONLY=#
+  echo Using native threads
+fi
+
+AC_SUBST(PTHREAD_ONLY)
+
+dnl =================================================================
+dnl Support for thread-safe versions of gethostbyaddr, gethostbyname,
+dnl gmtime and localtime
+dnl =================================================================
+
+dnl Next line needed to find the gethost*_r functions on Solaris
+AC_CHECK_LIB(nsl, gethostbyname)
+
+AC_CHECK_FUNC(gethostbyaddr_r, [
+  AC_MSG_CHECKING([signature of gethostbyaddr_r])
+  AC_TRY_COMPILE([
+#   include <netdb.h>
+  ], [
+    struct hostent *h, *hp;
+    char *a, *b;
+    int l, bl, t, e;
+    (void) gethostbyaddr_r(a, l, t, h, b, bl, &hp, &e)
+  ], [
+    AC_DEFINE(HAVE_GETHOSTBYADDR_R_8_ARGS)
+    AC_MSG_RESULT([8 args])
+  ], [
+    AC_TRY_COMPILE([
+#     include <netdb.h>
+    ], [
+      struct hostent *h;
+      char *a, *b;
+      int l, bl, t, e;
+      (void) gethostbyaddr_r(a, l, t, h, b, bl, &e)
+    ], [
+      AC_DEFINE(HAVE_GETHOSTBYADDR_R_7_ARGS)
+      AC_MSG_RESULT([7 args])
+    ], [
+      AC_TRY_COMPILE([
+#       include <netdb.h>
+      ], [
+        struct hostent_data *d;
+        struct hostent *h;
+        char a,
+        int l, t;
+        (void) gethostbyaddr_r(a, l, t, h, d)
+      ], [
+        AC_DEFINE(HAVE_GETHOSTBYADDR_R_5_ARGS)
+        AC_MSG_RESULT([5 args])
+      ], [
+        AC_MSG_RESULT(unrecognised)
+      ])
+    ])
+  ])
+], [
+  AC_MSG_RESULT(no)
 ])
 
-AC_SUBST(GNU_REGEX_ONLY)
-AC_SUBST(PCRE_REGEX_ONLY)
-AC_SUBST(NO_REGEX_ONLY)
+AC_CHECK_FUNC(gethostbyname_r, [
+  AC_MSG_CHECKING([signature of gethostbyname_r])
+  AC_TRY_COMPILE([
+#   include <netdb.h>
+  ], [
+    struct hostent *h, *r;
+    char *n, *b;
+    int bl, e;
+    (void) gethostbyname_r(n, h, b, bl, &r, &e)
+  ], [
+    AC_DEFINE(HAVE_GETHOSTBYNAME_R_6_ARGS)
+    AC_MSG_RESULT([6 args])
+  ], [
+    AC_TRY_COMPILE([
+#     include <netdb.h>
+    ], [
+      struct hostent *h;
+      char *n, *b;
+      int bl, e;
+      (void) gethostbyname_r(n, h, b, bl, &e)
+    ], [
+      AC_DEFINE(HAVE_GETHOSTBYNAME_R_5_ARGS)
+      AC_MSG_RESULT([5 args])
+    ], [
+      AC_TRY_COMPILE([
+#       include <netdb.h>
+      ], [
+        struct hostent_data *d;
+        struct hostent *h;
+        char *n,
+        (void) gethostbyname_r(n, h, d)
+      ], [
+        AC_DEFINE(HAVE_GETHOSTBYNAME_R_3_ARGS)
+        AC_MSG_RESULT([3 args])
+      ], [
+        AC_MSG_RESULT(unrecognised)
+      ])
+    ])
+  ])
+], [
+  AC_MSG_RESULT(no)
+])
+
+AC_CHECK_FUNC(gmtime_r, [
+  AC_MSG_CHECKING([signature of gmtime_r])
+  AC_TRY_COMPILE([
+#   include <time.h>
+  ], [
+    struct time *t;
+    struct tm *tm;
+    (void) gmtime_r(t, tm)
+  ], [
+    AC_MSG_RESULT(ok)
+    AC_DEFINE(HAVE_GMTIME_R)
+  ], [
+    AC_MSG_RESULT(unrecognised)
+  ])
+], [
+  AC_MSG_RESULT(no)
+])
+
+AC_CHECK_FUNC(localtime_r, [
+  AC_MSG_CHECKING([signature of localtime_r])
+  AC_TRY_COMPILE([
+#   include <time.h>
+  ], [
+    struct time *t;
+    struct tm *tm;
+    (void) localtime_r(t, tm)
+  ], [
+    AC_MSG_RESULT(ok)
+    AC_DEFINE(HAVE_LOCALTIME_R)
+  ], [
+    AC_MSG_RESULT(unrecognised)
+  ])
+], [
+  AC_MSG_RESULT(no)
+])
+
+dnl =================================================================
+dnl Solaris specific
+dnl FIXME: Not tested on Solaris yet...
+dnl ISFIXED: Have tested it on Solaris, but there are other ways to
+dnl    make these checks generic, e.g.:
+dnl AC_CHECK_FUNC(getsockopt, , AC_CHECK_LIB(socket, getsockopt))
+dnl    (Moritz Barsnick <moritz@barsnick.net>)
+dnl =================================================================
+
+
+SOCKET_LIB=
+
+case "$host" in
+*-solaris*) SOCKET_LIB="-lsocket -lnsl"
+            AC_DEFINE(__EXTENSIONS__)
+            if test "$GCC" = "yes"; then
+              # Set a GCC specific switch:
+              # This compiler switch makes Solaris thread-safe
+              PTHREAD_LIB=
+              SPECIAL_CFLAGS="-pthreads"
+            else
+              # What do we do without GCC? Guess this:
+              SPECIAL_CFLAGS="-D_REENTRANT"
+            fi
+;;
+esac
+
+AC_SUBST(SOCKET_LIB)
+
+dnl =================================================================
+dnl Solaris problem, and others perhaps (socklen_t is undefined)
+dnl =================================================================
+
+AC_MSG_CHECKING([for socklen_t])
+AC_EGREP_HEADER(socklen_t, sys/socket.h, AC_MSG_RESULT([yes]),
+       AC_MSG_RESULT([no])
+       AC_DEFINE(socklen_t,int,
+               [ Define to 'int' if <sys/socket.h> doesn't have it. ]))
+
+
+dnl =================================================================
+dnl OS/2 specific
+dnl =================================================================
+
+case "$host" in
+*-os2-emx*) SOCKET_LIB=-lsocket
+;;
+esac
+
+AC_SUBST(SOCKET_LIB)
 
+dnl =================================================================
+dnl Mac OSX specific
+dnl =================================================================
+    
+case "$host" in
+*-apple-darwin*) SPECIAL_CFLAGS="-Dunix"
+;;  
+esac
 
-dnl Other features:
+dnl =================================================================
+dnl AmigaOS specific
+dnl =================================================================
+
+AMIGAOS_ONLY=#
+
+case "$host" in
+*-amigaos) AMIGAOS_ONLY=
+;;
+esac
+
+AC_SUBST(AMIGAOS_ONLY)
+
+dnl =================================================================
+dnl Check for standard compiler stuff
+dnl =================================================================
+
+AC_EXEEXT
+AC_OBJEXT
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_TYPE_PID_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_CHECK_SIZEOF(int, 4)
+AC_CHECK_SIZEOF(char *, 4)
+AC_CHECK_SIZEOF(long, 4)
+AC_CHECK_SIZEOF(long long, 8)
+AC_CHECK_SIZEOF(size_t, 4)
+
+dnl Checks for header files.
+dnl AC_HEADER_SYS_WAIT
+dnl AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/time.h unistd.h)
+AC_CHECK_HEADERS([OS.h arpa/inet.h errno.h fcntl.h limits.h locale.h netdb.h netinet/in.h stddef.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h sys/timeb.h sys/wait.h unistd.h])
+
+dnl Checks for library functions.
+dnl AC_TYPE_SIGNAL
+dnl AC_CHECK_FUNC(strstr)
+dnl bcopy and memmove are for PCRE
+AC_CHECK_FUNCS([strerror bcopy memmove])
+AC_PROG_GCC_TRADITIONAL
+dnl uncommenting does not work for swa. suse linux
+dnl AC_FUNC_MALLOC
+AC_FUNC_SETPGRP
+AC_TYPE_SIGNAL
+dnl uncommenting does not work for swa. suse linux
+dnl AC_FUNC_STAT
+AC_CHECK_FUNCS([atexit getcwd gethostbyaddr gethostbyname inet_ntoa localtime_r memchr memmove memset regcomp select setlocale socket strchr strdup strerror strftime strstr strtoul])
+
+
+dnl =================================================================
+dnl Checks for libraries.
+dnl =================================================================
+dnl Note: Some systems may have the library but not the system header
+dnl       file, so we must check for both.
+dnl       Also check for correct version
+AC_CHECK_LIB(pcre, pcre_compile, [AC_CHECK_HEADER(pcre.h, [AC_EGREP_HEADER(pcre_fullinfo, pcre.h, [have_pcre=yes], [AC_MSG_WARN([[pcre old version installed]]); have_pcre=no])], [have_pcre=no])], [have_pcre=no])
+AC_CHECK_LIB(pcreposix, regcomp, [AC_CHECK_HEADER(pcreposix.h, [AC_EGREP_HEADER(pcreposix_regerror, pcreposix.h, [AC_MSG_WARN([[pcreposix old version installed]]); have_pcreposix=no], [have_pcreposix=yes])], [have_pcreposix=no])], [have_pcreposix=no], -lpcre)
+AC_CHECK_LIB(pcrs, pcrs_compile, [AC_CHECK_HEADER(pcrs.h, [have_pcrs=yes], [have_pcrs=no])], [have_pcrs=no])
+
+
+dnl =================================================================
+dnl Always defined
+dnl =================================================================
+
+AC_DEFINE(__MT__)
+
+dnl =================================================================
+dnl Features
+dnl =================================================================
 
 AC_ARG_ENABLE(toggle,
-[  --disable-toggle        Don't support temporary disable],
+[  --disable-toggle         Don't support temporary disable],
 [if test $enableval = yes; then
-  AC_DEFINE(TOGGLE)
-fi],AC_DEFINE(TOGGLE))
+  AC_DEFINE(FEATURE_TOGGLE)
+fi],AC_DEFINE(FEATURE_TOGGLE))
 
-PCRS_ONLY=
-AC_ARG_ENABLE(pcrs,
-[  --disable-pcrs          Don't support arbitrary content modification],
+AC_ARG_ENABLE(force,
+[  --disable-force          Don't allow single-page disable],
 [if test $enableval = yes; then
-  AC_DEFINE(PCRS)
-  AC_DEFINE(DENY_GZIP)
-else
-  PCRS_ONLY=#
-fi],[AC_DEFINE(PCRS) AC_DEFINE(DENY_GZIP)])
-AC_SUBST(PCRS_ONLY)
+  AC_DEFINE(FEATURE_FORCE_LOAD)
+fi],AC_DEFINE(FEATURE_FORCE_LOAD))
 
-AC_ARG_ENABLE(force,
-[  --disable-force         Don't allow blockfle to be bypassed],
+AC_ARG_ENABLE(fast-redirects,
+[  --disable-fast-redirects Don't support fast redirects],
 [if test $enableval = yes; then
-  AC_DEFINE(FORCE_LOAD)
-fi],AC_DEFINE(FORCE_LOAD))
+  AC_DEFINE(FEATURE_FAST_REDIRECTS)
+fi], AC_DEFINE(FEATURE_FAST_REDIRECTS))
 
 AC_ARG_ENABLE(killpopup,
-[  --disable-killpopup     Never block popups],
+[  --disable-killpopup      Never block popups],
 [if test $enableval = yes; then
-  AC_DEFINE(KILLPOPUPS)
-fi],AC_DEFINE(KILLPOPUPS))
+  AC_DEFINE(FEATURE_KILL_POPUPS)
+fi],AC_DEFINE(FEATURE_KILL_POPUPS))
 
 AC_ARG_ENABLE(stats,
-[  --disable-stats         Don't keep statistics],
-[if test $enableval = yes; then
-  AC_DEFINE(STATISTICS)
-fi],AC_DEFINE(STATISTICS))
-
-AC_ARG_ENABLE(split-proxy-args,
-[  --disable-split-proxy-args  One big show-proxy-args page, not one per file.],
-[if test $enableval = yes; then
-  AC_DEFINE(SPLIT_PROXY_ARGS)
-fi],AC_DEFINE(SPLIT_PROXY_ARGS))
-
-AC_ARG_ENABLE(webdav,
-[  --disable-webdav        Don't support WebDAV.  This option stops MS Outlook
-                          Express from accessing HotMail e-mail.],
+[  --disable-stats          Don't keep statistics],
 [if test $enableval = yes; then
-  AC_DEFINE(WEBDAV)
-fi],
-AC_DEFINE(WEBDAV))
+  AC_DEFINE(FEATURE_STATISTICS)
+fi],AC_DEFINE(FEATURE_STATISTICS))
 
 AC_ARG_ENABLE(ie-images,
-[  --disable-ie-images     Don't auto-detect whether a request from MS Internet
-                          Explorer is for an image or HTML.],
+[  --disable-ie-images      Don't auto-detect whether a request from MS Internet
+                           Explorer is for an image or HTML.],
 [if test $enableval = yes; then
-  AC_DEFINE(DETECT_MSIE_IMAGES)
+  AC_DEFINE(FEATURE_IMAGE_DETECT_MSIE)
 fi],
-AC_DEFINE(DETECT_MSIE_IMAGES))
+AC_DEFINE(FEATURE_IMAGE_DETECT_MSIE))
 
-AC_ARG_ENABLE(image-list,
-[  --disable-image-list    Don't try to figure out whether a request is for an
-                          image or HTML using the imagelist - assume HTML.],
+AC_ARG_ENABLE(image-blocking,
+[  --disable-image-blocking Don't try to figure out whether a request is 
+                           for an image or HTML - assume HTML.],
 [if test $enableval = yes; then
-  AC_DEFINE(USE_IMAGE_LIST)
+  AC_DEFINE(FEATURE_IMAGE_BLOCKING)
 fi],
-AC_DEFINE(USE_IMAGE_LIST))
+AC_DEFINE(FEATURE_IMAGE_BLOCKING))
 
 AC_ARG_ENABLE(acl-files,
-[  --disable-acl-files     Prevents the use of ACL files to control access to
-                          the proxy by IP address.],
+[  --disable-acl-files      Prevents the use of ACL files to control access to
+                           the proxy by IP address.],
 [if test $enableval = yes; then
-  AC_DEFINE(ACL_FILES)
+  AC_DEFINE(FEATURE_ACL)
 fi],
-AC_DEFINE(ACL_FILES))
+AC_DEFINE(FEATURE_ACL))
 
 AC_ARG_ENABLE(trust-files,
-[  --disable-trust-files   Prevents the use of trust files.],
+[  --disable-trust-files    Prevents the use of trust files.],
 [if test $enableval = yes; then
-  AC_DEFINE(TRUST_FILES)
+  AC_DEFINE(FEATURE_TRUST)
 fi],
-AC_DEFINE(TRUST_FILES))
+AC_DEFINE(FEATURE_TRUST))
 
 AC_ARG_ENABLE(jar-files,
-[  --disable-jar-files     Prevents the use of jar files to capture cookies.],
+[  --disable-jar-files      Prevents the use of jar files to capture cookies.],
 [if test $enableval = yes; then
-  AC_DEFINE(JAR_FILES)
+  AC_DEFINE(FEATURE_COOKIE_JAR)
 fi],
-AC_DEFINE(JAR_FILES))
+AC_DEFINE(FEATURE_COOKIE_JAR))
 
-LIBRARY_PCRE_ONLY=#
-STATIC_PCRE_ONLY=
-AC_ARG_ENABLE(static-pcre,
-[  --disable-static-pcre   Link dynamically with the pcre and pcreposix
-                          libraries.  You must build the libraries seperately.],
-[if test $enableval = no; then
-  LIBRARY_PCRE_ONLY=
-  STATIC_PCRE_ONLY=#
+AC_ARG_ENABLE(editor,
+[  --disable-editor         Prevents the use of the web-based actions file
+                           editor and web-based temporary disable setting.],
+[if test $enableval = yes; then
+  AC_DEFINE(FEATURE_CGI_EDIT_ACTIONS)
+fi],
+AC_DEFINE(FEATURE_CGI_EDIT_ACTIONS))
+
+AC_ARG_ENABLE(no-gifs,
+[  --enable-no-gifs         Use politically correct PNG format instead of GIF
+                           for built-in images. May not work with all browsers.],
+[if test $enableval = yes; then
+  AC_DEFINE(FEATURE_NO_GIFS)
 fi])
-AC_SUBST(LIBRARY_PCRE_ONLY)
+
+
+dnl pcre/pcrs is needed for CGI anyway, so
+dnl the choice is only between static and
+dnl dynamic:
+
+AC_ARG_ENABLE(dynamic-pcre,
+[  --disable-dynamic-pcre        Use the built-in, static pcre, even if
+                                libpcre is available],
+[ if test $enableval = "no"; then have_pcre=no; fi ])
+
+AC_ARG_ENABLE(dynamic-pcrs,
+[  --disable-dynamic-pcrs        Use the built-in, static pcrs, even if
+                                libpcrs is available],
+[ if test $enableval = "no"; then have_pcrs=no; fi ])
+
+
+# If we have libpcre and either we also have pcreposix or
+# we don't need pcreposix, then link pcre dynamically; else
+# build it and link statically
+#
+if test $have_pcre = "yes"; then
+  echo "using libpcre"
+  pcre_dyn=yes
+  STATIC_PCRE_ONLY=#
+  LIBS="$LIBS -lpcre -lpcreposix"
+else
+  echo "using built-in static pcre"
+  pcre_dyn=no
+  AC_DEFINE(STATIC_PCRE)
+  STATIC_PCRE_ONLY=
+fi
+
+# If we have libpcrs and pcre is linked dynamically
+# then also link pcrs dynamically, else build and link
+# pcrs statically
+#
+if test $have_pcrs = "yes" -a $pcre_dyn = "yes"; then
+  echo "using libpcrs"
+  STATIC_PCRS_ONLY=#
+  LIBS="$LIBS -lpcrs"
+else
+  echo "using built-in static pcrs"
+  AC_DEFINE(STATIC_PCRS)
+  STATIC_PCRS_ONLY=
+fi
+
 AC_SUBST(STATIC_PCRE_ONLY)
+AC_SUBST(STATIC_PCRS_ONLY)
+
+dnl =================================================================
+dnl Final cleanup and output
+dnl =================================================================
+
+dnl Remove the SPECIAL_CFLAGS stuff from CFLAGS, and add it seperately
+dnl in the Makefile
+CFLAGS=$old_CFLAGS_nospecial
+AC_SUBST(SPECIAL_CFLAGS)
 
-AC_OUTPUT(Makefile)
+AC_SUBST(PTHREAD_LIB)
 
+AC_OUTPUT(GNUmakefile doc/source/ldp.dsl)
diff --git a/contrib.sh b/contrib.sh
new file mode 100755 (executable)
index 0000000..74d5b72
--- /dev/null
@@ -0,0 +1,4035 @@
+#!/bin/bash
+
+echo "This script will create the gen_list contrib files in the current"
+echo "directory.  Do you wish to continue? [y/n]"
+
+typeset ans="n"
+read ans
+
+if [[ ${ans} != [Yy]* ]]; then
+       echo "Goodbye."
+       exit 1
+fi
+
+
+typeset fileList="Makefile README addr_clean.pl gen_list.c gen_list.h isa.c
+isa.h main.c malloc_police.c malloc_police.h rec_char.c rec_char.h
+rec_charptr.c rec_charptr.h rec_double.c rec_double.h rec_long.c
+rec_long.h rec_malloc_police.c rec_malloc_police.h"
+
+
+for i in ${fileList}; do
+
+       echo "creating ${i}"
+
+       ####################################
+       ##  sed explained:
+       ##
+       ##              -e "s/^\(#${i}:\)\(.*\)/\2/"
+       ##                      Find lines belonging to
+       ##                      this file and remove the
+       ##                      filename prefix.
+       ##
+       ##              -e "t print"
+       ##                      Jump to label print if the
+       ##                      above s command matched
+       ##
+       ##              -e "d"
+       ##                      This command is skipped
+       ##                      when the s command fails.
+       ##                      This will remove any
+       ##                      non-matching data.
+       ##
+       ##              -e ":print"
+       ##                      The last thing sed does
+       ##                      is print the data.  So,
+       ##                      by now, we only print
+       ##                      lines belonging to the file.
+       ##
+       ####################################
+
+       sed     -e "s/^\(#${i}:\)\(.*\)/\2/" \
+                       -e "t print" \
+                       -e "d" \
+                       -e ":print" \
+                       ${0} > ${i}
+
+done
+
+echo "done."
+
+exit 0
+
+#Makefile:PROGRAM      = test_list
+#Makefile:CFLAGS       = -g
+#Makefile:SRC          = main.c isa.c gen_list.c rec_char.c rec_charptr.c rec_double.c rec_long.c rec_malloc_police.c malloc_police.c
+#Makefile:OBJS         = main.o isa.o gen_list.o rec_char.o rec_charptr.o rec_double.o rec_long.o rec_malloc_police.o malloc_police.o
+#Makefile:
+#Makefile:all : $(PROGRAM)
+#Makefile:
+#Makefile:$(PROGRAM) : $(OBJS)
+#Makefile:     gcc $(CFLAGS) -o $(PROGRAM) $(OBJS)
+#Makefile:
+#Makefile:clean:
+#Makefile:     rm -f $(OBJS)
+#Makefile:
+#Makefile:clobber: clean
+#Makefile:     rm -f $(PROGRAM)
+
+
+#README:This list supports:
+#README:       copy construction,
+#README:       "virtual" destruction,
+#README:       streaming,
+#README:       comparison (equal comparison currently supported).
+#README:
+#README:With the "object oriented" nature of the list, nodes, and records; it is
+#README:easily concievable that sorted lists and hash tables could be implemented
+#README:with little extra effort.
+#README:
+#README:
+#README:Philosophical point:
+#README:
+#README:I am sure there is room for improvement with this design.  I am
+#README:submitting this as a generic doubly linked list recomendation for IJB.
+#README:Whatever the "collective" decides is fine with me.
+#README:
+#README:This implementation uses the "naming space" of gen_list, derived_rec,
+#README:construct, copy construct, stream, destruct, etc...  These are open to
+#README:argument.  I just used what was familiar to me and others in the "OO"
+#README:community.  If these need changed to be adopted ... "so be it".
+#README:
+#README:
+#README:Implementation point:
+#README:
+#README:I assume this is too late for a "3.0" release.  As I work for an
+#README:airline, the whole past summer has been hectic (not to mention the
+#README:last 4 months); but things have begun to settle down and I am
+#README:following the IJB lists a bit more closely.  And I would like to say
+#README:"HOLY CRAP!" .. you guys have accompolished a lot!  Way to go.
+#README:
+#README:But, the adoption of a better linked list package should at least be
+#README:high on the next release list (if not the current one).  If you choose
+#README:this submission or not, so be it.  But as a "data structure" man, I
+#README:think IJB's linked lists need addressing.
+#README:
+#README:
+#README:List/Enlist note:
+#README:
+#README:I have noticed the list.c file.  If this generic list is adopted, I
+#README:think all existing functionallity could be duplicated with the
+#README:"copy_contruct", "equal", and "destruct" `virtuals'.  This would also
+#README:eliminate and/or enhance the other manually maintained lists in IJB.
+#README:
+#README:
+#README:Debug note:
+#README:
+#README:Since the generic list defined a "stream" virtual, it could be programmed
+#README:that the list could print itself whenever a FATAL error occurs.  A user (or
+#README:programmer) could read the list and hopefully determine the cause of the
+#README:abend.
+#README:
+#README:
+#README:Potential note:
+#README:
+#README:Think of the possibilites of a linked list, sorted list, and/or a hash
+#README:list.  Think of a request to a web site that has been referenced
+#README:before.  If a hash list keep track of all block requests and regexp
+#README:change commands, then a site could be blocked and/or modified without
+#README:ever consulting the actions lists again.  What a speed up!
+#README:
+#README:What if some of the current lists were kept in sorted lists?  Then a
+#README:search for a particular record could be a binary search instead of a
+#README:linear search.
+#README:
+#README:The actions file(s) and regexp files(s) could be inserted into the
+#README:list from front to back order (or visa versa) and the processing would
+#README:take place in actual file order (which is more natural); rather than
+#README:in reverse order (as it is today).
+#README:
+#README:
+#README:Thank you for you time and attention to this contribution.  If it is
+#README:"blessed" by the group, I am available to give time to integrating
+#README:this into IJB.
+#README:
+#README:Let me know what y'all think about this package.
+#README:
+#README:-- 
+#README:Rodney
+
+
+#addr_clean.pl:#!/usr/bin/perl
+#addr_clean.pl:
+#addr_clean.pl:##      *********************************************************************
+#addr_clean.pl:##      *
+#addr_clean.pl:##      * File                  :       $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#addr_clean.pl:##      *
+#addr_clean.pl:##      * Purpose               :       Cleans addresses out of ./test_list and replaces
+#addr_clean.pl:##      *                                               them with "english" replacements.
+#addr_clean.pl:##      *
+#addr_clean.pl:##      * Usage                 :       ./test_list | ./addr_clean.pl
+#addr_clean.pl:##      *
+#addr_clean.pl:##      * Copyright             :       This program is free software; you can redistribute it 
+#addr_clean.pl:##      *                                               and/or modify it under the terms of the GNU General
+#addr_clean.pl:##      *                                               Public License as published by the Free Software
+#addr_clean.pl:##      *                                               Foundation; either version 2 of the License, or (at
+#addr_clean.pl:##      *                                               your option) any later version.
+#addr_clean.pl:##      *
+#addr_clean.pl:##      *                                               This program is distributed in the hope that it will
+#addr_clean.pl:##      *                                               be useful, but WITHOUT ANY WARRANTY; without even the
+#addr_clean.pl:##      *                                               implied warranty of MERCHANTABILITY or FITNESS FOR A
+#addr_clean.pl:##      *                                               PARTICULAR PURPOSE.     See the GNU General Public
+#addr_clean.pl:##      *                                               License for more details.
+#addr_clean.pl:##      *
+#addr_clean.pl:##      *                                               The GNU General Public License should be included with
+#addr_clean.pl:##      *                                               this file.      If not, you can view it at
+#addr_clean.pl:##      *                                               http://www.gnu.org/copyleft/gpl.html
+#addr_clean.pl:##      *                                               or write to the Free Software Foundation, Inc., 59
+#addr_clean.pl:##      *                                               Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#addr_clean.pl:##      *
+#addr_clean.pl:##      **********************************************************************/
+#addr_clean.pl:
+#addr_clean.pl:use strict;
+#addr_clean.pl:
+#addr_clean.pl:
+#addr_clean.pl:my $nMaxList = 0;
+#addr_clean.pl:my $nMaxNode = 0;
+#addr_clean.pl:my $nMaxRec = 0;
+#addr_clean.pl:my %aaTranslation;
+#addr_clean.pl:my $strLine;
+#addr_clean.pl:
+#addr_clean.pl:while ( $strLine = <STDIN> )
+#addr_clean.pl:{
+#addr_clean.pl:        if ( $strLine =~ m!(list.*=\s*)(0x[0-9a-f]+)! )
+#addr_clean.pl:        {
+#addr_clean.pl:                my $str1 = $1;
+#addr_clean.pl:                my $str2 = $2;
+#addr_clean.pl:
+#addr_clean.pl:                if ( ! defined $aaTranslation{$str2} )
+#addr_clean.pl:                {
+#addr_clean.pl:                        $aaTranslation{$str2} = "list" . ++ $nMaxList;
+#addr_clean.pl:                }
+#addr_clean.pl:                $strLine =~ s!(list.*=\s*)(0x[0-9a-f]+)!$str1($aaTranslation{$str2})!;
+#addr_clean.pl:        }
+#addr_clean.pl:
+#addr_clean.pl:
+#addr_clean.pl:        if ( $strLine =~ m!(node.*=\s*)(0x[0-9a-f]+)! )
+#addr_clean.pl:        {
+#addr_clean.pl:                my $str1 = $1;
+#addr_clean.pl:                my $str2 = $2;
+#addr_clean.pl:
+#addr_clean.pl:                if ( ! defined $aaTranslation{$str2} )
+#addr_clean.pl:                {
+#addr_clean.pl:                        $aaTranslation{$str2} = "node" . ++ $nMaxNode;
+#addr_clean.pl:                }
+#addr_clean.pl:                $strLine =~ s!(node.*=\s*)(0x[0-9a-f]+)!$str1($aaTranslation{$str2})!;
+#addr_clean.pl:        }
+#addr_clean.pl:
+#addr_clean.pl:
+#addr_clean.pl:        if ( $strLine =~ m!(rec.*=\s*(iter_. \.\.\. )?)(0x[0-9a-f]+)! )
+#addr_clean.pl:        {
+#addr_clean.pl:                my $str1 = $1;
+#addr_clean.pl:                my $str2 = $3;
+#addr_clean.pl:
+#addr_clean.pl:                if ( ! defined $aaTranslation{$str2} )
+#addr_clean.pl:                {
+#addr_clean.pl:                        $aaTranslation{$str2} = "rec" . ++ $nMaxRec;
+#addr_clean.pl:                }
+#addr_clean.pl:                $strLine =~ s!(rec.*=\s*(iter_. \.\.\. )?)(0x[0-9a-f]+)!$str1($aaTranslation{$str2})!;
+#addr_clean.pl:        }
+#addr_clean.pl:
+#addr_clean.pl:
+#addr_clean.pl:        ## Catch the copy constuct syntax
+#addr_clean.pl:
+#addr_clean.pl:        if ( $strLine =~ m!(list.*=>\s*)(0x[0-9a-f]+)! )
+#addr_clean.pl:        {
+#addr_clean.pl:                my $str1 = $1;
+#addr_clean.pl:                my $str2 = $2;
+#addr_clean.pl:
+#addr_clean.pl:                if ( ! defined $aaTranslation{$str2} )
+#addr_clean.pl:                {
+#addr_clean.pl:                        $aaTranslation{$str2} = "list" . ++ $nMaxList;
+#addr_clean.pl:                }
+#addr_clean.pl:                $strLine =~ s!(list.*=>\s*)(0x[0-9a-f]+)!$str1($aaTranslation{$str2})!;
+#addr_clean.pl:        }
+#addr_clean.pl:
+#addr_clean.pl:
+#addr_clean.pl:        if ( $strLine =~ m!(node.*=>\s*)(0x[0-9a-f]+)! )
+#addr_clean.pl:        {
+#addr_clean.pl:                my $str1 = $1;
+#addr_clean.pl:                my $str2 = $2;
+#addr_clean.pl:
+#addr_clean.pl:                if ( ! defined $aaTranslation{$str2} )
+#addr_clean.pl:                {
+#addr_clean.pl:                        $aaTranslation{$str2} = "node" . ++ $nMaxNode;
+#addr_clean.pl:                }
+#addr_clean.pl:                $strLine =~ s!(node.*=>\s*)(0x[0-9a-f]+)!$str1($aaTranslation{$str2})!;
+#addr_clean.pl:        }
+#addr_clean.pl:
+#addr_clean.pl:
+#addr_clean.pl:        if ( $strLine =~ m!(rec.*=>\s*)(0x[0-9a-f]+)! )
+#addr_clean.pl:        {
+#addr_clean.pl:                my $str1 = $1;
+#addr_clean.pl:                my $str2 = $2;
+#addr_clean.pl:
+#addr_clean.pl:                if ( ! defined $aaTranslation{$str2} )
+#addr_clean.pl:                {
+#addr_clean.pl:                        $aaTranslation{$str2} = "rec" . ++ $nMaxRec;
+#addr_clean.pl:                }
+#addr_clean.pl:                $strLine =~ s!(rec.*=>\s*)(0x[0-9a-f]+)!$str1($aaTranslation{$str2})!;
+#addr_clean.pl:        }
+#addr_clean.pl:
+#addr_clean.pl:        print( $strLine );
+#addr_clean.pl:
+#addr_clean.pl:}
+
+
+#gen_list.c:const char gen_list_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#gen_list.c: *
+#gen_list.c: * Purpose     :  To create some functions to do generic doubly linked
+#gen_list.c: *                                         list management.
+#gen_list.c: *
+#gen_list.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#gen_list.c: *                Privoxy team. http://www.privoxy.org/
+#gen_list.c: *
+#gen_list.c: *                This program is free software; you can redistribute it
+#gen_list.c: *                and/or modify it under the terms of the GNU General
+#gen_list.c: *                Public License as published by the Free Software
+#gen_list.c: *                Foundation; either version 2 of the License, or (at
+#gen_list.c: *                your option) any later version.
+#gen_list.c: *
+#gen_list.c: *                This program is distributed in the hope that it will
+#gen_list.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#gen_list.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#gen_list.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#gen_list.c: *                License for more details.
+#gen_list.c: *
+#gen_list.c: *                The GNU General Public License should be included with
+#gen_list.c: *                this file.  If not, you can view it at
+#gen_list.c: *                http://www.gnu.org/copyleft/gpl.html
+#gen_list.c: *                or write to the Free Software Foundation, Inc., 59
+#gen_list.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#gen_list.c: *
+#gen_list.c: * VI users                :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#gen_list.c: *                                         and edit IJB, correctly.
+#gen_list.c: *
+#gen_list.c: * Revisions   :
+#gen_list.c: *    $Log: contrib.sh,v $
+#gen_list.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#gen_list.c: *    name change related issues
+#gen_list.c: *
+#gen_list.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#gen_list.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#gen_list.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#gen_list.c: *    contrib directory and I cannot upload a tarball ... it gets
+#gen_list.c: *    corrupted).  This script will expand all files needed to create the
+#gen_list.c: *    linked list modules and an example program.  Please see the README.
+#gen_list.c: *    Feed back is welcomed.  Enjoy.
+#gen_list.c: *
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:\f
+#gen_list.c:
+#gen_list.c:#include <malloc.h>
+#gen_list.c:#include <stdio.h>
+#gen_list.c:#include <stdlib.h>
+#gen_list.c:#include <string.h>
+#gen_list.c:
+#gen_list.c:#include "gen_list.h"
+#gen_list.c:#include "malloc_police.h"
+#gen_list.c:
+#gen_list.c:const char gen_list_h_rcs[] = GEN_LIST_H_VERSION;
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/* This is used (for the moment) to cut out all the        */
+#gen_list.c:/* extra verbige of the malloc_police module.  After       */
+#gen_list.c:/* all, we do not want to see construct/destruct of a      */
+#gen_list.c:/* class that is supposed to be "in the background".       */
+#gen_list.c:
+#gen_list.c:/* But it could lead to broader usage.                                             */
+#gen_list.c:
+#gen_list.c:int list_is_quiet = 0;
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:#define CALL_VT_REC_COPY_CONSTRUCT(rec)    (((rec_copy_construct)(rec)->vtable[ VT_REC_COPY_CONSTRUCT ])( rec ))
+#gen_list.c:#define CALL_VT_REC_DESTRUCT(rec)                  (((rec_destruct)(rec)->vtable[ VT_REC_DESTRUCT ])( rec ))
+#gen_list.c:#define CALL_VT_REC_STREAM(rec)                            (((rec_stream)(rec)->vtable[ VT_REC_STREAM ])( rec ))
+#gen_list.c:#define CALL_VT_REC_EQUAL(rec,eq_rec)              (((rec_equal)((rec)->vtable[ VT_REC_EQUAL ]))( rec, eq_rec ))
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_rec_construct
+#gen_list.c: *
+#gen_list.c: * Description :  Called from a derived list record class ONLY.
+#gen_list.c: *                                         This function "construct" a classs: malloc_ed,
+#gen_list.c: *                                         vtable, isa, and sizeof_rec "attributes".
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The record.  If NULL, malloc is called.
+#gen_list.c: *                         2       :       isa (prounced "is a") ... type of the record.
+#gen_list.c: *                         3       :       Memory image size of this record.
+#gen_list.c: *                  ...    :       The "virtuals" for this record.  NOTE: this list
+#gen_list.c: *                                         may increase if more "virtuals" are added.
+#gen_list.c: *
+#gen_list.c: * Returns     :  A pointer to the record (either the orig record
+#gen_list.c: *                                         or the malloc_ed copy.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_rec_construct( enum GEN_LIST_ISA isa, int sizeof_rec, const t_vtable _vtable )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_rec *this_rec = (struct gen_list_rec *)MALLOC( sizeof_rec );
+#gen_list.c:   this_rec->vtable                = _vtable;
+#gen_list.c:   this_rec->isa                   = isa;
+#gen_list.c:   this_rec->sizeof_rec    = sizeof_rec;
+#gen_list.c:
+#gen_list.c:   return( this_rec );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_rec_copy_construct
+#gen_list.c: *
+#gen_list.c: * Description :  Makes a copy of the current existing record.  All
+#gen_list.c: *                                         inherited properties (isa, vtable, malloc_ed, ...)
+#gen_list.c: *                                         are kept in tact after the copy.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  Existing record.
+#gen_list.c: *                         2       :  New record.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The newly constructed copy record.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_rec_copy_construct( const struct gen_list_rec *this_rec )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_rec *copy_rec = (struct gen_list_rec *)MALLOC( this_rec->sizeof_rec );
+#gen_list.c:   copy_rec->vtable                = this_rec->vtable;
+#gen_list.c:   copy_rec->isa                   = this_rec->isa;
+#gen_list.c:   copy_rec->sizeof_rec    = this_rec->sizeof_rec;
+#gen_list.c:
+#gen_list.c:   return( copy_rec );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_rec_destruct
+#gen_list.c: *
+#gen_list.c: * Description :  Destruct the record.  Including free_ing the memory
+#gen_list.c: *                                         if applicable.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The record.
+#gen_list.c: *
+#gen_list.c: * Returns     :  NULL
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_rec_destruct( struct gen_list_rec *this_rec )
+#gen_list.c:{
+#gen_list.c:   FREE( this_rec );
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_rec_stream
+#gen_list.c: *
+#gen_list.c: * Description :  Displays all attributes on the STDOUT stream.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The record.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The record.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:const struct gen_list_rec *gen_list_rec_stream( const struct gen_list_rec *this_rec )
+#gen_list.c:{
+#gen_list.c:   LIST_SHOW( printf( "\t\tstream rec isa = %s\n", isa_ra[ this_rec->isa ] ) );
+#gen_list.c:   return( this_rec );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_rec_equal
+#gen_list.c: *
+#gen_list.c: * Description :  Compares two records to see if they are equal.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  A record.
+#gen_list.c: *          2  :  Another record.
+#gen_list.c: *
+#gen_list.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:int gen_list_rec_equal( const struct gen_list_rec *this_rec, const struct gen_list_rec *eq_rec )
+#gen_list.c:{
+#gen_list.c:   if ( NULL == this_rec && NULL == eq_rec )
+#gen_list.c:   {
+#gen_list.c:           return( 1 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   if (    ( NULL == this_rec && NULL != eq_rec )  ||
+#gen_list.c:                   ( NULL != this_rec && NULL == eq_rec ) )
+#gen_list.c:   {
+#gen_list.c:           return( 0 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   if (    ( this_rec->isa != eq_rec->isa ) ||
+#gen_list.c:                   ( this_rec->sizeof_rec != eq_rec->sizeof_rec ) )
+#gen_list.c:   {
+#gen_list.c:           LIST_SHOW( printf( "INFORMATION: sorry, but comparing different rec types is unsupported at this time.\n" ) );
+#gen_list.c:           return( 0 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( 1 );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*\f*********************************************************************/
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:struct gen_list_node
+#gen_list.c:{
+#gen_list.c:   /* private: */
+#gen_list.c:   struct gen_list_node    *next;
+#gen_list.c:   struct gen_list_node    *prev;
+#gen_list.c:
+#gen_list.c:   struct gen_list_rec     *rec;
+#gen_list.c:};
+#gen_list.c:/* public: */
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_construct( struct gen_list_rec *_rec );
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_copy_construct( const struct gen_list_node *this_node );
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_destruct( struct gen_list_node *this_node );
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_remove( struct gen_list_node *this_node );
+#gen_list.c:
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_set_next( struct gen_list_node *this_node, struct gen_list_node *_next );
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_set_prev( struct gen_list_node *this_node, struct gen_list_node *_prev );
+#gen_list.c:
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_get_next( const struct gen_list_node *this_node );
+#gen_list.c:extern struct gen_list_node *                      gen_list_node_get_prev( const struct gen_list_node *this_node );
+#gen_list.c:
+#gen_list.c:extern const struct gen_list_rec   *       gen_list_node_stream( const struct gen_list_node *this_node );
+#gen_list.c:extern int                                                                 gen_list_node_equal( const struct gen_list_node *this_node, const struct gen_list_node *eq_node );
+#gen_list.c:
+#gen_list.c:/* struct/class COMPLETE */
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_construct
+#gen_list.c: *
+#gen_list.c: * Description :  Constructs a generic list node and sets its record.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The node.  If NULL, malloc is called.
+#gen_list.c: *          2  :  The nodes record contents.
+#gen_list.c: *
+#gen_list.c: * Returns     :  A pointer to the node (either the orig node
+#gen_list.c: *                                         or the malloc_ed copy.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_construct( struct gen_list_rec *_rec )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *this_node = (struct gen_list_node *)MALLOC( sizeof( struct gen_list_node ) );
+#gen_list.c:
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:\tconstruct new node\t\t= %p
+#gen_list.c:\tconstruct new node->rec\t= %p\n\n", (const void *)this_node, (const void *)_rec ) );
+#gen_list.c:
+#gen_list.c:   this_node->rec          = _rec;
+#gen_list.c:   this_node->next = NULL;
+#gen_list.c:   this_node->prev = NULL;
+#gen_list.c:
+#gen_list.c:   return( this_node );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_copy_construct
+#gen_list.c: *
+#gen_list.c: * Description :  Makes a copy of the current node.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  Existing node.
+#gen_list.c: *                         2       :  New node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The newly constructed copy node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_copy_construct( const struct gen_list_node *this_node )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *copy_node = (struct gen_list_node *)MALLOC( sizeof( struct gen_list_node ) );
+#gen_list.c:
+#gen_list.c:   LIST_SHOW( printf( "\tcopy construct new node = %p => %p\n\n", (const void *)this_node, (const void *)copy_node ) );
+#gen_list.c:
+#gen_list.c:   copy_node->rec          = CALL_VT_REC_COPY_CONSTRUCT( this_node->rec );
+#gen_list.c:   copy_node->next = NULL;
+#gen_list.c:   copy_node->prev = NULL;
+#gen_list.c:
+#gen_list.c:   return( copy_node );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_destruct
+#gen_list.c: *
+#gen_list.c: * Description :  Destruct the node.  Including free_ing the memory
+#gen_list.c: *                                         if applicable.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  NULL
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_destruct( struct gen_list_node *this_node )
+#gen_list.c:{
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:\tdestruct this_node\t\t\t= %p
+#gen_list.c:\tdestruct this_node->rec\t\t= %p
+#gen_list.c:\tdestruct this_node->next\t= %p
+#gen_list.c:\tdestruct this_node->prev\t= %p\n\n", (const void *)this_node, (const void *)this_node->rec, (const void *)this_node->next, (const void *)this_node->prev ) );
+#gen_list.c:
+#gen_list.c:   if ( NULL != this_node->rec )
+#gen_list.c:   {
+#gen_list.c:           CALL_VT_REC_DESTRUCT( this_node->rec );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   FREE( this_node );
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_remove
+#gen_list.c: *
+#gen_list.c: * Description :  Destruct the node.  Including free_ing the memory
+#gen_list.c: *                                         if applicable.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  NULL
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_remove( struct gen_list_node *this_node )
+#gen_list.c:{
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:\tremove this_node\t\t\t= %p
+#gen_list.c:\tremove this_node->rec\t= %p
+#gen_list.c:\tremove this_node->next\t= %p
+#gen_list.c:\tremove this_node->prev\t= %p\n\n", (const void *)this_node, (const void *)this_node->rec, (const void *)this_node->next, (const void *)this_node->prev ) );
+#gen_list.c:
+#gen_list.c:   FREE( this_node );
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_set_next
+#gen_list.c: *
+#gen_list.c: * Description :  Sets the next node in the list series.  Used mainly
+#gen_list.c: *                                         when constructing and adding/removing nodes.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The node.
+#gen_list.c: *          2  :  The next node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_set_next( struct gen_list_node *this_node, struct gen_list_node *_next )
+#gen_list.c:{
+#gen_list.c:   this_node->next = _next;
+#gen_list.c:   return( this_node );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_set_prev
+#gen_list.c: *
+#gen_list.c: * Description :  Sets the previous node in the list series.  Used mainly
+#gen_list.c: *                                         when constructing and adding/removing nodes.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The node.
+#gen_list.c: *          2  :  The previous node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_set_prev( struct gen_list_node *this_node, struct gen_list_node *_prev )
+#gen_list.c:{
+#gen_list.c:   this_node->prev = _prev;
+#gen_list.c:   return( this_node );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_get_next
+#gen_list.c: *
+#gen_list.c: * Description :  Gets the next node in the list series.  Used mainly
+#gen_list.c: *                                         for traversing a list.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The next node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_get_next( const struct gen_list_node *this_node )
+#gen_list.c:{
+#gen_list.c:   return( this_node->next );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_get_prev
+#gen_list.c: *
+#gen_list.c: * Description :  Gets the previous node in the list series.  Used mainly
+#gen_list.c: *                                         for traversing a list.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The previous node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_node *gen_list_node_get_prev( const struct gen_list_node *this_node )
+#gen_list.c:{
+#gen_list.c:   return( this_node->prev );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_stream
+#gen_list.c: *
+#gen_list.c: * Description :  Displays all attributes on the STDOUT stream,
+#gen_list.c: *                                         including the contents of the nodes record.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The record.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The result of streaming the nodes record.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:const struct gen_list_rec *gen_list_node_stream( const struct gen_list_node *this_node )
+#gen_list.c:{
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:\tstream this_node\t\t\t= %p
+#gen_list.c:\tstream this_node->rec\t= %p
+#gen_list.c:\tstream this_node->next\t= %p
+#gen_list.c:\tstream this_node->prev\t= %p\n\n", (const void *)this_node, (const void *)this_node->rec, (const void *)this_node->next, (const void *)this_node->prev ) );
+#gen_list.c:
+#gen_list.c:   return( CALL_VT_REC_STREAM( this_node->rec ) );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_node_equal
+#gen_list.c: *
+#gen_list.c: * Description :  Compares two nodes (and their records) to see if they are equal.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  A node.
+#gen_list.c: *          2  :  Another node.
+#gen_list.c: *
+#gen_list.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:int gen_list_node_equal( const struct gen_list_node *this_node, const struct gen_list_node *eq_node )
+#gen_list.c:{
+#gen_list.c:   if ( NULL == this_node && NULL == eq_node )
+#gen_list.c:   {
+#gen_list.c:           return( 1 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   if (    ( NULL == this_node && NULL != eq_node ) ||
+#gen_list.c:                   ( NULL != this_node && NULL == eq_node ) )
+#gen_list.c:   {
+#gen_list.c:           return( 0 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( gen_list_rec_equal( this_node->rec, eq_node->rec ) );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*\f*********************************************************************/
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/* private: */
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_insert_node
+#gen_list.c: *
+#gen_list.c: * Description :  Inserts a node (not a record!) into a list.  This
+#gen_list.c: *                                         is (currently) only used in copy construction.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *          2  :  A new node to insert into the list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:const struct gen_list_node *gen_list_insert_node( struct gen_list *this_list, struct gen_list_node *node )
+#gen_list.c:{
+#gen_list.c:   gen_list_node_set_next( node, NULL );
+#gen_list.c:
+#gen_list.c:   if ( NULL == this_list->first )
+#gen_list.c:   {
+#gen_list.c:           this_list->first = node;
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   if ( NULL == this_list->last )
+#gen_list.c:   {
+#gen_list.c:           this_list->last = node;
+#gen_list.c:   }
+#gen_list.c:   else
+#gen_list.c:   {
+#gen_list.c:           gen_list_node_set_next( this_list->last, node );
+#gen_list.c:           gen_list_node_set_prev( node, this_list->last );
+#gen_list.c:           this_list->last = node;
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   this_list->last = node;
+#gen_list.c:
+#gen_list.c:   return( node );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_construct
+#gen_list.c: *
+#gen_list.c: * Description :  Constructs a generic list.
+#gen_list.c: *
+#gen_list.c: * Parameters  :   None
+#gen_list.c: *
+#gen_list.c: * Returns     :  A pointer to the list (either the orig list
+#gen_list.c: *                                         or the malloc_ed copy.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list *gen_list_construct()
+#gen_list.c:{
+#gen_list.c:   struct gen_list *this_list = (struct gen_list *)MALLOC( sizeof( struct gen_list ) );
+#gen_list.c:   LIST_SHOW( printf( "construct new list = %p\n\n", (const void *)this_list ) );
+#gen_list.c:
+#gen_list.c:   this_list->first        = NULL;
+#gen_list.c:   this_list->last = NULL;
+#gen_list.c:
+#gen_list.c:   return( this_list );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_copy_construct
+#gen_list.c: *
+#gen_list.c: * Description :  Makes a copy of the current list.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  Existing list.
+#gen_list.c: *                         2       :  New list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The newly constructed copy list.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list *gen_list_copy_construct( const struct gen_list *this_list )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *curr = this_list->first;
+#gen_list.c:   struct gen_list *copy_list = (struct gen_list *)MALLOC( sizeof( struct gen_list ) );
+#gen_list.c:
+#gen_list.c:   LIST_SHOW( printf( "copy construct new list = %p => %p\n\n", (const void *)this_list, (const void *)copy_list ) );
+#gen_list.c:
+#gen_list.c:   copy_list->first        = NULL;
+#gen_list.c:   copy_list->last = NULL;
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:   while ( NULL != curr )
+#gen_list.c:   {
+#gen_list.c:           struct gen_list_node *copy_node = gen_list_node_copy_construct( curr );
+#gen_list.c:           gen_list_insert_node( copy_list, copy_node );
+#gen_list.c:           curr = gen_list_node_get_next( curr );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( copy_list );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_destruct
+#gen_list.c: *
+#gen_list.c: * Description :  Destruct the list.  Including free_ing the memory
+#gen_list.c: *                                         if applicable.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  NULL
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list *gen_list_destruct( struct gen_list *this_list )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *curr = this_list->first;
+#gen_list.c:
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:destruct this_list\t\t\t= %p
+#gen_list.c:destruct this_list->first\t= %p
+#gen_list.c:destruct this_list->last\t= %p\n\n", (const void *)this_list, (const void *)this_list->first, (const void *)this_list->last ) );
+#gen_list.c:
+#gen_list.c:   while ( NULL != curr )
+#gen_list.c:   {
+#gen_list.c:           struct gen_list_node *next = gen_list_node_get_next( curr );
+#gen_list.c:           gen_list_node_destruct( curr );
+#gen_list.c:           curr = next;
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   FREE( this_list );
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_remove_all
+#gen_list.c: *
+#gen_list.c: * Description :  Destruct the list.  Including free_ing the memory
+#gen_list.c: *                                         if applicable.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  NULL
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list *gen_list_remove_all( struct gen_list *this_list )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *curr = this_list->first;
+#gen_list.c:
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:remove_all this_list\t\t\t\t= %p
+#gen_list.c:remove_all this_list->first\t= %p
+#gen_list.c:remove_all this_list->last\t\t= %p\n\n", (const void *)this_list, (const void *)this_list->first, (const void *)this_list->last ) );
+#gen_list.c:
+#gen_list.c:   while ( NULL != curr )
+#gen_list.c:   {
+#gen_list.c:           struct gen_list_node *next = gen_list_node_get_next( curr );
+#gen_list.c:           gen_list_node_remove( curr );
+#gen_list.c:           curr = next;
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   this_list->first = this_list->last = NULL;
+#gen_list.c:   return( this_list );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_remove
+#gen_list.c: *
+#gen_list.c: * Description :  A record from the list and return it if found.  This
+#gen_list.c: *                                         will allow a futher call to rec_destruct.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *          2  :  The record to be removed.
+#gen_list.c: *
+#gen_list.c: * Returns     :  rec if found and removed, NULL otherwise.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_remove( struct gen_list *this_list, struct gen_list_rec *rec )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node    *curr = this_list->first;
+#gen_list.c:
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:remove this_list\t\t\t= %p
+#gen_list.c:remove this_list->first\t= %p
+#gen_list.c:remove this_list->last\t= %p
+#gen_list.c:remove rec\t\t\t\t\t= %p\n\n", (const void *)this_list, (const void *)this_list->first, (const void *)this_list->last, rec ) );
+#gen_list.c:
+#gen_list.c:   while ( NULL != curr )
+#gen_list.c:   {
+#gen_list.c:           /* Grab these values before the are destroyed. */
+#gen_list.c:           struct gen_list_node    *prev = gen_list_node_get_prev( curr );
+#gen_list.c:           struct gen_list_node    *next = gen_list_node_get_next( curr );
+#gen_list.c:
+#gen_list.c:           /* Access to rec, next, prev of gen_list_node is allowed since it is private to gen_list */
+#gen_list.c:           if ( curr->rec == rec )
+#gen_list.c:           {
+#gen_list.c:                   /* Destruct the node, but not the record. */
+#gen_list.c:                   gen_list_node_remove( curr );
+#gen_list.c:
+#gen_list.c:                   if ( NULL == prev )
+#gen_list.c:                   {
+#gen_list.c:                           /************************************************/
+#gen_list.c:                           /* This is the first node in the list.                          */
+#gen_list.c:                           /*      Picture:                                                                                                */
+#gen_list.c:                           /* [first] ---------------------> [next]                        */
+#gen_list.c:                           /* [NULL] <---------------------- [next->prev]  */
+#gen_list.c:                           /************************************************/
+#gen_list.c:                           this_list->first = next;
+#gen_list.c:
+#gen_list.c:                           if ( NULL == next )
+#gen_list.c:                           {
+#gen_list.c:                                   /* Since next is NULL, then this is an empty list. */
+#gen_list.c:                                   this_list->last = NULL;
+#gen_list.c:                           }
+#gen_list.c:                           else
+#gen_list.c:                           {
+#gen_list.c:                                   /* Since next is not NULL, then there is another node to make first. */
+#gen_list.c:                                   gen_list_node_set_prev( next, NULL );
+#gen_list.c:                           }
+#gen_list.c:                   }
+#gen_list.c:                   else if ( NULL == next )
+#gen_list.c:                   {
+#gen_list.c:                           /************************************************/
+#gen_list.c:                           /* This is the last node in the list.                           */
+#gen_list.c:                           /*      Picture:                                                                                                */
+#gen_list.c:                           /* [last] ----------------------> [prev]                        */
+#gen_list.c:                           /* [prev->next] ----------------> [NULL]                        */
+#gen_list.c:                           /************************************************/
+#gen_list.c:                           this_list->last = prev;
+#gen_list.c:
+#gen_list.c:                           if ( NULL == prev )
+#gen_list.c:                           {
+#gen_list.c:                                   /* Since prev is NULL, then this is an empty list. */
+#gen_list.c:                                   this_list->first = NULL;
+#gen_list.c:                           }
+#gen_list.c:                           else
+#gen_list.c:                           {
+#gen_list.c:                                   /* Since prev is NULL, then there is another node to make last. */
+#gen_list.c:                                   gen_list_node_set_next( prev, NULL );
+#gen_list.c:                           }
+#gen_list.c:                   }
+#gen_list.c:                   else
+#gen_list.c:                   {
+#gen_list.c:                           /************************************************/
+#gen_list.c:                           /* This is a middle node in the list.                           */
+#gen_list.c:                           /*      Picture:                                                                                                */
+#gen_list.c:                           /* [prev->next] ----------------> [next]                        */
+#gen_list.c:                           /*                                      [removing middle]                                               */
+#gen_list.c:                           /* [prev] <---------------------- [next->prev]  */
+#gen_list.c:                           /************************************************/
+#gen_list.c:                           gen_list_node_set_next( prev, next );
+#gen_list.c:                           gen_list_node_set_prev( next, prev );
+#gen_list.c:                   }
+#gen_list.c:
+#gen_list.c:                   return( rec );
+#gen_list.c:           }
+#gen_list.c:           curr = next;
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_get_first
+#gen_list.c: *
+#gen_list.c: * Description :  Gets the first record in the list.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The first node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_get_first( const struct gen_list *this_list )
+#gen_list.c:{
+#gen_list.c:   if ( NULL == this_list->first )
+#gen_list.c:   {
+#gen_list.c:           return( NULL );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   /* Access to rec of gen_list_node is allowed since it is private to gen_list */
+#gen_list.c:   return( this_list->first->rec );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_get_last
+#gen_list.c: *
+#gen_list.c: * Description :  Gets the last record in the list.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The last node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_get_last( const struct gen_list *this_list )
+#gen_list.c:{
+#gen_list.c:   if ( NULL == this_list->last )
+#gen_list.c:   {
+#gen_list.c:           return( NULL );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   /* Access to rec of gen_list_node is allowed since it is private to gen_list */
+#gen_list.c:   return( this_list->last->rec );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_insert
+#gen_list.c: *
+#gen_list.c: * Description :  Inserts a record into the list.  This is the
+#gen_list.c: *                                         primary API interface for inserting a record.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *          2  :  A new record to insert into the list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The node.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:const struct gen_list_node *gen_list_insert( struct gen_list *this_list, struct gen_list_rec *_rec )
+#gen_list.c:{
+#gen_list.c:   return( gen_list_insert_node( this_list, gen_list_node_construct( _rec ) ) );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_stream
+#gen_list.c: *
+#gen_list.c: * Description :  Displays all attributes on the STDOUT stream,
+#gen_list.c: *                                         including the contents of the nodes.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  The list.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:const struct gen_list *gen_list_stream( const struct gen_list *this_list )
+#gen_list.c:{
+#gen_list.c:   const struct gen_list_node *curr = this_list->first;
+#gen_list.c:
+#gen_list.c:   LIST_SHOW( printf( "\
+#gen_list.c:stream this_list\t\t\t= %p
+#gen_list.c:stream this_list->first\t= %p
+#gen_list.c:stream this_list->last\t= %p\n\n", (const void *)this_list, (const void *)this_list->first, (const void *)this_list->last ) );
+#gen_list.c:
+#gen_list.c:   while ( NULL != curr )
+#gen_list.c:   {
+#gen_list.c:           struct gen_list_node    *next = gen_list_node_get_next( curr );
+#gen_list.c:           gen_list_node_stream( curr );
+#gen_list.c:           curr = next;
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( this_list );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_equal
+#gen_list.c: *
+#gen_list.c: * Description :  Compares two lists (and their nodes) to see if they are equal.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  A list.
+#gen_list.c: *          2  :  Another list.
+#gen_list.c: *
+#gen_list.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:int gen_list_equal( const struct gen_list *this_list, const struct gen_list *eq_list )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *c1 = this_list->first;
+#gen_list.c:   struct gen_list_node *c2 = eq_list->first;
+#gen_list.c:   int eq = 1;
+#gen_list.c:
+#gen_list.c:   if ( ( NULL == c1 && NULL != c2 ) || ( NULL != c1 && NULL == c2 ) )
+#gen_list.c:   {
+#gen_list.c:           return( 0 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   while ( ( eq ) && ( NULL != c1 ) && ( NULL != c2 ) )
+#gen_list.c:   {
+#gen_list.c:           /* Access to rec of gen_list_node is allowed since it is private to gen_list */
+#gen_list.c:           eq = CALL_VT_REC_EQUAL( c1->rec, c2->rec );
+#gen_list.c:           if ( NULL != c1 )
+#gen_list.c:           {
+#gen_list.c:                   c1 = gen_list_node_get_next( c1 );
+#gen_list.c:           }
+#gen_list.c:
+#gen_list.c:           if ( NULL != c2 )
+#gen_list.c:           {
+#gen_list.c:                   c2 = gen_list_node_get_next( c2 );
+#gen_list.c:           }
+#gen_list.c:
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   if ( NULL == c1 && NULL == c2 )
+#gen_list.c:   {
+#gen_list.c:           return( 1 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( eq );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_find
+#gen_list.c: *
+#gen_list.c: * Description :  Find a record that matches the one passed to this
+#gen_list.c: *                                         function.
+#gen_list.c: *                                         NOTE: this function receives a RECORD and not a NODE.
+#gen_list.c: *                                         Some implementation issues might be easier addressed
+#gen_list.c: *                                         if a node was passed ... but for the time being, I
+#gen_list.c: *                                         would like to keep the use/programmer isolated from
+#gen_list.c: *                                         the node structure/class.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *          2  :  The record to find.
+#gen_list.c: *
+#gen_list.c: * Returns     :  NULL => none found, anything else is a pointer to the record.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_find( const struct gen_list *this_list, struct gen_list_rec *rec )
+#gen_list.c:{
+#gen_list.c:   const struct gen_list_node *curr = this_list->first;
+#gen_list.c:   int eq = 0;
+#gen_list.c:
+#gen_list.c:   if ( NULL == curr && NULL == rec )
+#gen_list.c:   {
+#gen_list.c:           return( (struct gen_list_rec *)1 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   if (    ( NULL == curr && NULL != rec ) ||
+#gen_list.c:                   ( NULL != curr && NULL == rec ) )
+#gen_list.c:   {
+#gen_list.c:           return( 0 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   /* Access to rec of gen_list_node is allowed since it is private to gen_list */
+#gen_list.c:   if ( curr->rec->isa != rec->isa )
+#gen_list.c:   {
+#gen_list.c:           LIST_SHOW( printf( "INFORMATION: sorry, but comparing different list types is unsupported at this time.\n" ) );
+#gen_list.c:           return( 0 );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   if ( NULL == curr )
+#gen_list.c:   {
+#gen_list.c:           return( NULL );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:   while ( ( !eq ) && ( NULL != curr ) )
+#gen_list.c:   {
+#gen_list.c:           struct gen_list_node    *next = gen_list_node_get_next( curr );
+#gen_list.c:
+#gen_list.c:           eq = CALL_VT_REC_EQUAL( curr->rec, rec );
+#gen_list.c:
+#gen_list.c:           if ( eq )
+#gen_list.c:           {
+#gen_list.c:                   return( curr->rec );
+#gen_list.c:           }
+#gen_list.c:
+#gen_list.c:           curr = next;
+#gen_list.c:
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_iterate
+#gen_list.c: *
+#gen_list.c: * Description :  Pass over the list, calling "iter" for every record.
+#gen_list.c: *                                         If the "iter" function returns a non-NULL value,
+#gen_list.c: *                                         return it and stop iterating.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *          2  :  The iterator function.
+#gen_list.c: *
+#gen_list.c: * Returns     :  Whatever the iterator does, or NULL if the entire
+#gen_list.c: *                                         list was processed.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_iterate( struct gen_list *this_list, rec_iterate iter )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *curr = this_list->first;
+#gen_list.c:
+#gen_list.c:   if ( NULL == curr )
+#gen_list.c:   {
+#gen_list.c:           return( NULL );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   while ( NULL != curr )
+#gen_list.c:   {
+#gen_list.c:           /* Access to rec of gen_list_node is allowed since it is private to gen_list */
+#gen_list.c:           struct gen_list_node    *next = gen_list_node_get_next( curr );
+#gen_list.c:           struct gen_list_rec *r = iter( curr->rec );
+#gen_list.c:
+#gen_list.c:           if ( NULL != r )
+#gen_list.c:           {
+#gen_list.c:                   return( r );
+#gen_list.c:           }
+#gen_list.c:
+#gen_list.c:           curr = next;
+#gen_list.c:
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+#gen_list.c:
+#gen_list.c:
+#gen_list.c:/*********************************************************************
+#gen_list.c: *
+#gen_list.c: * Function    :  gen_list_iterate
+#gen_list.c: *
+#gen_list.c: * Description :  Pass over the list (in reverse order), calling "iter"
+#gen_list.c: *                                         for every record.  If the "iter" function returns
+#gen_list.c: *                                         a non-NULL value, return it and stop iterating.
+#gen_list.c: *
+#gen_list.c: * Parameters  :
+#gen_list.c: *          1  :  The list.
+#gen_list.c: *          2  :  The iterator function.
+#gen_list.c: *
+#gen_list.c: * Returns     :  Whatever the iterator does, or NULL if the entire
+#gen_list.c: *                                         list was processed.
+#gen_list.c: *
+#gen_list.c: *********************************************************************/
+#gen_list.c:struct gen_list_rec *gen_list_iterate_reverse( struct gen_list *this_list, rec_iterate iter )
+#gen_list.c:{
+#gen_list.c:   struct gen_list_node *curr = this_list->last;
+#gen_list.c:
+#gen_list.c:   if ( NULL == curr )
+#gen_list.c:   {
+#gen_list.c:           return( NULL );
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   while ( NULL != curr )
+#gen_list.c:   {
+#gen_list.c:           /* Access to rec of gen_list_node is allowed since it is private to gen_list */
+#gen_list.c:           struct gen_list_node    *prev = gen_list_node_get_prev( curr );
+#gen_list.c:           struct gen_list_rec *r = iter( curr->rec );
+#gen_list.c:
+#gen_list.c:           if ( NULL != r )
+#gen_list.c:           {
+#gen_list.c:                   return( r );
+#gen_list.c:           }
+#gen_list.c:
+#gen_list.c:           curr = prev;
+#gen_list.c:
+#gen_list.c:   }
+#gen_list.c:
+#gen_list.c:   return( NULL );
+#gen_list.c:
+#gen_list.c:}
+
+
+#gen_list.h:#ifndef GEN_LIST_H_INCLUDED
+#gen_list.h:#define GEN_LIST_H_INCLUDED
+#gen_list.h:#define GEN_LIST_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#gen_list.h:/*********************************************************************
+#gen_list.h: *
+#gen_list.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#gen_list.h: *
+#gen_list.h: * Purpose     :  To create some functions to do generic doubly linked
+#gen_list.h: *                                         list management.
+#gen_list.h: *
+#gen_list.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#gen_list.h: *                Privoxy team. http://www.privoxy.org/
+#gen_list.h: *
+#gen_list.h: *                This program is free software; you can redistribute it
+#gen_list.h: *                and/or modify it under the terms of the GNU General
+#gen_list.h: *                Public License as published by the Free Software
+#gen_list.h: *                Foundation; either version 2 of the License, or (at
+#gen_list.h: *                your option) any later version.
+#gen_list.h: *
+#gen_list.h: *                This program is distributed in the hope that it will
+#gen_list.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#gen_list.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#gen_list.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#gen_list.h: *                License for more details.
+#gen_list.h: *
+#gen_list.h: *                The GNU General Public License should be included with
+#gen_list.h: *                this file.  If not, you can view it at
+#gen_list.h: *                http://www.gnu.org/copyleft/gpl.html
+#gen_list.h: *                or write to the Free Software Foundation, Inc., 59
+#gen_list.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#gen_list.h: *
+#gen_list.h: * VI users                :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#gen_list.h: *                                         and edit IJB, correctly.
+#gen_list.h: *
+#gen_list.h: * Revisions   :
+#gen_list.h: *    $Log: contrib.sh,v $
+#gen_list.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#gen_list.h: *    name change related issues
+#gen_list.h: *
+#gen_list.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#gen_list.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#gen_list.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#gen_list.h: *    contrib directory and I cannot upload a tarball ... it gets
+#gen_list.h: *    corrupted).  This script will expand all files needed to create the
+#gen_list.h: *    linked list modules and an example program.  Please see the README.
+#gen_list.h: *    Feed back is welcomed.  Enjoy.
+#gen_list.h: *
+#gen_list.h: *
+#gen_list.h: *********************************************************************/
+#gen_list.h:\f
+#gen_list.h:
+#gen_list.h:#ifdef __cplusplus
+#gen_list.h:extern "C" {
+#gen_list.h:#endif
+#gen_list.h:
+#gen_list.h:#include "isa.h"
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:extern int list_is_quiet;
+#gen_list.h:
+#gen_list.h:#define LIST_SHOW(stmt)  if ( ! list_is_quiet ) { stmt; }
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:struct gen_list_rec;
+#gen_list.h:typedef struct gen_list_rec *                      (*rec_copy_construct)( struct gen_list_rec *copy_rec );
+#gen_list.h:typedef struct gen_list_rec *                      (*rec_destruct)( struct gen_list_rec *this_rec );
+#gen_list.h:typedef const struct gen_list_rec *        (*rec_stream)( const struct gen_list_rec *this_rec );
+#gen_list.h:typedef int                                                                        (*rec_equal)( const struct gen_list_rec *this_rec, const struct gen_list_rec *eq_rec );
+#gen_list.h:typedef struct gen_list_rec *                      (*rec_iterate)( struct gen_list_rec *this_rec );
+#gen_list.h:
+#gen_list.h:typedef void * (*rec_method)( void *this_rec, ... );
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:enum VT_ENTRIES
+#gen_list.h:{
+#gen_list.h:   VT_REC_COPY_CONSTRUCT,
+#gen_list.h:   VT_REC_DESTRUCT,
+#gen_list.h:   VT_REC_STREAM,
+#gen_list.h:   VT_REC_EQUAL,
+#gen_list.h:   VT_REC_MAX
+#gen_list.h:};
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:typedef const rec_method *t_vtable;
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:struct gen_list_rec
+#gen_list.h:{
+#gen_list.h:   /* private: */
+#gen_list.h:   t_vtable vtable;
+#gen_list.h:   enum GEN_LIST_ISA isa;
+#gen_list.h:   int sizeof_rec;
+#gen_list.h:   /* contents HERE */
+#gen_list.h:};
+#gen_list.h:/* public: */
+#gen_list.h:extern struct gen_list_rec *                       gen_list_rec_construct( enum GEN_LIST_ISA isa, int sizeof_rec, const t_vtable _vtable );
+#gen_list.h:extern struct gen_list_rec *                       gen_list_rec_copy_construct( const struct gen_list_rec *this_rec );
+#gen_list.h:extern struct gen_list_rec *                       gen_list_rec_destruct( struct gen_list_rec *this_rec );
+#gen_list.h:extern const struct gen_list_rec * gen_list_rec_stream( const struct gen_list_rec *this_rec );
+#gen_list.h:extern int                                                                 gen_list_rec_equal( const struct gen_list_rec *this_rec, const struct gen_list_rec *eq_rec );
+#gen_list.h:
+#gen_list.h:/* struct/class COMPLETE */
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:/*\f*********************************************************************/
+#gen_list.h:
+#gen_list.h:/* private: to gen_list */
+#gen_list.h:struct gen_list_node;
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:struct gen_list
+#gen_list.h:{
+#gen_list.h:   /* private: */
+#gen_list.h:   struct gen_list_node *first;
+#gen_list.h:   struct gen_list_node *last;
+#gen_list.h:};
+#gen_list.h:/* gen_list_insert_node */
+#gen_list.h:
+#gen_list.h:/* public: */
+#gen_list.h:extern struct gen_list *                           gen_list_construct();
+#gen_list.h:extern struct gen_list *                           gen_list_copy_construct( const struct gen_list *this_list );
+#gen_list.h:extern struct gen_list *                           gen_list_destruct( struct gen_list *this_list );
+#gen_list.h:extern struct gen_list *                           gen_list_remove_all( struct gen_list *this_list );
+#gen_list.h:extern struct gen_list_rec *                       gen_list_remove( struct gen_list *this_list, struct gen_list_rec *_rec );
+#gen_list.h:extern struct gen_list_rec *                       gen_list_get_first( const struct gen_list *this_list );
+#gen_list.h:extern struct gen_list_rec *                       gen_list_get_last( const struct gen_list *this_list );
+#gen_list.h:extern const struct gen_list_node *        gen_list_insert( struct gen_list *this_list, struct gen_list_rec *_rec );
+#gen_list.h:extern const struct gen_list *             gen_list_stream( const struct gen_list *this_list );
+#gen_list.h:extern int                                                                 gen_list_equal( const struct gen_list *this_list, const struct gen_list *eq_list );
+#gen_list.h:extern struct gen_list_rec *                       gen_list_find( const struct gen_list *this_list, struct gen_list_rec *rec );
+#gen_list.h:extern struct gen_list_rec *                       gen_list_iterate( struct gen_list *this_list, rec_iterate iter );
+#gen_list.h:/* struct/class COMPLETE */
+#gen_list.h:
+#gen_list.h:
+#gen_list.h:#ifdef __cplusplus
+#gen_list.h:} /* extern "C" */
+#gen_list.h:#endif
+#gen_list.h:
+#gen_list.h:#endif /* ndef GEN_LIST_H_INCLUDED */
+#gen_list.h:
+#gen_list.h:/*
+#gen_list.h:  Local Variables:
+#gen_list.h:  tab-width: 3
+#gen_list.h:  end:
+#gen_list.h:*/
+
+
+#isa.c:const char isa_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#isa.c:/*********************************************************************
+#isa.c: *
+#isa.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#isa.c: *
+#isa.c: * Purpose     :  Pronounced "is a".  To create "english" translations
+#isa.c: *                                              for all linked "classes".
+#isa.c: *
+#isa.c: *                                              NOTE:   this header file must appear once and only once
+#isa.c: *                                                              per project.
+#isa.c: *
+#isa.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#isa.c: *                Privoxy team. http://www.privoxy.org/
+#isa.c: *
+#isa.c: *                This program is free software; you can redistribute it
+#isa.c: *                and/or modify it under the terms of the GNU General
+#isa.c: *                Public License as published by the Free Software
+#isa.c: *                Foundation; either version 2 of the License, or (at
+#isa.c: *                your option) any later version.
+#isa.c: *
+#isa.c: *                This program is distributed in the hope that it will
+#isa.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#isa.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#isa.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#isa.c: *                License for more details.
+#isa.c: *
+#isa.c: *                The GNU General Public License should be included with
+#isa.c: *                this file.  If not, you can view it at
+#isa.c: *                http://www.gnu.org/copyleft/gpl.html
+#isa.c: *                or write to the Free Software Foundation, Inc., 59
+#isa.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#isa.c: *
+#isa.c: * VI users             :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#isa.c: *                                              and edit IJB, correctly.
+#isa.c: *
+#isa.c: * Revisions   :
+#isa.c: *    $Log: contrib.sh,v $
+#isa.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#isa.c: *    name change related issues
+#isa.c: *
+#isa.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#isa.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#isa.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#isa.c: *    contrib directory and I cannot upload a tarball ... it gets
+#isa.c: *    corrupted).  This script will expand all files needed to create the
+#isa.c: *    linked list modules and an example program.  Please see the README.
+#isa.c: *    Feed back is welcomed.  Enjoy.
+#isa.c: *
+#isa.c: *    Revision 1.1  2001/11/30 21:55:51  rodney
+#isa.c: *    Initial revision
+#isa.c: *
+#isa.c: *
+#isa.c: *********************************************************************/
+#isa.c:\f
+#isa.c:
+#isa.c:#include <malloc.h>
+#isa.c:#include <stdio.h>
+#isa.c:#include <stdlib.h>
+#isa.c:#include <string.h>
+#isa.c:
+#isa.c:#include "gen_list.h"
+#isa.c:#include "isa.h"
+#isa.c:
+#isa.c:const char isa_h_rcs[] = ISA_H_VERSION;
+#isa.c:
+#isa.c:
+#isa.c:/* Pronounce "ra" phonectically and you get "array", which this variable is. */
+#isa.c:char *isa_ra[] =
+#isa.c:{
+#isa.c:        "GEN_LIST_REC",
+#isa.c:        "REC_MALLOC_POLICE",
+#isa.c:        "REC_CHAR",
+#isa.c:        "REC_CHARPTR",
+#isa.c:        "REC_DOUBLE",
+#isa.c:        "REC_LONG",
+#isa.c:        NULL
+#isa.c:};
+
+
+#isa.h:#ifndef ISA_H_INCLUDED
+#isa.h:#define ISA_H_INCLUDED
+#isa.h:#define ISA_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#isa.h:/*********************************************************************
+#isa.h: *
+#isa.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#isa.h: *
+#isa.h: * Purpose     :  Pronounced "is a".  To create "english" translations
+#isa.h: *                                              for all linked "classes".
+#isa.h: *
+#isa.h: *                                              NOTE:   this header file must appear once and only once
+#isa.h: *                                                              per project.
+#isa.h: *
+#isa.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#isa.h: *                Privoxy team. http://www.privoxy.org/
+#isa.h: *
+#isa.h: *                This program is free software; you can redistribute it
+#isa.h: *                and/or modify it under the terms of the GNU General
+#isa.h: *                Public License as published by the Free Software
+#isa.h: *                Foundation; either version 2 of the License, or (at
+#isa.h: *                your option) any later version.
+#isa.h: *
+#isa.h: *                This program is distributed in the hope that it will
+#isa.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#isa.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#isa.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#isa.h: *                License for more details.
+#isa.h: *
+#isa.h: *                The GNU General Public License should be included with
+#isa.h: *                this file.  If not, you can view it at
+#isa.h: *                http://www.gnu.org/copyleft/gpl.html
+#isa.h: *                or write to the Free Software Foundation, Inc., 59
+#isa.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#isa.h: *
+#isa.h: * VI users             :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#isa.h: *                                              and edit IJB, correctly.
+#isa.h: *
+#isa.h: * Revisions   :
+#isa.h: *    $Log: contrib.sh,v $
+#isa.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#isa.h: *    name change related issues
+#isa.h: *
+#isa.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#isa.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#isa.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#isa.h: *    contrib directory and I cannot upload a tarball ... it gets
+#isa.h: *    corrupted).  This script will expand all files needed to create the
+#isa.h: *    linked list modules and an example program.  Please see the README.
+#isa.h: *    Feed back is welcomed.  Enjoy.
+#isa.h: *
+#isa.h: *
+#isa.h: *********************************************************************/
+#isa.h:\f
+#isa.h:
+#isa.h:#ifdef __cplusplus
+#isa.h:extern "C" {
+#isa.h:#endif
+#isa.h:
+#isa.h:
+#isa.h:enum GEN_LIST_ISA
+#isa.h:{
+#isa.h:        ISA_GEN_LIST_REC,
+#isa.h:        ISA_MALLOC_POLICE,
+#isa.h:        ISA_CHAR,
+#isa.h:        ISA_CHARPTR,
+#isa.h:        ISA_DOUBLE,
+#isa.h:        ISA_LONG,
+#isa.h:        ISA_MAX
+#isa.h:};
+#isa.h:
+#isa.h:
+#isa.h:/* Pronounce "ra" phonectically and you get "array", which this variable is. */
+#isa.h:extern char *isa_ra[];
+#isa.h:
+#isa.h:
+#isa.h:#ifdef __cplusplus
+#isa.h:} /* extern "C" */
+#isa.h:#endif
+#isa.h:
+#isa.h:#endif /* ndef ISA_H_INCLUDED */
+#isa.h:
+#isa.h:/*
+#isa.h:  Local Variables:
+#isa.h:  tab-width: 3
+#isa.h:  end:
+#isa.h:*/
+
+
+#main.c:const char main_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#main.c:/*********************************************************************
+#main.c: *
+#main.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#main.c: *
+#main.c: * Purpose     :  To test "generic list" creation and manipulation.
+#main.c: *
+#main.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#main.c: *                Privoxy team. http://www.privoxy.org/
+#main.c: *
+#main.c: *                This program is free software; you can redistribute it
+#main.c: *                and/or modify it under the terms of the GNU General
+#main.c: *                Public License as published by the Free Software
+#main.c: *                Foundation; either version 2 of the License, or (at
+#main.c: *                your option) any later version.
+#main.c: *
+#main.c: *                This program is distributed in the hope that it will
+#main.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#main.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#main.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#main.c: *                License for more details.
+#main.c: *
+#main.c: *                The GNU General Public License should be included with
+#main.c: *                this file.  If not, you can view it at
+#main.c: *                http://www.gnu.org/copyleft/gpl.html
+#main.c: *                or write to the Free Software Foundation, Inc., 59
+#main.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#main.c: *
+#main.c: * VI users            :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#main.c: *                                             and edit IJB, correctly.
+#main.c: *
+#main.c: * Note                        :       This output assumes (per IJB standards) that tabs are
+#main.c: *                                             set to 3 characters.  If you run this in a terminal,
+#main.c: *                                             you may want to run this as so:
+#main.c: *                                                     >./test_list 2>&1 | expand -t3 | ./addr_clean.pl
+#main.c: *                                             This will expand the tab to 3 columns and then replace
+#main.c: *                                             "0x" style addresses with more human readable ones.
+#main.c: *
+#main.c: * Revisions   :
+#main.c: *    $Log: contrib.sh,v $
+#main.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#main.c: *    name change related issues
+#main.c: *
+#main.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#main.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#main.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#main.c: *    contrib directory and I cannot upload a tarball ... it gets
+#main.c: *    corrupted).  This script will expand all files needed to create the
+#main.c: *    linked list modules and an example program.  Please see the README.
+#main.c: *    Feed back is welcomed.  Enjoy.
+#main.c: *
+#main.c: *
+#main.c: *********************************************************************/
+#main.c:\f
+#main.c:
+#main.c:#include <malloc.h>
+#main.c:#include <stdio.h>
+#main.c:#include <stdlib.h>
+#main.c:#include <string.h>
+#main.c:
+#main.c:#include "gen_list.h"
+#main.c:#include "rec_char.h"
+#main.c:#include "rec_charptr.h"
+#main.c:#include "rec_double.h"
+#main.c:#include "rec_long.h"
+#main.c:#include "malloc_police.h"
+#main.c:
+#main.c:
+#main.c:extern const char isa_rcs[];
+#main.c:extern const char isa_h_rcs[];
+#main.c:extern const char gen_list_rcs[];
+#main.c:extern const char gen_list_h_rcs[];
+#main.c:extern const char malloc_police_rcs[];
+#main.c:extern const char malloc_police_h_rcs[];
+#main.c:extern const char rec_charptr_rcs[];
+#main.c:extern const char rec_charptr_h_rcs[];
+#main.c:extern const char rec_long_rcs[];
+#main.c:extern const char rec_long_h_rcs[];
+#main.c:extern const char rec_double_rcs[];
+#main.c:extern const char rec_double_h_rcs[];
+#main.c:extern const char rec_char_rcs[];
+#main.c:extern const char rec_char_h_rcs[];
+#main.c:extern const char rec_malloc_police_rcs[];
+#main.c:extern const char rec_malloc_police_h_rcs[];
+#main.c:extern const char main_rcs[];
+#main.c:
+#main.c:
+#main.c:/*********************************************************************
+#main.c: *
+#main.c: * Function    :  my_custom_charptr_iterator_1
+#main.c: *
+#main.c: * Description :  This funtion is called once for every record in a
+#main.c: *                                             list.  Or at least until we return non-NULL.  BTW,
+#main.c: *                                             this function always returns NULL, thus it will
+#main.c: *                                             iterate over the entire list.
+#main.c: *
+#main.c: * Parameters  :
+#main.c: *          1  :  The record.
+#main.c: *
+#main.c: * Returns     :  NULL
+#main.c: *
+#main.c: *********************************************************************/
+#main.c:struct derived_rec_charptr *my_custom_charptr_iterator_1( struct derived_rec_charptr *this_rec )
+#main.c:{
+#main.c:       printf( "\
+#main.c:\t\tcharptr iterator_1 this_rec\t\t\t\t= iter_1 ... %p
+#main.c:\t\tcharptr iterator_1 this_rec->contents\t= iter_1 ... %s\n\n", (const void *)this_rec, this_rec->contents );
+#main.c:       return( NULL );
+#main.c:
+#main.c:}
+#main.c:
+#main.c:
+#main.c:/*********************************************************************
+#main.c: *
+#main.c: * Function    :  my_custom_charptr_iterator_2
+#main.c: *
+#main.c: * Description :  This funtion is called once for every record in a
+#main.c: *                                             list.  Or at least until we return non-NULL.  BTW,
+#main.c: *                                             this function always returns non-NULL, thus it will
+#main.c: *                                             iterate over only 1 record.
+#main.c: *
+#main.c: * Parameters  :
+#main.c: *          1  :  The record.
+#main.c: *
+#main.c: * Returns     :  The record.
+#main.c: *
+#main.c: *********************************************************************/
+#main.c:struct derived_rec_charptr *my_custom_charptr_iterator_2( struct derived_rec_charptr *this_rec )
+#main.c:{
+#main.c:       printf( "\
+#main.c:\t\tcharptr iterator_1 this_rec\t\t\t\t= iter_2 ... %p
+#main.c:\t\tcharptr iterator_1 this_rec->contents\t= iter_2 ... %s\n\n", (const void *)this_rec, this_rec->contents );
+#main.c:       return( this_rec );
+#main.c:
+#main.c:}
+#main.c:
+#main.c:
+#main.c:/*********************************************************************
+#main.c: *
+#main.c: * Function    :  main
+#main.c: *
+#main.c: * Description :  Test the doubly linked list as it is so far.
+#main.c: *
+#main.c: * Parameters  :  None
+#main.c: *
+#main.c: * Returns     :  N/A
+#main.c: *
+#main.c: *********************************************************************/
+#main.c:int main( int argc, const char **argv )
+#main.c:{
+#main.c:       struct gen_list *lcharptr;
+#main.c:       struct gen_list *llong;
+#main.c:       struct gen_list *ldouble;
+#main.c:       struct gen_list *lchar;
+#main.c:
+#main.c:       struct gen_list *lcharptr_c;
+#main.c:       struct gen_list *llong_c;
+#main.c:       struct gen_list *ldouble_c;
+#main.c:       struct gen_list *lchar_c;
+#main.c:
+#main.c:       struct gen_list_rec *f_rec;
+#main.c:
+#main.c:       struct gen_list *no_own_list;
+#main.c:       struct gen_list_rec *no_own_rec1;
+#main.c:       struct gen_list_rec *no_own_rec2;
+#main.c:       struct gen_list_rec *no_own_rec3;
+#main.c:
+#main.c:       printf( "\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n\n",
+#main.c:                         gen_list_rcs,
+#main.c:                         gen_list_h_rcs,
+#main.c:                         isa_rcs,
+#main.c:                         isa_h_rcs,
+#main.c:                         malloc_police_rcs,
+#main.c:                         malloc_police_h_rcs,
+#main.c:                         rec_char_rcs,
+#main.c:                         rec_char_h_rcs,
+#main.c:                         rec_charptr_rcs,
+#main.c:                         rec_charptr_h_rcs,
+#main.c:                         rec_long_rcs,
+#main.c:                         rec_long_h_rcs,
+#main.c:                         rec_double_rcs,
+#main.c:                         rec_double_h_rcs,
+#main.c:                         rec_malloc_police_rcs,
+#main.c:                         rec_malloc_police_h_rcs,
+#main.c:                         main_rcs );
+#main.c:
+#main.c:
+#main.c:       /* Force a memory leak to test the strdup/malloc/free police. */
+#main.c:       /* NOTE: this should trigger the alphanum check of allocated memory. */
+#main.c:       strcpy( MALLOC( 60 ), "Force a memory leak to test the strdup/malloc/free police." );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_construct to constuct a charptr list -- **\n" );
+#main.c:       lcharptr = gen_list_construct();
+#main.c:
+#main.c:       gen_list_insert( lcharptr, (struct gen_list_rec *)derived_rec_charptr_construct( "Rodney Stromlund" ) );
+#main.c:       gen_list_insert( lcharptr, f_rec = (struct gen_list_rec *)derived_rec_charptr_construct( "RJS" ) );
+#main.c:       gen_list_insert( lcharptr, (struct gen_list_rec *)derived_rec_charptr_construct( "jammin!" ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to test streaming a charptr list -- **\n" );
+#main.c:       gen_list_stream( lcharptr );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_find to find the 2nd charptr record -- **\n" );
+#main.c:       f_rec = gen_list_find( lcharptr, f_rec );
+#main.c:       printf( "Found rec = %p\n", f_rec );
+#main.c:       derived_rec_charptr_stream( (const struct derived_rec_charptr *)f_rec );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_copy_construct to test copy construct the charptr list -- **\n" );
+#main.c:       lcharptr_c = gen_list_copy_construct( lcharptr );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_equal to see if the copied list is the same as the orig -- **
+#main.c:** -- NOTE: they will NOT be because the charptr copy constructor changes the string contents -- **\n" );
+#main.c:       printf( "Are these 2 equal? => %d\n\n", gen_list_equal( lcharptr, lcharptr_c ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to stream a copied charptr list -- **\n" );
+#main.c:       gen_list_stream( lcharptr_c );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_construct to constuct a long list -- **\n" );
+#main.c:       llong = gen_list_construct();
+#main.c:
+#main.c:
+#main.c:       gen_list_insert( llong, no_own_rec1 = (struct gen_list_rec *)derived_rec_long_construct( 1 ) );
+#main.c:       gen_list_insert( llong, no_own_rec2 = (struct gen_list_rec *)derived_rec_long_construct( 100 ) );
+#main.c:       gen_list_insert( llong, no_own_rec3 = (struct gen_list_rec *)derived_rec_long_construct( 200 ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to test streaming a long list -- **\n" );
+#main.c:       gen_list_stream( llong );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_copy_construct to test copy construct the long list -- **\n" );
+#main.c:       llong_c = gen_list_copy_construct( llong );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to stream a copied long list -- **\n" );
+#main.c:       gen_list_stream( llong_c );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_construct to test a no-owner long list -- **\n" );
+#main.c:       no_own_list = gen_list_construct();
+#main.c:       gen_list_insert( no_own_list, no_own_rec1 );
+#main.c:       gen_list_insert( no_own_list, no_own_rec2 );
+#main.c:       gen_list_insert( no_own_list, no_own_rec3 );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to stream a no-owner list -- **\n" );
+#main.c:       gen_list_stream( no_own_list );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_equal to see if list and no-owner list are equal  NOTE: they should be. -- **\n" );
+#main.c:       printf( "Are these 2 equal? => %d\n\n", gen_list_equal( llong, no_own_list ) );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_construct to constuct a double list -- **\n" );
+#main.c:       ldouble = gen_list_construct();
+#main.c:
+#main.c:       gen_list_insert( ldouble, (struct gen_list_rec *)derived_rec_double_construct( 3.0 ) );
+#main.c:       gen_list_insert( ldouble, (struct gen_list_rec *)derived_rec_double_construct( 3.1 ) );
+#main.c:       gen_list_insert( ldouble, (struct gen_list_rec *)derived_rec_double_construct( 3.14 ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to test streaming a double list -- **\n" );
+#main.c:       gen_list_stream( ldouble );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_copy_construct to test copy construct the double list -- **\n" );
+#main.c:       ldouble_c = gen_list_copy_construct( ldouble );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to stream a copied double list -- **\n" );
+#main.c:       gen_list_stream( ldouble_c );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_construct to constuct a char list -- **\n" );
+#main.c:       lchar = gen_list_construct();
+#main.c:
+#main.c:       gen_list_insert( lchar, (struct gen_list_rec *)derived_rec_char_construct( '1' ) );
+#main.c:       gen_list_insert( lchar, (struct gen_list_rec *)derived_rec_char_construct( 'A' ) );
+#main.c:       gen_list_insert( lchar, (struct gen_list_rec *)derived_rec_char_construct( 'a' ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to test streaming a char list -- **\n" );
+#main.c:       gen_list_stream( lchar );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_copy_construct to test copy construct the char list -- **\n" );
+#main.c:       lchar_c = gen_list_copy_construct( lchar );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_equal to see if the copied list is the same as the orig  NOTE: they should be. -- **\n" );
+#main.c:       printf( "Are these 2 equal? => %d\n\n", gen_list_equal( lchar, lchar_c ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_stream to stream a copied char list -- **\n" );
+#main.c:       gen_list_stream( lchar_c );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_iterate to iterate a charptr list -- **
+#main.c:** -- NOTE: this iterator (my_custom_charptr_iterator_1) will iterate the whole list. -- **\n" );
+#main.c:       gen_list_iterate( lcharptr,     (rec_iterate)my_custom_charptr_iterator_1 );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_iterate to iterate a copied charptr list -- **
+#main.c:** -- NOTE: this iterator (my_custom_charptr_iterator_2) will return after the first iteration. -- **\n" );
+#main.c:       gen_list_iterate( lcharptr_c,   (rec_iterate)my_custom_charptr_iterator_2 );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_iterate_reverse to iterate a charptr list -- **
+#main.c:** -- NOTE: this iterator (my_custom_charptr_iterator_1) will iterate the whole list. -- **\n" );
+#main.c:       gen_list_iterate_reverse( lcharptr,     (rec_iterate)my_custom_charptr_iterator_1 );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_iterate_reverse to iterate a copied charptr list -- **
+#main.c:** -- NOTE: this iterator (my_custom_charptr_iterator_2) will return after the first iteration. -- **\n" );
+#main.c:       gen_list_iterate_reverse( lcharptr_c,   (rec_iterate)my_custom_charptr_iterator_2 );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_equal to see if 2 different typed lists are equal  NOTE: they should not be. -- **\n" );
+#main.c:       printf( "Are these 2 equal? => %d\n\n", gen_list_equal( lcharptr, llong ) );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_remove_all to erase a no-owner list -- **\n" );
+#main.c:       no_own_list = gen_list_remove_all( no_own_list );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct a no-owner list -- **\n" );
+#main.c:       no_own_list = gen_list_destruct( no_own_list );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_remove to remove the first record of a copied charptr list -- **\n" );
+#main.c:       derived_rec_charptr_destruct( (struct derived_rec_charptr *)gen_list_remove( lcharptr_c, gen_list_get_first( lcharptr_c ) ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_remove to remove the last record of a copied long list -- **\n" );
+#main.c:       derived_rec_long_destruct( (struct derived_rec_long *)gen_list_remove( llong_c, gen_list_get_last( llong_c ) ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_remove to remove the middle record of an original charptr list -- **\n" );
+#main.c:       derived_rec_charptr_destruct( (struct derived_rec_charptr *)gen_list_remove( lcharptr, f_rec ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_remove to remove the all 3 records of a copied char list (first to last) -- **\n" );
+#main.c:       derived_rec_char_destruct( (struct derived_rec_char *)gen_list_remove( lchar_c, gen_list_get_first( lchar_c ) ) );
+#main.c:       derived_rec_char_destruct( (struct derived_rec_char *)gen_list_remove( lchar_c, gen_list_get_first( lchar_c ) ) );
+#main.c:       derived_rec_char_destruct( (struct derived_rec_char *)gen_list_remove( lchar_c, gen_list_get_first( lchar_c ) ) );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_remove to remove the all 3 records of the original char list (last to first) -- **\n" );
+#main.c:       derived_rec_char_destruct( (struct derived_rec_char *)gen_list_remove( lchar, gen_list_get_last( lchar ) ) );
+#main.c:       derived_rec_char_destruct( (struct derived_rec_char *)gen_list_remove( lchar, gen_list_get_last( lchar ) ) );
+#main.c:       derived_rec_char_destruct( (struct derived_rec_char *)gen_list_remove( lchar, gen_list_get_last( lchar ) ) );
+#main.c:
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the original charptr list (less the middle record) -- **\n" );
+#main.c:       lcharptr = gen_list_destruct( lcharptr );
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the copied charptr list (less the first record) -- **\n" );
+#main.c:       lcharptr_c = gen_list_destruct( lcharptr_c );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the original long list -- **\n" );
+#main.c:       llong = gen_list_destruct( llong );
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the copied long list (less the last record) -- **\n" );
+#main.c:       llong_c = gen_list_destruct( llong_c );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the original double list -- **\n" );
+#main.c:       ldouble = gen_list_destruct( ldouble );
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the copied double list -- **\n" );
+#main.c:       ldouble_c = gen_list_destruct( ldouble_c );
+#main.c:
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the original char list (less all records last to first) -- **\n" );
+#main.c:       lchar = gen_list_destruct( lchar );
+#main.c:       printf( "** -- Calling gen_list_destruct to destruct the copied char list (less all records first to last) -- **\n" );
+#main.c:       lchar_c = gen_list_destruct( lchar_c );
+#main.c:
+#main.c:
+#main.c:       /* Force another memory leak to test the strdup/malloc/free police. */
+#main.c:       /* NOTE: this should trigger the alphanum check of allocated memory. */
+#main.c:       STRDUP( "Force another memory leak to test the strdup/malloc/free police." );
+#main.c:
+#main.c:       /* Force a memory leak in a list and also in 2 nodes. */
+#main.c:       /* NOTE: this should NOT trigger the alphanum check of allocated memory. */
+#main.c:       gen_list_construct();
+#main.c:
+#main.c:       /* NOTE: this should trigger 1 NON check (for the node) */
+#main.c:       /* followed by 1 alphanum check for the charptr string. */
+#main.c:       derived_rec_charptr_construct( "Leaky charptr node." );
+#main.c:
+#main.c:       /* NOTE: this should NOT trigger the alphanum check of allocated memory. */
+#main.c:       derived_rec_char_construct( 'Z' );
+#main.c:
+#main.c:
+#main.c:       printf( "\ndone" );
+#main.c:       return( 0 );
+#main.c:
+#main.c:}
+#main.c:
+#main.c:
+#main.c:/*
+#main.c:  Local Variables:
+#main.c:  tab-width: 3
+#main.c:  end:
+#main.c:*/
+
+
+#malloc_police.c:const char malloc_police_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#malloc_police.c:/*********************************************************************
+#malloc_police.c: *
+#malloc_police.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#malloc_police.c: *
+#malloc_police.c: * Purpose     :  This module uses the rec_malloc_police to build a
+#malloc_police.c: *                                            list of allocated and freed memory.  When the
+#malloc_police.c: *                                            program exits, we will print a list of all memory
+#malloc_police.c: *                                            that was allocated, but never freed.  This could
+#malloc_police.c: *                                            be most helpful to developers and debugers.
+#malloc_police.c: *
+#malloc_police.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#malloc_police.c: *                Privoxy team. http://www.privoxy.org/
+#malloc_police.c: *
+#malloc_police.c: *                This program is free software; you can redistribute it
+#malloc_police.c: *                and/or modify it under the terms of the GNU General
+#malloc_police.c: *                Public License as published by the Free Software
+#malloc_police.c: *                Foundation; either version 2 of the License, or (at
+#malloc_police.c: *                your option) any later version.
+#malloc_police.c: *
+#malloc_police.c: *                This program is distributed in the hope that it will
+#malloc_police.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#malloc_police.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#malloc_police.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#malloc_police.c: *                License for more details.
+#malloc_police.c: *
+#malloc_police.c: *                The GNU General Public License should be included with
+#malloc_police.c: *                this file.  If not, you can view it at
+#malloc_police.c: *                http://www.gnu.org/copyleft/gpl.html
+#malloc_police.c: *                or write to the Free Software Foundation, Inc., 59
+#malloc_police.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#malloc_police.c: *
+#malloc_police.c: * VI users           :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#malloc_police.c: *                                            and edit IJB, correctly.
+#malloc_police.c: *
+#malloc_police.c: * Revisions   :
+#malloc_police.c: *    $Log: contrib.sh,v $
+#malloc_police.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#malloc_police.c: *    name change related issues
+#malloc_police.c: *
+#malloc_police.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#malloc_police.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#malloc_police.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#malloc_police.c: *    contrib directory and I cannot upload a tarball ... it gets
+#malloc_police.c: *    corrupted).  This script will expand all files needed to create the
+#malloc_police.c: *    linked list modules and an example program.  Please see the README.
+#malloc_police.c: *    Feed back is welcomed.  Enjoy.
+#malloc_police.c: *
+#malloc_police.c: *
+#malloc_police.c: *********************************************************************/
+#malloc_police.c:\f
+#malloc_police.c:
+#malloc_police.c:#include <ctype.h>
+#malloc_police.c:#include <malloc.h>
+#malloc_police.c:#include <stdio.h>
+#malloc_police.c:#include <stdlib.h>
+#malloc_police.c:#include <string.h>
+#malloc_police.c:
+#malloc_police.c:#include "gen_list.h"
+#malloc_police.c:#include "malloc_police.h"
+#malloc_police.c:#include "rec_malloc_police.h"
+#malloc_police.c:
+#malloc_police.c:const char malloc_police_h_rcs[] = MALLOC_POLICE_H_VERSION;
+#malloc_police.c:
+#malloc_police.c:
+#malloc_police.c:/* When we need to allocate malloc_police records, we */
+#malloc_police.c:/* will do recursion infinately.  This variable will */
+#malloc_police.c:/* stop the STRDUP, MALLOC, and FREE replacements from */
+#malloc_police.c:/* trying to log these allocations. */
+#malloc_police.c:
+#malloc_police.c:char recursion_protect = 0;
+#malloc_police.c:
+#malloc_police.c:struct gen_list *get_police_list();
+#malloc_police.c:static char called_once = 0;
+#malloc_police.c:static const char *leak_report_header = "%s****************************** MEMORY LEAK REPORT %s ******************************%s";
+#malloc_police.c:
+#malloc_police.c:
+#malloc_police.c:/*********************************************************************
+#malloc_police.c: *
+#malloc_police.c: * Function    :  police_list_release_iterator
+#malloc_police.c: *
+#malloc_police.c: * Description :  Iterator for the police list.  We will report
+#malloc_police.c: *                                            "leaked" memory for the developer to correct.
+#malloc_police.c: *
+#malloc_police.c: * Parameters  :
+#malloc_police.c: *          1  :  The record.
+#malloc_police.c: *
+#malloc_police.c: * Returns     :  NULL
+#malloc_police.c: *
+#malloc_police.c: *********************************************************************/
+#malloc_police.c:struct derived_rec_malloc_police *police_list_release_iterator( struct derived_rec_malloc_police *this_rec )
+#malloc_police.c:{
+#malloc_police.c:      if ( ! called_once )
+#malloc_police.c:      {
+#malloc_police.c:              called_once = 1;
+#malloc_police.c:              fprintf( stderr, leak_report_header, "\n\n", "BEGIN", "\n\n" );
+#malloc_police.c:      }
+#malloc_police.c:
+#malloc_police.c:      fprintf( stderr, "\
+#malloc_police.c:\t\tmalloc_police leaked memory iterator this_rec\t\t\t\t\t= %p
+#malloc_police.c:\t\tmalloc_police leaked memory iterator this_rec->alloced_addr\t= %p
+#malloc_police.c:\t\tmalloc_police leaked memory iterator this_rec->source_where\t= %s
+#malloc_police.c:\t\tmalloc_police leaked memory iterator this_rec->sz\t\t\t\t= %ld\n",
+#malloc_police.c:                              (const void *)this_rec,
+#malloc_police.c:                              this_rec->alloced_addr,
+#malloc_police.c:                              this_rec->source_where,
+#malloc_police.c:                              this_rec->sz
+#malloc_police.c:      );
+#malloc_police.c:
+#malloc_police.c:      if (
+#malloc_police.c:              this_rec->sz >= 3 &&
+#malloc_police.c:              isalnum( ((const char *)this_rec->alloced_addr)[ 0 ] ) &&
+#malloc_police.c:              isalnum( ((const char *)this_rec->alloced_addr)[ 1 ] ) &&
+#malloc_police.c:              isalnum( ((const char *)this_rec->alloced_addr)[ 2 ] ) )
+#malloc_police.c:      {
+#malloc_police.c:              /* If the memory starts with 3 alpha-numerics,
+#malloc_police.c:               * assume a string was allocated.  This might be
+#malloc_police.c:               * a little dangerous for production code, but I
+#malloc_police.c:               * will take the risk for development payoff
+#malloc_police.c:               * (at least for now ...) */
+#malloc_police.c:                      
+#malloc_police.c:              fprintf( stderr, "\
+#malloc_police.c:\t\tAlpha numeric found, assuming a string was allocated\t\t\t= %s\n",
+#malloc_police.c:                                      this_rec->alloced_addr
+#malloc_police.c:              );
+#malloc_police.c:      }
+#malloc_police.c:
+#malloc_police.c:      fprintf( stderr, "\n" );
+#malloc_police.c:
+#malloc_police.c:      return( NULL );
+#malloc_police.c:
+#malloc_police.c:}
+#malloc_police.c:
+#malloc_police.c:
+#malloc_police.c:/*********************************************************************
+#malloc_police.c: *
+#malloc_police.c: * Function    :  release_police_list
+#malloc_police.c: *
+#malloc_police.c: * Description :  Iterates the police_list and reports "leaked" memory.
+#malloc_police.c: *                                            It will then free the list itself.
+#malloc_police.c: *
+#malloc_police.c: * Parameters  :      None
+#malloc_police.c: *
+#malloc_police.c: * Returns     :  None.
+#malloc_police.c: *
+#malloc_police.c: *********************************************************************/
+#malloc_police.c:void release_police_list()
+#malloc_police.c:{
+#malloc_police.c:      struct gen_list *police_list = get_police_list();
+#malloc_police.c:      fflush( stdout );
+#malloc_police.c:      gen_list_iterate( police_list, (rec_iterate)police_list_release_iterator );
+#malloc_police.c:
+#malloc_police.c:      if ( called_once )
+#malloc_police.c:      {
+#malloc_police.c:              called_once = 0;
+#malloc_police.c:              fprintf( stderr, leak_report_header, "", "END", "\n" );
+#malloc_police.c:      }
+#malloc_police.c:
+#malloc_police.c:}
+#malloc_police.c:
+#malloc_police.c:
+#malloc_police.c:/*********************************************************************
+#malloc_police.c: *
+#malloc_police.c: * Function    :  get_police_list
+#malloc_police.c: *
+#malloc_police.c: * Description :  Get the police malloc/strdup/free list.  Generate
+#malloc_police.c: *                                            a new one if it does not yet exist.
+#malloc_police.c: *
+#malloc_police.c: * Parameters  :      None
+#malloc_police.c: *
+#malloc_police.c: * Returns     :  The police list.
+#malloc_police.c: *
+#malloc_police.c: *********************************************************************/
+#malloc_police.c:struct gen_list *get_police_list()
+#malloc_police.c:{
+#malloc_police.c:      static struct gen_list *police_list = NULL;
+#malloc_police.c:
+#malloc_police.c:      if ( NULL == police_list )
+#malloc_police.c:      {
+#malloc_police.c:              recursion_protect ++;
+#malloc_police.c:              list_is_quiet ++;
+#malloc_police.c:
+#malloc_police.c:              police_list = gen_list_construct();
+#malloc_police.c:              atexit( release_police_list );
+#malloc_police.c:
+#malloc_police.c:              recursion_protect --;
+#malloc_police.c:              list_is_quiet --;
+#malloc_police.c:      }
+#malloc_police.c:
+#malloc_police.c:      return( police_list );
+#malloc_police.c:
+#malloc_police.c:}
+#malloc_police.c:
+#malloc_police.c:
+#malloc_police.c:/*********************************************************************
+#malloc_police.c: *
+#malloc_police.c: * Function    :  police_strdup
+#malloc_police.c: *
+#malloc_police.c: * Description :  Save the results of the strdup into our linked list.
+#malloc_police.c: *                                            This will be checked against latter free(s).
+#malloc_police.c: *
+#malloc_police.c: * Parameters  :
+#malloc_police.c: *          1  :  The string to be duplicated.
+#malloc_police.c: *          2  :  Filename where the strdup occured.
+#malloc_police.c: *          3  :  Line# of where the strdup occured.
+#malloc_police.c: *
+#malloc_police.c: * Returns     :  Pointer to newly allocated memory.
+#malloc_police.c: *
+#malloc_police.c: * NOTE                       :       This could replace the custom strdup for __MINGW32__
+#malloc_police.c: *                                            systems.  We only need to copy the conditionally
+#malloc_police.c: *                                            compiled code here and eliminate the strdup copy.
+#malloc_police.c: *
+#malloc_police.c: *********************************************************************/
+#malloc_police.c:char *police_strdup( const char *s, const char *filename, long lineno )
+#malloc_police.c:{
+#malloc_police.c:      char *ret = strdup( s );
+#malloc_police.c:
+#malloc_police.c:      if ( 0 == recursion_protect )
+#malloc_police.c:      {
+#malloc_police.c:              char buffer[ 255 ];
+#malloc_police.c:              sprintf( buffer, "strdup : %s @ %ld for %ld (%s)", filename, lineno, strlen( s ) + 1, s );
+#malloc_police.c:
+#malloc_police.c:              recursion_protect ++;
+#malloc_police.c:              list_is_quiet ++;
+#malloc_police.c:
+#malloc_police.c:              gen_list_insert(
+#malloc_police.c:                      get_police_list(),
+#malloc_police.c:                      (struct gen_list_rec *)derived_rec_malloc_police_construct( ret, buffer, strlen( s ) + 1 )
+#malloc_police.c:              );
+#malloc_police.c:
+#malloc_police.c:              recursion_protect --;
+#malloc_police.c:              list_is_quiet --;
+#malloc_police.c:      }
+#malloc_police.c:
+#malloc_police.c:      return( ret );
+#malloc_police.c:
+#malloc_police.c:}
+#malloc_police.c:
+#malloc_police.c:
+#malloc_police.c:/*********************************************************************
+#malloc_police.c: *
+#malloc_police.c: * Function    :  police_malloc
+#malloc_police.c: *
+#malloc_police.c: * Description :  Save the results of the malloc into our linked list.
+#malloc_police.c: *                                            This will be checked against latter free(s).
+#malloc_police.c: *
+#malloc_police.c: * Parameters  :
+#malloc_police.c: *          1  :  The size of the memory to be malloc(ed).
+#malloc_police.c: *          2  :  Filename where the malloc occured.
+#malloc_police.c: *          3  :  Line# of where the malloc occured.
+#malloc_police.c: *
+#malloc_police.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#malloc_police.c: *
+#malloc_police.c: *********************************************************************/
+#malloc_police.c:void *police_malloc( size_t sz, const char *filename, long lineno )
+#malloc_police.c:{
+#malloc_police.c:      void *ret = malloc( sz );
+#malloc_police.c:
+#malloc_police.c:      if ( 0 == recursion_protect )
+#malloc_police.c:      {
+#malloc_police.c:              char buffer[ 255 ];
+#malloc_police.c:              sprintf( buffer, "malloc : %s @ %ld for %ld", filename, lineno, sz );
+#malloc_police.c:
+#malloc_police.c:              recursion_protect ++;
+#malloc_police.c:              list_is_quiet ++;
+#malloc_police.c:
+#malloc_police.c:              gen_list_insert(
+#malloc_police.c:                      get_police_list(),
+#malloc_police.c:                      (struct gen_list_rec *)derived_rec_malloc_police_construct( ret, buffer, sz )
+#malloc_police.c:              );
+#malloc_police.c:
+#malloc_police.c:              recursion_protect --;
+#malloc_police.c:              list_is_quiet --;
+#malloc_police.c:      }
+#malloc_police.c:
+#malloc_police.c:      return( ret );
+#malloc_police.c:
+#malloc_police.c:}
+#malloc_police.c:
+#malloc_police.c:
+#malloc_police.c:/*********************************************************************
+#malloc_police.c: *
+#malloc_police.c: * Function    :  police_free
+#malloc_police.c: *
+#malloc_police.c: * Description :  Frees the memory allocation and removes the address
+#malloc_police.c: *                                            from the linked list.  Anything left in this list
+#malloc_police.c: *                                            is "leaked" memory.
+#malloc_police.c: *
+#malloc_police.c: * Parameters  :
+#malloc_police.c: *          1  :  Pointer to the memory to be freed.
+#malloc_police.c: *          2  :  Filename where the free occured.
+#malloc_police.c: *          3  :  Line# of where the free occured.
+#malloc_police.c: *
+#malloc_police.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#malloc_police.c: *
+#malloc_police.c: *********************************************************************/
+#malloc_police.c:void police_free( void *ptr, const char *filename, long lineno )
+#malloc_police.c:{
+#malloc_police.c:      if ( 0 == recursion_protect )
+#malloc_police.c:      {
+#malloc_police.c:              struct derived_rec_malloc_police *rec;
+#malloc_police.c:              struct gen_list_rec *fRec;
+#malloc_police.c:              struct gen_list *l = get_police_list();
+#malloc_police.c:
+#malloc_police.c:              recursion_protect ++;
+#malloc_police.c:              list_is_quiet ++;
+#malloc_police.c:
+#malloc_police.c:              rec = derived_rec_malloc_police_construct( ptr, "FREEING POLICE RECORD.", 23 );
+#malloc_police.c:              fRec = gen_list_find( l, (struct gen_list_rec *)rec );
+#malloc_police.c:              derived_rec_malloc_police_destruct( rec );
+#malloc_police.c:
+#malloc_police.c:              if ( NULL == fRec )
+#malloc_police.c:              {
+#malloc_police.c:                      fprintf( stderr, "\nERROR: free failed to find corresponding strdup/malloc : %s @ %ld\n", filename, lineno );
+#malloc_police.c:              }
+#malloc_police.c:              else
+#malloc_police.c:              {
+#malloc_police.c:                      derived_rec_malloc_police_destruct( (struct derived_rec_malloc_police *)gen_list_remove( l, fRec ) );
+#malloc_police.c:              }
+#malloc_police.c:
+#malloc_police.c:              recursion_protect --;
+#malloc_police.c:              list_is_quiet --;
+#malloc_police.c:      }
+#malloc_police.c:
+#malloc_police.c:      free( ptr );
+#malloc_police.c:
+#malloc_police.c:}
+
+
+#malloc_police.h:#ifndef MALLOC_POLICE_H_INCLUDED
+#malloc_police.h:#define MALLOC_POLICE_H_INCLUDED
+#malloc_police.h:#define MALLOC_POLICE_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#malloc_police.h:/*********************************************************************
+#malloc_police.h: *
+#malloc_police.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#malloc_police.h: *
+#malloc_police.h: * Purpose     :  This module uses the rec_malloc_police to build a
+#malloc_police.h: *                                            list of allocated and freed memory.  When the
+#malloc_police.h: *                                            program exits, we will print a list of all memory
+#malloc_police.h: *                                            that was allocated, but never freed.  This could
+#malloc_police.h: *                                            be most helpful to developers and debugers.
+#malloc_police.h: *
+#malloc_police.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#malloc_police.h: *                Privoxy team. http://www.privoxy.org/
+#malloc_police.h: *
+#malloc_police.h: *                This program is free software; you can redistribute it
+#malloc_police.h: *                and/or modify it under the terms of the GNU General
+#malloc_police.h: *                Public License as published by the Free Software
+#malloc_police.h: *                Foundation; either version 2 of the License, or (at
+#malloc_police.h: *                your option) any later version.
+#malloc_police.h: *
+#malloc_police.h: *                This program is distributed in the hope that it will
+#malloc_police.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#malloc_police.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#malloc_police.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#malloc_police.h: *                License for more details.
+#malloc_police.h: *
+#malloc_police.h: *                The GNU General Public License should be included with
+#malloc_police.h: *                this file.  If not, you can view it at
+#malloc_police.h: *                http://www.gnu.org/copyleft/gpl.html
+#malloc_police.h: *                or write to the Free Software Foundation, Inc., 59
+#malloc_police.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#malloc_police.h: *
+#malloc_police.h: * VI users           :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#malloc_police.h: *                                            and edit IJB, correctly.
+#malloc_police.h: *
+#malloc_police.h: * Revisions   :
+#malloc_police.h: *    $Log: contrib.sh,v $
+#malloc_police.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#malloc_police.h: *    name change related issues
+#malloc_police.h: *
+#malloc_police.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#malloc_police.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#malloc_police.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#malloc_police.h: *    contrib directory and I cannot upload a tarball ... it gets
+#malloc_police.h: *    corrupted).  This script will expand all files needed to create the
+#malloc_police.h: *    linked list modules and an example program.  Please see the README.
+#malloc_police.h: *    Feed back is welcomed.  Enjoy.
+#malloc_police.h: *
+#malloc_police.h: *
+#malloc_police.h: *********************************************************************/
+#malloc_police.h:\f
+#malloc_police.h:
+#malloc_police.h:#ifdef __cplusplus
+#malloc_police.h:extern "C" {
+#malloc_police.h:#endif
+#malloc_police.h:
+#malloc_police.h:
+#malloc_police.h:char *police_strdup( const char *s, const char *filename, long lineno );
+#malloc_police.h:void *police_malloc( size_t sz, const char *filename, long lineno );
+#malloc_police.h:void police_free( void *ptr, const char *filename, long lineno );
+#malloc_police.h:
+#malloc_police.h:#define STRDUP(s)                     police_strdup( s, __FILE__, __LINE__ )
+#malloc_police.h:#define MALLOC(sz)            police_malloc( sz, __FILE__, __LINE__ )
+#malloc_police.h:#define FREE(ptr)                     police_free( ptr, __FILE__, __LINE__ )
+#malloc_police.h:
+#malloc_police.h:
+#malloc_police.h:#ifdef __cplusplus
+#malloc_police.h:} /* extern "C" */
+#malloc_police.h:#endif
+#malloc_police.h:
+#malloc_police.h:#endif /* ndef MALLOC_POLICE_H_INCLUDED */
+#malloc_police.h:
+#malloc_police.h:/*
+#malloc_police.h:  Local Variables:
+#malloc_police.h:  tab-width: 3
+#malloc_police.h:  end:
+#malloc_police.h:*/
+
+
+#rec_char.c:const char rec_char_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#rec_char.c:/*********************************************************************
+#rec_char.c: *
+#rec_char.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_char.c: *
+#rec_char.c: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_char.c: *
+#rec_char.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_char.c: *                Privoxy team. http://www.privoxy.org/
+#rec_char.c: *
+#rec_char.c: *                This program is free software; you can redistribute it
+#rec_char.c: *                and/or modify it under the terms of the GNU General
+#rec_char.c: *                Public License as published by the Free Software
+#rec_char.c: *                Foundation; either version 2 of the License, or (at
+#rec_char.c: *                your option) any later version.
+#rec_char.c: *
+#rec_char.c: *                This program is distributed in the hope that it will
+#rec_char.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_char.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_char.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_char.c: *                License for more details.
+#rec_char.c: *
+#rec_char.c: *                The GNU General Public License should be included with
+#rec_char.c: *                this file.  If not, you can view it at
+#rec_char.c: *                http://www.gnu.org/copyleft/gpl.html
+#rec_char.c: *                or write to the Free Software Foundation, Inc., 59
+#rec_char.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_char.c: *
+#rec_char.c: * VI users                :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_char.c: *                                         and edit IJB, correctly.
+#rec_char.c: *
+#rec_char.c: * Revisions   :
+#rec_char.c: *    $Log: contrib.sh,v $
+#rec_char.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_char.c: *    name change related issues
+#rec_char.c: *
+#rec_char.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_char.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_char.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_char.c: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_char.c: *    corrupted).  This script will expand all files needed to create the
+#rec_char.c: *    linked list modules and an example program.  Please see the README.
+#rec_char.c: *    Feed back is welcomed.  Enjoy.
+#rec_char.c: *
+#rec_char.c: *
+#rec_char.c: *********************************************************************/
+#rec_char.c:\f
+#rec_char.c:
+#rec_char.c:#include <malloc.h>
+#rec_char.c:#include <stdio.h>
+#rec_char.c:#include <stdlib.h>
+#rec_char.c:#include <string.h>
+#rec_char.c:
+#rec_char.c:#include "gen_list.h"
+#rec_char.c:#include "rec_char.h"
+#rec_char.c:
+#rec_char.c:const char rec_char_h_rcs[] = REC_CHAR_H_VERSION;
+#rec_char.c:
+#rec_char.c:
+#rec_char.c:static const rec_method rec_char_vtable[] =
+#rec_char.c:{
+#rec_char.c:   (rec_method)derived_rec_char_copy_construct,
+#rec_char.c:   (rec_method)derived_rec_char_destruct,
+#rec_char.c:   (rec_method)derived_rec_char_stream,
+#rec_char.c:   (rec_method)derived_rec_char_equal
+#rec_char.c:};
+#rec_char.c:
+#rec_char.c:
+#rec_char.c:/*********************************************************************
+#rec_char.c: *
+#rec_char.c: * Function    :  derived_rec_char_construct
+#rec_char.c: *
+#rec_char.c: * Description :  A simple derived record class that contains 1 string.
+#rec_char.c: *
+#rec_char.c: * Parameters  :
+#rec_char.c: *          1  :  The record
+#rec_char.c: *          2  :  The string to contain.
+#rec_char.c: *
+#rec_char.c: * Returns     :  A pointer to the constructed record.
+#rec_char.c: *
+#rec_char.c: *********************************************************************/
+#rec_char.c:struct derived_rec_char *derived_rec_char_construct( const char _contents )
+#rec_char.c:{
+#rec_char.c:   struct derived_rec_char *this_rec = (struct derived_rec_char *)gen_list_rec_construct(
+#rec_char.c:           ISA_CHAR,
+#rec_char.c:           sizeof( struct derived_rec_char ),
+#rec_char.c:           rec_char_vtable
+#rec_char.c:   );
+#rec_char.c:
+#rec_char.c:   this_rec->contents = _contents;
+#rec_char.c:
+#rec_char.c:   LIST_SHOW( printf( "\
+#rec_char.c:\t\tchar construct new rec\t\t\t\t= %p
+#rec_char.c:\t\tchar construct new rec contents\t= %c\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_char.c:
+#rec_char.c:   return( this_rec );
+#rec_char.c:
+#rec_char.c:}
+#rec_char.c:
+#rec_char.c:
+#rec_char.c:/*********************************************************************
+#rec_char.c: *
+#rec_char.c: * Function    :  derived_rec_char_copy_construct
+#rec_char.c: *
+#rec_char.c: * Description :  Copies one char record to another.
+#rec_char.c: *
+#rec_char.c: * Parameters  :
+#rec_char.c: *          1  :  Existing record.
+#rec_char.c: *                         2       :  Copy record.
+#rec_char.c: *
+#rec_char.c: * Returns     :  The newly constructed copy record.
+#rec_char.c: *
+#rec_char.c: *********************************************************************/
+#rec_char.c:struct derived_rec_char *derived_rec_char_copy_construct( const struct derived_rec_char *this_rec )
+#rec_char.c:{
+#rec_char.c:   struct derived_rec_char *copy_rec = (struct derived_rec_char *)gen_list_rec_copy_construct( (struct gen_list_rec *)this_rec );
+#rec_char.c:   copy_rec->contents = this_rec->contents;
+#rec_char.c:
+#rec_char.c:   LIST_SHOW( printf( "\
+#rec_char.c:\t\tchar copy construct new gen rec\t\t\t\t= %p => %p
+#rec_char.c:\t\tchar copy construct new gen rec contents\t= %c\n\n", (const void *)this_rec, (const void *)copy_rec, copy_rec->contents ) );
+#rec_char.c:
+#rec_char.c:   return( copy_rec );
+#rec_char.c:
+#rec_char.c:}
+#rec_char.c:
+#rec_char.c:
+#rec_char.c:/*********************************************************************
+#rec_char.c: *
+#rec_char.c: * Function    :  derived_rec_char_destruct        
+#rec_char.c: *
+#rec_char.c: * Description :  Destruct the char record.
+#rec_char.c: *
+#rec_char.c: * Parameters  :
+#rec_char.c: *          1  :  The record.
+#rec_char.c: *
+#rec_char.c: * Returns     :  NULL
+#rec_char.c: *
+#rec_char.c: *********************************************************************/
+#rec_char.c:struct derived_rec_char *derived_rec_char_destruct( struct derived_rec_char *this_rec )
+#rec_char.c:{
+#rec_char.c:   LIST_SHOW( printf( "\
+#rec_char.c:\t\tchar destruct this_rec\t\t\t\t= %p
+#rec_char.c:\t\tchar destruct this_rec->contents\t= %c\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_char.c:
+#rec_char.c:   this_rec->contents = '!';
+#rec_char.c:   return( (struct derived_rec_char *)gen_list_rec_destruct( (struct gen_list_rec *)this_rec ) );
+#rec_char.c:
+#rec_char.c:}
+#rec_char.c:
+#rec_char.c:
+#rec_char.c:/*********************************************************************
+#rec_char.c: *
+#rec_char.c: * Function    :  derived_rec_char_stream
+#rec_char.c: *
+#rec_char.c: * Description :  Displays all char attributes on the STDOUT stream.
+#rec_char.c: *
+#rec_char.c: * Parameters  :
+#rec_char.c: *          1  :  The record.
+#rec_char.c: *
+#rec_char.c: * Returns     :  The record.
+#rec_char.c: *
+#rec_char.c: *********************************************************************/
+#rec_char.c:const struct derived_rec_char *derived_rec_char_stream( const struct derived_rec_char *this_rec )
+#rec_char.c:{
+#rec_char.c:   this_rec = (struct derived_rec_char *)gen_list_rec_stream(
+#rec_char.c:           (struct gen_list_rec *)this_rec
+#rec_char.c:   );
+#rec_char.c:   LIST_SHOW( printf( "\
+#rec_char.c:\t\tchar stream this_rec\t\t\t\t\t= %p
+#rec_char.c:\t\tchar stream this_rec->contents\t= %c\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_char.c:
+#rec_char.c:   return( this_rec );
+#rec_char.c:
+#rec_char.c:}
+#rec_char.c:
+#rec_char.c:
+#rec_char.c:/*********************************************************************
+#rec_char.c: *
+#rec_char.c: * Function    :  derived_rec_char_equal
+#rec_char.c: *
+#rec_char.c: * Description :  Compares two char records to see if they are equal.
+#rec_char.c: *
+#rec_char.c: * Parameters  :
+#rec_char.c: *          1  :  A record.
+#rec_char.c: *          2  :  Another record.
+#rec_char.c: *
+#rec_char.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#rec_char.c: *
+#rec_char.c: *********************************************************************/
+#rec_char.c:int derived_rec_char_equal( const struct derived_rec_char *this_rec, const struct derived_rec_char *eq_rec )
+#rec_char.c:{
+#rec_char.c:   if ( ! gen_list_rec_equal( (const struct gen_list_rec *)this_rec, (struct gen_list_rec *)eq_rec ) )
+#rec_char.c:   {
+#rec_char.c:           return( 0 );
+#rec_char.c:   }
+#rec_char.c:   return( this_rec->contents == eq_rec->contents );
+#rec_char.c:
+#rec_char.c:}
+
+
+#rec_char.h:#ifndef REC_CHAR_H_INCLUDED
+#rec_char.h:#define REC_CHAR_H_INCLUDED
+#rec_char.h:#define REC_CHAR_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#rec_char.h:/*********************************************************************
+#rec_char.h: *
+#rec_char.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_char.h: *
+#rec_char.h: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_char.h: *
+#rec_char.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_char.h: *                Privoxy team. http://www.privoxy.org/
+#rec_char.h: *
+#rec_char.h: *                This program is free software; you can redistribute it
+#rec_char.h: *                and/or modify it under the terms of the GNU General
+#rec_char.h: *                Public License as published by the Free Software
+#rec_char.h: *                Foundation; either version 2 of the License, or (at
+#rec_char.h: *                your option) any later version.
+#rec_char.h: *
+#rec_char.h: *                This program is distributed in the hope that it will
+#rec_char.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_char.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_char.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_char.h: *                License for more details.
+#rec_char.h: *
+#rec_char.h: *                The GNU General Public License should be included with
+#rec_char.h: *                this file.  If not, you can view it at
+#rec_char.h: *                http://www.gnu.org/copyleft/gpl.html
+#rec_char.h: *                or write to the Free Software Foundation, Inc., 59
+#rec_char.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_char.h: *
+#rec_char.h: * VI users                :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_char.h: *                                         and edit IJB, correctly.
+#rec_char.h: *
+#rec_char.h: * Revisions   :
+#rec_char.h: *    $Log: contrib.sh,v $
+#rec_char.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_char.h: *    name change related issues
+#rec_char.h: *
+#rec_char.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_char.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_char.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_char.h: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_char.h: *    corrupted).  This script will expand all files needed to create the
+#rec_char.h: *    linked list modules and an example program.  Please see the README.
+#rec_char.h: *    Feed back is welcomed.  Enjoy.
+#rec_char.h: *
+#rec_char.h: *
+#rec_char.h: *********************************************************************/
+#rec_char.h:\f
+#rec_char.h:
+#rec_char.h:#ifdef __cplusplus
+#rec_char.h:extern "C" {
+#rec_char.h:#endif
+#rec_char.h:
+#rec_char.h:
+#rec_char.h:struct derived_rec_char
+#rec_char.h:{
+#rec_char.h:   /* private: */
+#rec_char.h:   struct gen_list_rec parent_rec;
+#rec_char.h:   char contents;
+#rec_char.h:};
+#rec_char.h:
+#rec_char.h:/* public: */
+#rec_char.h:extern struct derived_rec_char *   derived_rec_char_construct( const char _contents );
+#rec_char.h:extern struct derived_rec_char *   derived_rec_char_copy_construct( const struct derived_rec_char *this_rec );
+#rec_char.h:extern struct derived_rec_char *   derived_rec_char_destruct( struct derived_rec_char *this_rec );
+#rec_char.h:extern const struct derived_rec_char *derived_rec_char_stream( const struct derived_rec_char *this_rec );
+#rec_char.h:extern int                                                         derived_rec_char_equal( const struct derived_rec_char *this_rec, const struct derived_rec_char *eq_rec );
+#rec_char.h:
+#rec_char.h:/* struct/class COMPLETE */
+#rec_char.h:
+#rec_char.h:
+#rec_char.h:#ifdef __cplusplus
+#rec_char.h:} /* extern "C" */
+#rec_char.h:#endif
+#rec_char.h:
+#rec_char.h:#endif /* ndef REC_CHAR_H_INCLUDED */
+#rec_char.h:
+#rec_char.h:/*
+#rec_char.h:  Local Variables:
+#rec_char.h:  tab-width: 3
+#rec_char.h:  end:
+#rec_char.h:*/
+
+
+#rec_charptr.c:const char rec_charptr_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#rec_charptr.c:/*********************************************************************
+#rec_charptr.c: *
+#rec_charptr.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_charptr.c: *
+#rec_charptr.c: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_charptr.c: *
+#rec_charptr.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_charptr.c: *                Privoxy team. http://www.privoxy.org/
+#rec_charptr.c: *
+#rec_charptr.c: *                This program is free software; you can redistribute it
+#rec_charptr.c: *                and/or modify it under the terms of the GNU General
+#rec_charptr.c: *                Public License as published by the Free Software
+#rec_charptr.c: *                Foundation; either version 2 of the License, or (at
+#rec_charptr.c: *                your option) any later version.
+#rec_charptr.c: *
+#rec_charptr.c: *                This program is distributed in the hope that it will
+#rec_charptr.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_charptr.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_charptr.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_charptr.c: *                License for more details.
+#rec_charptr.c: *
+#rec_charptr.c: *                The GNU General Public License should be included with
+#rec_charptr.c: *                this file.  If not, you can view it at
+#rec_charptr.c: *                http://www.gnu.org/copyleft/gpl.html
+#rec_charptr.c: *                or write to the Free Software Foundation, Inc., 59
+#rec_charptr.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_charptr.c: *
+#rec_charptr.c: * VI users             :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_charptr.c: *                                              and edit IJB, correctly.
+#rec_charptr.c: *
+#rec_charptr.c: * Revisions   :
+#rec_charptr.c: *    $Log: contrib.sh,v $
+#rec_charptr.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_charptr.c: *    name change related issues
+#rec_charptr.c: *
+#rec_charptr.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_charptr.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_charptr.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_charptr.c: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_charptr.c: *    corrupted).  This script will expand all files needed to create the
+#rec_charptr.c: *    linked list modules and an example program.  Please see the README.
+#rec_charptr.c: *    Feed back is welcomed.  Enjoy.
+#rec_charptr.c: *
+#rec_charptr.c: *
+#rec_charptr.c: *********************************************************************/
+#rec_charptr.c:\f
+#rec_charptr.c:
+#rec_charptr.c:#include <malloc.h>
+#rec_charptr.c:#include <stdio.h>
+#rec_charptr.c:#include <stdlib.h>
+#rec_charptr.c:#include <string.h>
+#rec_charptr.c:
+#rec_charptr.c:#include "gen_list.h"
+#rec_charptr.c:#include "rec_charptr.h"
+#rec_charptr.c:#include "malloc_police.h"
+#rec_charptr.c:
+#rec_charptr.c:const char rec_charptr_h_rcs[] = REC_CHARPTR_H_VERSION;
+#rec_charptr.c:
+#rec_charptr.c:
+#rec_charptr.c:static const rec_method rec_charptr_vtable[] =
+#rec_charptr.c:{
+#rec_charptr.c:        (rec_method)derived_rec_charptr_copy_construct,
+#rec_charptr.c:        (rec_method)derived_rec_charptr_destruct,
+#rec_charptr.c:        (rec_method)derived_rec_charptr_stream,
+#rec_charptr.c:        (rec_method)derived_rec_charptr_equal
+#rec_charptr.c:};
+#rec_charptr.c:
+#rec_charptr.c:
+#rec_charptr.c:/*********************************************************************
+#rec_charptr.c: *
+#rec_charptr.c: * Function    :  derived_rec_charptr_construct
+#rec_charptr.c: *
+#rec_charptr.c: * Description :  A simple derived record class that contains 1 string.
+#rec_charptr.c: *
+#rec_charptr.c: * Parameters  :
+#rec_charptr.c: *          1  :  The record
+#rec_charptr.c: *          2  :  The string to contain.
+#rec_charptr.c: *
+#rec_charptr.c: * Returns     :  A pointer to the constructed record.
+#rec_charptr.c: *
+#rec_charptr.c: *********************************************************************/
+#rec_charptr.c:struct derived_rec_charptr *derived_rec_charptr_construct( const char *_contents )
+#rec_charptr.c:{
+#rec_charptr.c:        struct derived_rec_charptr *this_rec = (struct derived_rec_charptr *)gen_list_rec_construct(
+#rec_charptr.c:                ISA_CHARPTR,
+#rec_charptr.c:                sizeof( struct derived_rec_charptr ),
+#rec_charptr.c:                rec_charptr_vtable
+#rec_charptr.c:        );
+#rec_charptr.c:
+#rec_charptr.c:        this_rec->contents = STRDUP( _contents );
+#rec_charptr.c:
+#rec_charptr.c:        LIST_SHOW( printf( "\
+#rec_charptr.c:\t\tcharptr construct new rec\t\t\t\t= %p
+#rec_charptr.c:\t\tcharptr construct new rec contents\t= %s\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_charptr.c:
+#rec_charptr.c:        return( this_rec );
+#rec_charptr.c:
+#rec_charptr.c:}
+#rec_charptr.c:
+#rec_charptr.c:
+#rec_charptr.c:/*********************************************************************
+#rec_charptr.c: *
+#rec_charptr.c: * Function    :  derived_rec_charptr_copy_construct
+#rec_charptr.c: *
+#rec_charptr.c: * Description :  Copies one charptr record to another.
+#rec_charptr.c: *
+#rec_charptr.c: * Parameters  :
+#rec_charptr.c: *          1  :  Existing record.
+#rec_charptr.c: *                              2       :  Copy record.
+#rec_charptr.c: *
+#rec_charptr.c: * Returns     :  The newly constructed copy record.
+#rec_charptr.c: *
+#rec_charptr.c: *********************************************************************/
+#rec_charptr.c:struct derived_rec_charptr *derived_rec_charptr_copy_construct( const struct derived_rec_charptr *this_rec )
+#rec_charptr.c:{
+#rec_charptr.c:        int len;
+#rec_charptr.c:        char *new_contents;
+#rec_charptr.c:
+#rec_charptr.c:        struct derived_rec_charptr *copy_rec = (struct derived_rec_charptr *)gen_list_rec_copy_construct( (struct gen_list_rec *)this_rec );
+#rec_charptr.c:
+#rec_charptr.c:        len = strlen( this_rec->contents );
+#rec_charptr.c:        len += sizeof( "COPY " );
+#rec_charptr.c:
+#rec_charptr.c:        copy_rec->contents = (char *)MALLOC( len );
+#rec_charptr.c:        strcpy( copy_rec->contents, "COPY " );
+#rec_charptr.c:        strcat( copy_rec->contents, this_rec->contents );
+#rec_charptr.c:
+#rec_charptr.c:        LIST_SHOW( printf( "\
+#rec_charptr.c:\t\tcharptr copy construct new gen rec\t\t\t\t= %p => %p
+#rec_charptr.c:\t\tcharptr copy construct new gen rec contents\t= %s\n\n", (const void *)this_rec, (const void *)copy_rec, copy_rec->contents ) );
+#rec_charptr.c:
+#rec_charptr.c:
+#rec_charptr.c:        return( copy_rec );
+#rec_charptr.c:
+#rec_charptr.c:}
+#rec_charptr.c:
+#rec_charptr.c:
+#rec_charptr.c:/*********************************************************************
+#rec_charptr.c: *
+#rec_charptr.c: * Function    :  derived_rec_charptr_destruct  
+#rec_charptr.c: *
+#rec_charptr.c: * Description :  Destruct the charptr record.
+#rec_charptr.c: *
+#rec_charptr.c: * Parameters  :
+#rec_charptr.c: *          1  :  The record.
+#rec_charptr.c: *
+#rec_charptr.c: * Returns     :  NULL
+#rec_charptr.c: *
+#rec_charptr.c: *********************************************************************/
+#rec_charptr.c:struct derived_rec_charptr *derived_rec_charptr_destruct( struct derived_rec_charptr *this_rec )
+#rec_charptr.c:{
+#rec_charptr.c:        LIST_SHOW( printf( "\
+#rec_charptr.c:\t\tcharptr destruct this_rec\t\t\t\t= %p
+#rec_charptr.c:\t\tcharptr destruct this_rec->contents\t= %s\n\n", (const void *)this_rec, (const void *)this_rec->contents ) );
+#rec_charptr.c:
+#rec_charptr.c:        memset( this_rec->contents, '!', strlen( this_rec->contents ) );
+#rec_charptr.c:        FREE( this_rec->contents );
+#rec_charptr.c:        return( (struct derived_rec_charptr *)gen_list_rec_destruct( (struct gen_list_rec *)this_rec ) );
+#rec_charptr.c:
+#rec_charptr.c:}
+#rec_charptr.c:
+#rec_charptr.c:
+#rec_charptr.c:/*********************************************************************
+#rec_charptr.c: *
+#rec_charptr.c: * Function    :  derived_rec_charptr_stream
+#rec_charptr.c: *
+#rec_charptr.c: * Description :  Displays all charptr attributes on the STDOUT stream.
+#rec_charptr.c: *
+#rec_charptr.c: * Parameters  :
+#rec_charptr.c: *          1  :  The record.
+#rec_charptr.c: *
+#rec_charptr.c: * Returns     :  The record.
+#rec_charptr.c: *
+#rec_charptr.c: *********************************************************************/
+#rec_charptr.c:const struct derived_rec_charptr *derived_rec_charptr_stream( const struct derived_rec_charptr *this_rec )
+#rec_charptr.c:{
+#rec_charptr.c:        this_rec = (struct derived_rec_charptr *)gen_list_rec_stream(
+#rec_charptr.c:                (struct gen_list_rec *)this_rec
+#rec_charptr.c:        );
+#rec_charptr.c:        LIST_SHOW( printf( "\
+#rec_charptr.c:\t\tcharptr stream this_rec\t\t\t\t\t= %p
+#rec_charptr.c:\t\tcharptr stream this_rec->contents\t= %s\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_charptr.c:
+#rec_charptr.c:        return( this_rec );
+#rec_charptr.c:
+#rec_charptr.c:}
+#rec_charptr.c:
+#rec_charptr.c:
+#rec_charptr.c:/*********************************************************************
+#rec_charptr.c: *
+#rec_charptr.c: * Function    :  derived_rec_charptr_equal
+#rec_charptr.c: *
+#rec_charptr.c: * Description :  Compares two charptr records to see if they are equal.
+#rec_charptr.c: *
+#rec_charptr.c: * Parameters  :
+#rec_charptr.c: *          1  :  A record.
+#rec_charptr.c: *          2  :  Another record.
+#rec_charptr.c: *
+#rec_charptr.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#rec_charptr.c: *
+#rec_charptr.c: *********************************************************************/
+#rec_charptr.c:int derived_rec_charptr_equal( const struct derived_rec_charptr *this_rec, const struct derived_rec_charptr *eq_rec )
+#rec_charptr.c:{
+#rec_charptr.c:        if ( ! gen_list_rec_equal( (const struct gen_list_rec *)this_rec, (struct gen_list_rec *)eq_rec ) )
+#rec_charptr.c:        {
+#rec_charptr.c:                return( 0 );
+#rec_charptr.c:        }
+#rec_charptr.c:        return( 0 == strcmp( this_rec->contents, eq_rec->contents ) );
+#rec_charptr.c:
+#rec_charptr.c:}
+
+
+#rec_charptr.h:#ifndef REC_CHARPTR_H_INCLUDED
+#rec_charptr.h:#define REC_CHARPTR_H_INCLUDED
+#rec_charptr.h:#define REC_CHARPTR_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#rec_charptr.h:/*********************************************************************
+#rec_charptr.h: *
+#rec_charptr.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_charptr.h: *
+#rec_charptr.h: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_charptr.h: *
+#rec_charptr.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_charptr.h: *                Privoxy team. http://www.privoxy.org/
+#rec_charptr.h: *
+#rec_charptr.h: *                This program is free software; you can redistribute it
+#rec_charptr.h: *                and/or modify it under the terms of the GNU General
+#rec_charptr.h: *                Public License as published by the Free Software
+#rec_charptr.h: *                Foundation; either version 2 of the License, or (at
+#rec_charptr.h: *                your option) any later version.
+#rec_charptr.h: *
+#rec_charptr.h: *                This program is distributed in the hope that it will
+#rec_charptr.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_charptr.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_charptr.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_charptr.h: *                License for more details.
+#rec_charptr.h: *
+#rec_charptr.h: *                The GNU General Public License should be included with
+#rec_charptr.h: *                this file.  If not, you can view it at
+#rec_charptr.h: *                http://www.gnu.org/copyleft/gpl.html
+#rec_charptr.h: *                or write to the Free Software Foundation, Inc., 59
+#rec_charptr.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_charptr.h: *
+#rec_charptr.h: * VI users             :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_charptr.h: *                                              and edit IJB, correctly.
+#rec_charptr.h: *
+#rec_charptr.h: * Revisions   :
+#rec_charptr.h: *    $Log: contrib.sh,v $
+#rec_charptr.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_charptr.h: *    name change related issues
+#rec_charptr.h: *
+#rec_charptr.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_charptr.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_charptr.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_charptr.h: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_charptr.h: *    corrupted).  This script will expand all files needed to create the
+#rec_charptr.h: *    linked list modules and an example program.  Please see the README.
+#rec_charptr.h: *    Feed back is welcomed.  Enjoy.
+#rec_charptr.h: *
+#rec_charptr.h: *
+#rec_charptr.h: *********************************************************************/
+#rec_charptr.h:\f
+#rec_charptr.h:
+#rec_charptr.h:#ifdef __cplusplus
+#rec_charptr.h:extern "C" {
+#rec_charptr.h:#endif
+#rec_charptr.h:
+#rec_charptr.h:
+#rec_charptr.h:struct derived_rec_charptr
+#rec_charptr.h:{
+#rec_charptr.h:        /* private: */
+#rec_charptr.h:        struct gen_list_rec parent_rec;
+#rec_charptr.h:        char *contents;
+#rec_charptr.h:};
+#rec_charptr.h:
+#rec_charptr.h:/* public: */
+#rec_charptr.h:extern struct derived_rec_charptr *     derived_rec_charptr_construct( const char *_contents );
+#rec_charptr.h:extern struct derived_rec_charptr *     derived_rec_charptr_copy_construct( const struct derived_rec_charptr *this_rec );
+#rec_charptr.h:extern struct derived_rec_charptr *     derived_rec_charptr_destruct( struct derived_rec_charptr *this_rec );
+#rec_charptr.h:extern const struct derived_rec_charptr *derived_rec_charptr_stream( const struct derived_rec_charptr *this_rec );
+#rec_charptr.h:extern int                                                                      derived_rec_charptr_equal( const struct derived_rec_charptr *this_rec, const struct derived_rec_charptr *eq_rec );
+#rec_charptr.h:
+#rec_charptr.h:/* struct/class COMPLETE */
+#rec_charptr.h:
+#rec_charptr.h:
+#rec_charptr.h:#ifdef __cplusplus
+#rec_charptr.h:} /* extern "C" */
+#rec_charptr.h:#endif
+#rec_charptr.h:
+#rec_charptr.h:#endif /* ndef REC_CHARPTR_H_INCLUDED */
+#rec_charptr.h:
+#rec_charptr.h:/*
+#rec_charptr.h:  Local Variables:
+#rec_charptr.h:  tab-width: 3
+#rec_charptr.h:  end:
+#rec_charptr.h:*/
+
+
+#rec_double.c:const char rec_double_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#rec_double.c:/*********************************************************************
+#rec_double.c: *
+#rec_double.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_double.c: *
+#rec_double.c: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_double.c: *
+#rec_double.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_double.c: *                Privoxy team. http://www.privoxy.org/
+#rec_double.c: *
+#rec_double.c: *                This program is free software; you can redistribute it
+#rec_double.c: *                and/or modify it under the terms of the GNU General
+#rec_double.c: *                Public License as published by the Free Software
+#rec_double.c: *                Foundation; either version 2 of the License, or (at
+#rec_double.c: *                your option) any later version.
+#rec_double.c: *
+#rec_double.c: *                This program is distributed in the hope that it will
+#rec_double.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_double.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_double.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_double.c: *                License for more details.
+#rec_double.c: *
+#rec_double.c: *                The GNU General Public License should be included with
+#rec_double.c: *                this file.  If not, you can view it at
+#rec_double.c: *                http://www.gnu.org/copyleft/gpl.html
+#rec_double.c: *                or write to the Free Software Foundation, Inc., 59
+#rec_double.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_double.c: *
+#rec_double.c: * VI users              :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_double.c: *                                               and edit IJB, correctly.
+#rec_double.c: *
+#rec_double.c: * Revisions   :
+#rec_double.c: *    $Log: contrib.sh,v $
+#rec_double.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_double.c: *    name change related issues
+#rec_double.c: *
+#rec_double.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_double.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_double.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_double.c: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_double.c: *    corrupted).  This script will expand all files needed to create the
+#rec_double.c: *    linked list modules and an example program.  Please see the README.
+#rec_double.c: *    Feed back is welcomed.  Enjoy.
+#rec_double.c: *
+#rec_double.c: *
+#rec_double.c: *********************************************************************/
+#rec_double.c:\f
+#rec_double.c:
+#rec_double.c:#include <malloc.h>
+#rec_double.c:#include <stdio.h>
+#rec_double.c:#include <stdlib.h>
+#rec_double.c:#include <string.h>
+#rec_double.c:
+#rec_double.c:#include "gen_list.h"
+#rec_double.c:#include "rec_double.h"
+#rec_double.c:
+#rec_double.c:const char rec_double_h_rcs[] = REC_DOUBLE_H_VERSION;
+#rec_double.c:
+#rec_double.c:
+#rec_double.c:static const rec_method rec_double_vtable[] =
+#rec_double.c:{
+#rec_double.c: (rec_method)derived_rec_double_copy_construct,
+#rec_double.c: (rec_method)derived_rec_double_destruct,
+#rec_double.c: (rec_method)derived_rec_double_stream,
+#rec_double.c: (rec_method)derived_rec_double_equal
+#rec_double.c:};
+#rec_double.c:
+#rec_double.c:
+#rec_double.c:/*********************************************************************
+#rec_double.c: *
+#rec_double.c: * Function    :  derived_rec_double_construct
+#rec_double.c: *
+#rec_double.c: * Description :  A simple derived record class that contains 1 string.
+#rec_double.c: *
+#rec_double.c: * Parameters  :
+#rec_double.c: *          1  :  The record
+#rec_double.c: *          2  :  The string to contain.
+#rec_double.c: *
+#rec_double.c: * Returns     :  A pointer to the constructed record.
+#rec_double.c: *
+#rec_double.c: *********************************************************************/
+#rec_double.c:struct derived_rec_double *derived_rec_double_construct( const double _contents )
+#rec_double.c:{
+#rec_double.c: struct derived_rec_double *this_rec = (struct derived_rec_double *)gen_list_rec_construct(
+#rec_double.c:         ISA_DOUBLE,
+#rec_double.c:         sizeof( struct derived_rec_double ),
+#rec_double.c:         rec_double_vtable
+#rec_double.c: );
+#rec_double.c:
+#rec_double.c: this_rec->contents = _contents;
+#rec_double.c:
+#rec_double.c: LIST_SHOW( printf( "\
+#rec_double.c:\t\tdouble construct new rec\t\t\t\t= %p
+#rec_double.c:\t\tdouble construct new rec contents\t= %8.2lf\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_double.c:
+#rec_double.c: return( this_rec );
+#rec_double.c:
+#rec_double.c:}
+#rec_double.c:
+#rec_double.c:
+#rec_double.c:/*********************************************************************
+#rec_double.c: *
+#rec_double.c: * Function    :  derived_rec_double_copy_construct
+#rec_double.c: *
+#rec_double.c: * Description :  Copies one double record to another.
+#rec_double.c: *
+#rec_double.c: * Parameters  :
+#rec_double.c: *          1  :  Existing record.
+#rec_double.c: *                               2       :  Copy record.
+#rec_double.c: *
+#rec_double.c: * Returns     :  The newly constructed copy record.
+#rec_double.c: *
+#rec_double.c: *********************************************************************/
+#rec_double.c:struct derived_rec_double *derived_rec_double_copy_construct( const struct derived_rec_double *this_rec )
+#rec_double.c:{
+#rec_double.c: struct derived_rec_double *copy_rec = (struct derived_rec_double *)gen_list_rec_copy_construct( (struct gen_list_rec *)this_rec );
+#rec_double.c: copy_rec->contents = - this_rec->contents;
+#rec_double.c:
+#rec_double.c: LIST_SHOW( printf( "\
+#rec_double.c:\t\tdouble copy construct new gen rec\t\t\t\t= %p => %p
+#rec_double.c:\t\tdouble copy construct new gen rec contents\t= %8.2lf\n\n", (const void *)this_rec, (const void *)copy_rec, copy_rec->contents ) );
+#rec_double.c:
+#rec_double.c: return( copy_rec );
+#rec_double.c:
+#rec_double.c:}
+#rec_double.c:
+#rec_double.c:
+#rec_double.c:/*********************************************************************
+#rec_double.c: *
+#rec_double.c: * Function    :  derived_rec_double_destruct    
+#rec_double.c: *
+#rec_double.c: * Description :  Destruct the double record.
+#rec_double.c: *
+#rec_double.c: * Parameters  :
+#rec_double.c: *          1  :  The record.
+#rec_double.c: *
+#rec_double.c: * Returns     :  NULL
+#rec_double.c: *
+#rec_double.c: *********************************************************************/
+#rec_double.c:struct derived_rec_double *derived_rec_double_destruct( struct derived_rec_double *this_rec )
+#rec_double.c:{
+#rec_double.c: LIST_SHOW( printf( "\
+#rec_double.c:\t\tdouble destruct this_rec\t\t\t\t= %p
+#rec_double.c:\t\tdouble destruct this_rec->contents\t= %8.2lf\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_double.c:
+#rec_double.c: this_rec->contents = -1.1111;
+#rec_double.c: return( (struct derived_rec_double *)gen_list_rec_destruct( (struct gen_list_rec *)this_rec ) );
+#rec_double.c:
+#rec_double.c:}
+#rec_double.c:
+#rec_double.c:
+#rec_double.c:/*********************************************************************
+#rec_double.c: *
+#rec_double.c: * Function    :  derived_rec_double_stream
+#rec_double.c: *
+#rec_double.c: * Description :  Displays all double attributes on the STDOUT stream.
+#rec_double.c: *
+#rec_double.c: * Parameters  :
+#rec_double.c: *          1  :  The record.
+#rec_double.c: *
+#rec_double.c: * Returns     :  The record.
+#rec_double.c: *
+#rec_double.c: *********************************************************************/
+#rec_double.c:const struct derived_rec_double *derived_rec_double_stream( const struct derived_rec_double *this_rec )
+#rec_double.c:{
+#rec_double.c: this_rec = (struct derived_rec_double *)gen_list_rec_stream(
+#rec_double.c:         (struct gen_list_rec *)this_rec
+#rec_double.c: );
+#rec_double.c: LIST_SHOW( printf( "\
+#rec_double.c:\t\tdouble stream this_rec\t\t\t\t= %p
+#rec_double.c:\t\tdouble stream this_rec->contents\t= %8.2lf\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_double.c:
+#rec_double.c: return( this_rec );
+#rec_double.c:
+#rec_double.c:}
+#rec_double.c:
+#rec_double.c:
+#rec_double.c:/*********************************************************************
+#rec_double.c: *
+#rec_double.c: * Function    :  derived_rec_double_equal
+#rec_double.c: *
+#rec_double.c: * Description :  Compares two double records to see if they are equal.
+#rec_double.c: *
+#rec_double.c: * Parameters  :
+#rec_double.c: *          1  :  A record.
+#rec_double.c: *          2  :  Another record.
+#rec_double.c: *
+#rec_double.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#rec_double.c: *
+#rec_double.c: *********************************************************************/
+#rec_double.c:int derived_rec_double_equal( const struct derived_rec_double *this_rec, const struct derived_rec_double *eq_rec )
+#rec_double.c:{
+#rec_double.c: if ( ! gen_list_rec_equal( (const struct gen_list_rec *)this_rec, (struct gen_list_rec *)eq_rec ) )
+#rec_double.c: {
+#rec_double.c:         return( 0 );
+#rec_double.c: }
+#rec_double.c: return( this_rec->contents == eq_rec->contents );
+#rec_double.c:
+#rec_double.c:}
+
+
+#rec_double.h:#ifndef REC_DOUBLE_H_INCLUDED
+#rec_double.h:#define REC_DOUBLE_H_INCLUDED
+#rec_double.h:#define REC_DOUBLE_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#rec_double.h:/*********************************************************************
+#rec_double.h: *
+#rec_double.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_double.h: *
+#rec_double.h: * Purpose     :  gen_A "derived class" of gen_list_rec.
+#rec_double.h: *
+#rec_double.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_double.h: *                Privoxy team. http://www.privoxy.org/
+#rec_double.h: *
+#rec_double.h: *                This program is free software; you can redistribute it
+#rec_double.h: *                and/or modify it under the terms of the GNU General
+#rec_double.h: *                Public License as published by the Free Software
+#rec_double.h: *                Foundation; either version 2 of the License, or (at
+#rec_double.h: *                your option) any later version.
+#rec_double.h: *
+#rec_double.h: *                This program is distributed in the hope that it will
+#rec_double.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_double.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_double.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_double.h: *                License for more details.
+#rec_double.h: *
+#rec_double.h: *                The GNU General Public License should be included with
+#rec_double.h: *                this file.  If not, you can view it at
+#rec_double.h: *                http://www.gnu.org/copyleft/gpl.html
+#rec_double.h: *                or write to the Free Software Foundation, Inc., 59
+#rec_double.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_double.h: *
+#rec_double.h: * VI users              :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_double.h: *                                               and edit IJB, correctly.
+#rec_double.h: *
+#rec_double.h: * Revisions   :
+#rec_double.h: *    $Log: contrib.sh,v $
+#rec_double.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_double.h: *    name change related issues
+#rec_double.h: *
+#rec_double.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_double.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_double.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_double.h: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_double.h: *    corrupted).  This script will expand all files needed to create the
+#rec_double.h: *    linked list modules and an example program.  Please see the README.
+#rec_double.h: *    Feed back is welcomed.  Enjoy.
+#rec_double.h: *
+#rec_double.h: *
+#rec_double.h: *********************************************************************/
+#rec_double.h:\f
+#rec_double.h:
+#rec_double.h:#ifdef __cplusplus
+#rec_double.h:extern "C" {
+#rec_double.h:#endif
+#rec_double.h:
+#rec_double.h:
+#rec_double.h:struct derived_rec_double
+#rec_double.h:{
+#rec_double.h: /* private: */
+#rec_double.h: struct gen_list_rec parent_rec;
+#rec_double.h: double contents;
+#rec_double.h:};
+#rec_double.h:
+#rec_double.h:/* public: */
+#rec_double.h:extern struct derived_rec_double *       derived_rec_double_construct( const double _contents );
+#rec_double.h:extern struct derived_rec_double *       derived_rec_double_copy_construct( const struct derived_rec_double *this_rec );
+#rec_double.h:extern struct derived_rec_double *       derived_rec_double_destruct( struct derived_rec_double *this_rec );
+#rec_double.h:extern const struct derived_rec_double *derived_rec_double_stream( const struct derived_rec_double *this_rec );
+#rec_double.h:extern int                                                               derived_rec_double_equal( const struct derived_rec_double *this_rec, const struct derived_rec_double *eq_rec );
+#rec_double.h:
+#rec_double.h:/* struct/class COMPLETE */
+#rec_double.h:
+#rec_double.h:
+#rec_double.h:#ifdef __cplusplus
+#rec_double.h:} /* extern "C" */
+#rec_double.h:#endif
+#rec_double.h:
+#rec_double.h:#endif /* ndef REC_DOUBLE_H_INCLUDED */
+#rec_double.h:
+#rec_double.h:/*
+#rec_double.h:  Local Variables:
+#rec_double.h:  tab-width: 3
+#rec_double.h:  end:
+#rec_double.h:*/
+
+
+#rec_long.c:const char rec_long_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#rec_long.c:/*********************************************************************
+#rec_long.c: *
+#rec_long.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_long.c: *
+#rec_long.c: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_long.c: *
+#rec_long.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_long.c: *                Privoxy team. http://www.privoxy.org/
+#rec_long.c: *
+#rec_long.c: *                This program is free software; you can redistribute it
+#rec_long.c: *                and/or modify it under the terms of the GNU General
+#rec_long.c: *                Public License as published by the Free Software
+#rec_long.c: *                Foundation; either version 2 of the License, or (at
+#rec_long.c: *                your option) any later version.
+#rec_long.c: *
+#rec_long.c: *                This program is distributed in the hope that it will
+#rec_long.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_long.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_long.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_long.c: *                License for more details.
+#rec_long.c: *
+#rec_long.c: *                The GNU General Public License should be included with
+#rec_long.c: *                this file.  If not, you can view it at
+#rec_long.c: *                http://www.gnu.org/copyleft/gpl.html
+#rec_long.c: *                or write to the Free Software Foundation, Inc., 59
+#rec_long.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_long.c: *
+#rec_long.c: * VI users                :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_long.c: *                                         and edit IJB, correctly.
+#rec_long.c: *
+#rec_long.c: * Revisions   :
+#rec_long.c: *    $Log: contrib.sh,v $
+#rec_long.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_long.c: *    name change related issues
+#rec_long.c: *
+#rec_long.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_long.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_long.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_long.c: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_long.c: *    corrupted).  This script will expand all files needed to create the
+#rec_long.c: *    linked list modules and an example program.  Please see the README.
+#rec_long.c: *    Feed back is welcomed.  Enjoy.
+#rec_long.c: *
+#rec_long.c: *
+#rec_long.c: *********************************************************************/
+#rec_long.c:\f
+#rec_long.c:
+#rec_long.c:#include <malloc.h>
+#rec_long.c:#include <stdio.h>
+#rec_long.c:#include <stdlib.h>
+#rec_long.c:#include <string.h>
+#rec_long.c:
+#rec_long.c:#include "gen_list.h"
+#rec_long.c:#include "rec_long.h"
+#rec_long.c:
+#rec_long.c:const char rec_long_h_rcs[] = REC_LONG_H_VERSION;
+#rec_long.c:
+#rec_long.c:
+#rec_long.c:static const rec_method rec_long_vtable[] =
+#rec_long.c:{
+#rec_long.c:   (rec_method)derived_rec_long_copy_construct,
+#rec_long.c:   (rec_method)derived_rec_long_destruct,
+#rec_long.c:   (rec_method)derived_rec_long_stream,
+#rec_long.c:   (rec_method)derived_rec_long_equal
+#rec_long.c:};
+#rec_long.c:
+#rec_long.c:
+#rec_long.c:/*********************************************************************
+#rec_long.c: *
+#rec_long.c: * Function    :  derived_rec_long_construct
+#rec_long.c: *
+#rec_long.c: * Description :  A simple derived record class that contains 1 string.
+#rec_long.c: *
+#rec_long.c: * Parameters  :
+#rec_long.c: *          1  :  The record
+#rec_long.c: *          2  :  The string to contain.
+#rec_long.c: *
+#rec_long.c: * Returns     :  A pointer to the constructed record.
+#rec_long.c: *
+#rec_long.c: *********************************************************************/
+#rec_long.c:struct derived_rec_long *derived_rec_long_construct( const long _contents )
+#rec_long.c:{
+#rec_long.c:   struct derived_rec_long *this_rec = (struct derived_rec_long *)gen_list_rec_construct(
+#rec_long.c:           ISA_LONG,
+#rec_long.c:           sizeof( struct derived_rec_long ),
+#rec_long.c:           rec_long_vtable
+#rec_long.c:   );
+#rec_long.c:
+#rec_long.c:   this_rec->contents = _contents;
+#rec_long.c:
+#rec_long.c:   LIST_SHOW( printf( "\
+#rec_long.c:\t\tlong construct new rec\t\t\t\t= %p
+#rec_long.c:\t\tlong construct new rec contents\t= %d\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_long.c:
+#rec_long.c:   return( this_rec );
+#rec_long.c:
+#rec_long.c:}
+#rec_long.c:
+#rec_long.c:
+#rec_long.c:/*********************************************************************
+#rec_long.c: *
+#rec_long.c: * Function    :  derived_rec_long_copy_construct
+#rec_long.c: *
+#rec_long.c: * Description :  Copies one long record to another.
+#rec_long.c: *
+#rec_long.c: * Parameters  :
+#rec_long.c: *          1  :  Existing record.
+#rec_long.c: *                         2       :  Copy record.
+#rec_long.c: *
+#rec_long.c: * Returns     :  The newly constructed copy record.
+#rec_long.c: *
+#rec_long.c: *********************************************************************/
+#rec_long.c:struct derived_rec_long *derived_rec_long_copy_construct( const struct derived_rec_long *this_rec )
+#rec_long.c:{
+#rec_long.c:   struct derived_rec_long *copy_rec = (struct derived_rec_long *)gen_list_rec_copy_construct( (struct gen_list_rec *)this_rec );
+#rec_long.c:   copy_rec->contents = - this_rec->contents;
+#rec_long.c:
+#rec_long.c:   LIST_SHOW( printf( "\
+#rec_long.c:\t\tlong copy construct new gen rec\t\t\t\t= %p => %p
+#rec_long.c:\t\tlong copy construct new gen rec contents\t= %d\n\n", (const void *)this_rec, (const void *)copy_rec, copy_rec->contents ) );
+#rec_long.c:
+#rec_long.c:   return( copy_rec );
+#rec_long.c:
+#rec_long.c:}
+#rec_long.c:
+#rec_long.c:
+#rec_long.c:/*********************************************************************
+#rec_long.c: *
+#rec_long.c: * Function    :  derived_rec_long_destruct        
+#rec_long.c: *
+#rec_long.c: * Description :  Destruct the long record.
+#rec_long.c: *
+#rec_long.c: * Parameters  :
+#rec_long.c: *          1  :  The record.
+#rec_long.c: *
+#rec_long.c: * Returns     :  NULL
+#rec_long.c: *
+#rec_long.c: *********************************************************************/
+#rec_long.c:struct derived_rec_long *derived_rec_long_destruct( struct derived_rec_long *this_rec )
+#rec_long.c:{
+#rec_long.c:   LIST_SHOW( printf( "\
+#rec_long.c:\t\tlong destruct this_rec\t\t\t\t= %p
+#rec_long.c:\t\tlong destruct this_rec->contents\t= %d\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_long.c:
+#rec_long.c:   this_rec->contents = -1;
+#rec_long.c:   return( (struct derived_rec_long *)gen_list_rec_destruct( (struct gen_list_rec *)this_rec ) );
+#rec_long.c:
+#rec_long.c:}
+#rec_long.c:
+#rec_long.c:
+#rec_long.c:/*********************************************************************
+#rec_long.c: *
+#rec_long.c: * Function    :  derived_rec_long_stream
+#rec_long.c: *
+#rec_long.c: * Description :  Displays all long attributes on the STDOUT stream.
+#rec_long.c: *
+#rec_long.c: * Parameters  :
+#rec_long.c: *          1  :  The record.
+#rec_long.c: *
+#rec_long.c: * Returns     :  The record.
+#rec_long.c: *
+#rec_long.c: *********************************************************************/
+#rec_long.c:const struct derived_rec_long *derived_rec_long_stream( const struct derived_rec_long *this_rec )
+#rec_long.c:{
+#rec_long.c:   this_rec = (struct derived_rec_long *)gen_list_rec_stream(
+#rec_long.c:           (struct gen_list_rec *)this_rec
+#rec_long.c:   );
+#rec_long.c:   LIST_SHOW( printf( "\
+#rec_long.c:\t\tlong stream this_rec\t\t\t\t\t= %p
+#rec_long.c:\t\tlong stream this_rec->contents\t= %d\n\n", (const void *)this_rec, this_rec->contents ) );
+#rec_long.c:
+#rec_long.c:   return( this_rec );
+#rec_long.c:
+#rec_long.c:}
+#rec_long.c:
+#rec_long.c:
+#rec_long.c:/*********************************************************************
+#rec_long.c: *
+#rec_long.c: * Function    :  derived_rec_long_equal
+#rec_long.c: *
+#rec_long.c: * Description :  Compares two long records to see if they are equal.
+#rec_long.c: *
+#rec_long.c: * Parameters  :
+#rec_long.c: *          1  :  A record.
+#rec_long.c: *          2  :  Another record.
+#rec_long.c: *
+#rec_long.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#rec_long.c: *
+#rec_long.c: *********************************************************************/
+#rec_long.c:int derived_rec_long_equal( const struct derived_rec_long *this_rec, const struct derived_rec_long *eq_rec )
+#rec_long.c:{
+#rec_long.c:   if ( ! gen_list_rec_equal( (const struct gen_list_rec *)this_rec, (struct gen_list_rec *)eq_rec ) )
+#rec_long.c:   {
+#rec_long.c:           return( 0 );
+#rec_long.c:   }
+#rec_long.c:   return( this_rec->contents == eq_rec->contents );
+#rec_long.c:
+#rec_long.c:}
+
+
+#rec_long.h:#ifndef REC_LONG_H_INCLUDED
+#rec_long.h:#define REC_LONG_H_INCLUDED
+#rec_long.h:#define REC_LONG_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#rec_long.h:/*********************************************************************
+#rec_long.h: *
+#rec_long.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_long.h: *
+#rec_long.h: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_long.h: *
+#rec_long.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_long.h: *                Privoxy team. http://www.privoxy.org/
+#rec_long.h: *
+#rec_long.h: *                This program is free software; you can redistribute it
+#rec_long.h: *                and/or modify it under the terms of the GNU General
+#rec_long.h: *                Public License as published by the Free Software
+#rec_long.h: *                Foundation; either version 2 of the License, or (at
+#rec_long.h: *                your option) any later version.
+#rec_long.h: *
+#rec_long.h: *                This program is distributed in the hope that it will
+#rec_long.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_long.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_long.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_long.h: *                License for more details.
+#rec_long.h: *
+#rec_long.h: *                The GNU General Public License should be included with
+#rec_long.h: *                this file.  If not, you can view it at
+#rec_long.h: *                http://www.gnu.org/copyleft/gpl.html
+#rec_long.h: *                or write to the Free Software Foundation, Inc., 59
+#rec_long.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_long.h: *
+#rec_long.h: * VI users                :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_long.h: *                                         and edit IJB, correctly.
+#rec_long.h: *
+#rec_long.h: * Revisions   :
+#rec_long.h: *    $Log: contrib.sh,v $
+#rec_long.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_long.h: *    name change related issues
+#rec_long.h: *
+#rec_long.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_long.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_long.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_long.h: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_long.h: *    corrupted).  This script will expand all files needed to create the
+#rec_long.h: *    linked list modules and an example program.  Please see the README.
+#rec_long.h: *    Feed back is welcomed.  Enjoy.
+#rec_long.h: *
+#rec_long.h: *
+#rec_long.h: *********************************************************************/
+#rec_long.h:\f
+#rec_long.h:
+#rec_long.h:#ifdef __cplusplus
+#rec_long.h:extern "C" {
+#rec_long.h:#endif
+#rec_long.h:
+#rec_long.h:
+#rec_long.h:struct derived_rec_long
+#rec_long.h:{
+#rec_long.h:   /* private: */
+#rec_long.h:   struct gen_list_rec parent_rec;
+#rec_long.h:   long contents;
+#rec_long.h:};
+#rec_long.h:
+#rec_long.h:/* public: */
+#rec_long.h:extern struct derived_rec_long *   derived_rec_long_construct( const long _contents );
+#rec_long.h:extern struct derived_rec_long *   derived_rec_long_copy_construct( const struct derived_rec_long *this_rec );
+#rec_long.h:extern struct derived_rec_long *   derived_rec_long_destruct( struct derived_rec_long *this_rec );
+#rec_long.h:extern const struct derived_rec_long *derived_rec_long_stream( const struct derived_rec_long *this_rec );
+#rec_long.h:extern int                                                         derived_rec_long_equal( const struct derived_rec_long *this_rec, const struct derived_rec_long *eq_rec );
+#rec_long.h:
+#rec_long.h:/* struct/class COMPLETE */
+#rec_long.h:
+#rec_long.h:
+#rec_long.h:#ifdef __cplusplus
+#rec_long.h:} /* extern "C" */
+#rec_long.h:#endif
+#rec_long.h:
+#rec_long.h:#endif /* ndef REC_LONG_H_INCLUDED */
+#rec_long.h:
+#rec_long.h:/*
+#rec_long.h:  Local Variables:
+#rec_long.h:  tab-width: 3
+#rec_long.h:  end:
+#rec_long.h:*/
+
+
+#rec_malloc_police.c:const char rec_malloc_police_rcs[] = "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $";
+#rec_malloc_police.c:/*********************************************************************
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_malloc_police.c: *                                                This class helps to build a list of allocated and
+#rec_malloc_police.c: *                                                freed memory.  When the program exits, we will print
+#rec_malloc_police.c: *                                                a list of all memory that was allocated, but never
+#rec_malloc_police.c: *                                                freed.  This could be most helpful to developers
+#rec_malloc_police.c: *                                                and debugers.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_malloc_police.c: *                Privoxy team. http://www.privoxy.org/
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *                This program is free software; you can redistribute it
+#rec_malloc_police.c: *                and/or modify it under the terms of the GNU General
+#rec_malloc_police.c: *                Public License as published by the Free Software
+#rec_malloc_police.c: *                Foundation; either version 2 of the License, or (at
+#rec_malloc_police.c: *                your option) any later version.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *                This program is distributed in the hope that it will
+#rec_malloc_police.c: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_malloc_police.c: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_malloc_police.c: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_malloc_police.c: *                License for more details.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *                The GNU General Public License should be included with
+#rec_malloc_police.c: *                this file.  If not, you can view it at
+#rec_malloc_police.c: *                http://www.gnu.org/copyleft/gpl.html
+#rec_malloc_police.c: *                or write to the Free Software Foundation, Inc., 59
+#rec_malloc_police.c: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * VI users               :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_malloc_police.c: *                                                and edit IJB, correctly.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Revisions   :
+#rec_malloc_police.c: *    $Log: contrib.sh,v $
+#rec_malloc_police.c: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_malloc_police.c: *    name change related issues
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_malloc_police.c: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_malloc_police.c: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_malloc_police.c: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_malloc_police.c: *    corrupted).  This script will expand all files needed to create the
+#rec_malloc_police.c: *    linked list modules and an example program.  Please see the README.
+#rec_malloc_police.c: *    Feed back is welcomed.  Enjoy.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *********************************************************************/
+#rec_malloc_police.c:\f
+#rec_malloc_police.c:
+#rec_malloc_police.c:#include <stdio.h>
+#rec_malloc_police.c:
+#rec_malloc_police.c:#include "gen_list.h"
+#rec_malloc_police.c:#include "malloc_police.h"
+#rec_malloc_police.c:#include "rec_malloc_police.h"
+#rec_malloc_police.c:
+#rec_malloc_police.c:const char rec_malloc_police_h_rcs[] = REC_MALLOC_POLICE_H_VERSION;
+#rec_malloc_police.c:
+#rec_malloc_police.c:
+#rec_malloc_police.c:static const rec_method rec_malloc_police_vtable[] =
+#rec_malloc_police.c:{
+#rec_malloc_police.c:  (rec_method)derived_rec_malloc_police_copy_construct,
+#rec_malloc_police.c:  (rec_method)derived_rec_malloc_police_destruct,
+#rec_malloc_police.c:  (rec_method)derived_rec_malloc_police_stream,
+#rec_malloc_police.c:  (rec_method)derived_rec_malloc_police_equal
+#rec_malloc_police.c:};
+#rec_malloc_police.c:
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*********************************************************************
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Function    :  derived_rec_malloc_police_construct
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Description :  A simple derived record class that contains 1 string.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Parameters  :
+#rec_malloc_police.c: *          1  :  The record
+#rec_malloc_police.c: *          2  :  The string to contain.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Returns     :  A pointer to the constructed record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *********************************************************************/
+#rec_malloc_police.c:struct derived_rec_malloc_police *derived_rec_malloc_police_construct( void *_alloced_addr, char *_source_where, size_t _sz )
+#rec_malloc_police.c:{
+#rec_malloc_police.c:  struct derived_rec_malloc_police *this_rec;
+#rec_malloc_police.c:  list_is_quiet ++;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  this_rec = (struct derived_rec_malloc_police *)gen_list_rec_construct(
+#rec_malloc_police.c:          ISA_MALLOC_POLICE,
+#rec_malloc_police.c:          sizeof( struct derived_rec_malloc_police ),
+#rec_malloc_police.c:          rec_malloc_police_vtable
+#rec_malloc_police.c:  );
+#rec_malloc_police.c:
+#rec_malloc_police.c:  this_rec->alloced_addr  = _alloced_addr;
+#rec_malloc_police.c:  this_rec->source_where  = STRDUP( _source_where );
+#rec_malloc_police.c:  this_rec->sz                            = _sz;
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*        LIST_SHOW( printf( "\ */
+#rec_malloc_police.c:/* \t\tmalloc_police construct new rec\t\t\t\t\t= %p */
+#rec_malloc_police.c:/* \t\tmalloc_police construct new rec alloced_addr = %p */
+#rec_malloc_police.c:/* \t\tmalloc_police construct new rec source_where = %s */
+#rec_malloc_police.c:/* \t\tmalloc_police construct new rec sz\t\t\t\t\t= %ld\n\n", */
+#rec_malloc_police.c:/*                          (const void *)this_rec, */
+#rec_malloc_police.c:/*                          this_rec->alloced_addr, */
+#rec_malloc_police.c:/*                          this_rec->source_where, */
+#rec_malloc_police.c:/*                          this_rec->sz */
+#rec_malloc_police.c:/*        ) ); */
+#rec_malloc_police.c:
+#rec_malloc_police.c:  list_is_quiet --;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  return( this_rec );
+#rec_malloc_police.c:
+#rec_malloc_police.c:}
+#rec_malloc_police.c:
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*********************************************************************
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Function    :  derived_rec_malloc_police_copy_construct
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Description :  Copies one malloc_police record to another.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Parameters  :
+#rec_malloc_police.c: *          1  :  Existing record.
+#rec_malloc_police.c: *                                2       :  Copy record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Returns     :  The newly constructed copy record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *********************************************************************/
+#rec_malloc_police.c:struct derived_rec_malloc_police *derived_rec_malloc_police_copy_construct( const struct derived_rec_malloc_police *this_rec )
+#rec_malloc_police.c:{
+#rec_malloc_police.c:  int len;
+#rec_malloc_police.c:  char *new_contents;
+#rec_malloc_police.c:  struct derived_rec_malloc_police *copy_rec;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  list_is_quiet ++;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  copy_rec = (struct derived_rec_malloc_police *)gen_list_rec_copy_construct( (struct gen_list_rec *)this_rec );
+#rec_malloc_police.c:
+#rec_malloc_police.c:  copy_rec->alloced_addr  = this_rec->alloced_addr;
+#rec_malloc_police.c:  copy_rec->source_where  = STRDUP( this_rec->source_where );
+#rec_malloc_police.c:  copy_rec->sz                            = this_rec->sz;
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*        LIST_SHOW( printf( "\ */
+#rec_malloc_police.c:/* \t\tmalloc_police copy construct new gen rec = %p => %p */
+#rec_malloc_police.c:/* \t\tmalloc_police copy construct new gen rec alloced_addr = %p */
+#rec_malloc_police.c:/* \t\tmalloc_police copy construct new gen rec source_where = %s */
+#rec_malloc_police.c:/* \t\tmalloc_police copy construct new gen rec sz\t\t\t\t\t= %ld\n\n", */
+#rec_malloc_police.c:/*                          (const void *)this_rec, (const void *)copy_rec, */
+#rec_malloc_police.c:/*                          copy_rec->alloced_addr, */
+#rec_malloc_police.c:/*                          copy_rec->source_where, */
+#rec_malloc_police.c:/*                          copy_rec->sz */
+#rec_malloc_police.c:/*        ) ); */
+#rec_malloc_police.c:
+#rec_malloc_police.c:  list_is_quiet --;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  return( copy_rec );
+#rec_malloc_police.c:
+#rec_malloc_police.c:}
+#rec_malloc_police.c:
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*********************************************************************
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Function    :  derived_rec_malloc_police_destruct      
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Description :  Destruct the malloc_police record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Parameters  :
+#rec_malloc_police.c: *          1  :  The record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Returns     :  NULL
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *********************************************************************/
+#rec_malloc_police.c:struct derived_rec_malloc_police *derived_rec_malloc_police_destruct( struct derived_rec_malloc_police *this_rec )
+#rec_malloc_police.c:{
+#rec_malloc_police.c:  struct derived_rec_malloc_police *d;
+#rec_malloc_police.c:  list_is_quiet ++;
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*        LIST_SHOW( printf( "\ */
+#rec_malloc_police.c:/* \t\tmalloc_police destruct this_rec\t\t\t\t\t\t= %p */
+#rec_malloc_police.c:/* \t\tmalloc_police destruct this_rec->alloced_addr\t= %p */
+#rec_malloc_police.c:/* \t\tmalloc_police destruct this_rec->source_where\t= %s, */
+#rec_malloc_police.c:/* \t\tmalloc_police destruct this_rec->sz\t\t\t\t\t= %ld\n\n", */
+#rec_malloc_police.c:/*                          (const void *)this_rec, */
+#rec_malloc_police.c:/*                          this_rec->alloced_addr, */
+#rec_malloc_police.c:/*                          this_rec->source_where, */
+#rec_malloc_police.c:/*                          this_rec->sz */
+#rec_malloc_police.c:/*        ) ); */
+#rec_malloc_police.c:
+#rec_malloc_police.c:  memset( this_rec->source_where, '!', strlen( this_rec->source_where ) );
+#rec_malloc_police.c:  FREE( this_rec->source_where );
+#rec_malloc_police.c:
+#rec_malloc_police.c:  d = (struct derived_rec_malloc_police *)gen_list_rec_destruct( (struct gen_list_rec *)this_rec );
+#rec_malloc_police.c:  list_is_quiet --;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  return( d );
+#rec_malloc_police.c:
+#rec_malloc_police.c:}
+#rec_malloc_police.c:
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*********************************************************************
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Function    :  derived_rec_malloc_police_stream
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Description :  Displays all malloc_police attributes on the STDOUT stream.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Parameters  :
+#rec_malloc_police.c: *          1  :  The record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Returns     :  The record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *********************************************************************/
+#rec_malloc_police.c:const struct derived_rec_malloc_police *derived_rec_malloc_police_stream( const struct derived_rec_malloc_police *this_rec )
+#rec_malloc_police.c:{
+#rec_malloc_police.c:  list_is_quiet ++;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  this_rec = (struct derived_rec_malloc_police *)gen_list_rec_stream(
+#rec_malloc_police.c:          (struct gen_list_rec *)this_rec
+#rec_malloc_police.c:  );
+#rec_malloc_police.c:  LIST_SHOW( printf( "\
+#rec_malloc_police.c:\t\tmalloc_police stream this_rec\t\t\t\t\t= %p
+#rec_malloc_police.c:\t\tmalloc_police stream this_rec->alloced_addr\t= %p
+#rec_malloc_police.c:\t\tmalloc_police stream this_rec->source_where\t= %s
+#rec_malloc_police.c:\t\tmalloc_police stream this_rec->sz\t\t\t\t= %ld\n\n",
+#rec_malloc_police.c:                                                   (const void *)this_rec,
+#rec_malloc_police.c:                                                   this_rec->alloced_addr,
+#rec_malloc_police.c:                                                   this_rec->source_where,
+#rec_malloc_police.c:                                                   this_rec->sz
+#rec_malloc_police.c:  ) );
+#rec_malloc_police.c:
+#rec_malloc_police.c:  list_is_quiet --;
+#rec_malloc_police.c:  return( this_rec );
+#rec_malloc_police.c:
+#rec_malloc_police.c:}
+#rec_malloc_police.c:
+#rec_malloc_police.c:
+#rec_malloc_police.c:/*********************************************************************
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Function    :  derived_rec_malloc_police_equal
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Description :  Compares two malloc_police records to see if they are equal.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Parameters  :
+#rec_malloc_police.c: *          1  :  A record.
+#rec_malloc_police.c: *          2  :  Another record.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: * Returns     :  0 => NOT EQUAL, anything else is EQUAL.
+#rec_malloc_police.c: *
+#rec_malloc_police.c: *********************************************************************/
+#rec_malloc_police.c:int derived_rec_malloc_police_equal( const struct derived_rec_malloc_police *this_rec, const struct derived_rec_malloc_police *eq_rec )
+#rec_malloc_police.c:{
+#rec_malloc_police.c:  list_is_quiet ++;
+#rec_malloc_police.c:
+#rec_malloc_police.c:  if ( ! gen_list_rec_equal( (const struct gen_list_rec *)this_rec, (struct gen_list_rec *)eq_rec ) )
+#rec_malloc_police.c:  {
+#rec_malloc_police.c:          return( 0 );
+#rec_malloc_police.c:  }
+#rec_malloc_police.c:
+#rec_malloc_police.c:  list_is_quiet --;
+#rec_malloc_police.c:  return( this_rec->alloced_addr == eq_rec->alloced_addr );
+#rec_malloc_police.c:
+#rec_malloc_police.c:}
+
+
+#rec_malloc_police.h:#ifndef REC_MALLOC_POLICE_H_INCLUDED
+#rec_malloc_police.h:#define REC_MALLOC_POLICE_H_INCLUDED
+#rec_malloc_police.h:#define REC_MALLOC_POLICE_H_VERSION "$Id: contrib.sh,v 1.2 2002/03/24 13:25:43 swa Exp $"
+#rec_malloc_police.h:/*********************************************************************
+#rec_malloc_police.h: *
+#rec_malloc_police.h: * File        :  $Source: /cvsroot/ijbswa/current/contrib.sh,v $
+#rec_malloc_police.h: *
+#rec_malloc_police.h: * Purpose     :  A "derived class" of gen_list_rec.
+#rec_malloc_police.h: *                                                This class helps to build a list of allocated and
+#rec_malloc_police.h: *                                                freed memory.  When the program exits, we will print
+#rec_malloc_police.h: *                                                a list of all memory that was allocated, but never
+#rec_malloc_police.h: *                                                freed.  This could be most helpful to developers
+#rec_malloc_police.h: *                                                and debugers.
+#rec_malloc_police.h: *
+#rec_malloc_police.h: * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#rec_malloc_police.h: *                Privoxy team. http://www.privoxy.org/
+#rec_malloc_police.h: *
+#rec_malloc_police.h: *                This program is free software; you can redistribute it
+#rec_malloc_police.h: *                and/or modify it under the terms of the GNU General
+#rec_malloc_police.h: *                Public License as published by the Free Software
+#rec_malloc_police.h: *                Foundation; either version 2 of the License, or (at
+#rec_malloc_police.h: *                your option) any later version.
+#rec_malloc_police.h: *
+#rec_malloc_police.h: *                This program is distributed in the hope that it will
+#rec_malloc_police.h: *                be useful, but WITHOUT ANY WARRANTY; without even the
+#rec_malloc_police.h: *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#rec_malloc_police.h: *                PARTICULAR PURPOSE.  See the GNU General Public
+#rec_malloc_police.h: *                License for more details.
+#rec_malloc_police.h: *
+#rec_malloc_police.h: *                The GNU General Public License should be included with
+#rec_malloc_police.h: *                this file.  If not, you can view it at
+#rec_malloc_police.h: *                http://www.gnu.org/copyleft/gpl.html
+#rec_malloc_police.h: *                or write to the Free Software Foundation, Inc., 59
+#rec_malloc_police.h: *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#rec_malloc_police.h: *
+#rec_malloc_police.h: * VI users               :       Please "set tabstop=3 shiftwidth=3" to view this file,
+#rec_malloc_police.h: *                                                and edit IJB, correctly.
+#rec_malloc_police.h: *
+#rec_malloc_police.h: * Revisions   :
+#rec_malloc_police.h: *    $Log: contrib.sh,v $
+#rec_malloc_police.h: *    Revision 1.2  2002/03/24 13:25:43  swa
+#rec_malloc_police.h: *    name change related issues
+#rec_malloc_police.h: *
+#rec_malloc_police.h: *    Revision 1.1  2001/12/07 01:54:50  iwanttokeepanon
+#rec_malloc_police.h: *    A contribution/recomendation to the IJBSWA group for a generic doubly
+#rec_malloc_police.h: *    linked list.  This file is a home brew "bash tar" (I cannot create a
+#rec_malloc_police.h: *    contrib directory and I cannot upload a tarball ... it gets
+#rec_malloc_police.h: *    corrupted).  This script will expand all files needed to create the
+#rec_malloc_police.h: *    linked list modules and an example program.  Please see the README.
+#rec_malloc_police.h: *    Feed back is welcomed.  Enjoy.
+#rec_malloc_police.h: *
+#rec_malloc_police.h: *
+#rec_malloc_police.h: *********************************************************************/
+#rec_malloc_police.h:\f
+#rec_malloc_police.h:
+#rec_malloc_police.h:#ifdef __cplusplus
+#rec_malloc_police.h:extern "C" {
+#rec_malloc_police.h:#endif
+#rec_malloc_police.h:
+#rec_malloc_police.h:
+#rec_malloc_police.h:struct derived_rec_malloc_police
+#rec_malloc_police.h:{
+#rec_malloc_police.h:  /* private: */
+#rec_malloc_police.h:  struct  gen_list_rec parent_rec;
+#rec_malloc_police.h:  void            *alloced_addr;
+#rec_malloc_police.h:  char            *source_where;
+#rec_malloc_police.h:  size_t  sz;
+#rec_malloc_police.h:};
+#rec_malloc_police.h:
+#rec_malloc_police.h:/* public: */
+#rec_malloc_police.h:extern struct derived_rec_malloc_police * derived_rec_malloc_police_construct( void *_alloced_addr, char *_source_where, size_t _sz );
+#rec_malloc_police.h:extern struct derived_rec_malloc_police * derived_rec_malloc_police_copy_construct( const struct derived_rec_malloc_police *this_rec );
+#rec_malloc_police.h:extern struct derived_rec_malloc_police * derived_rec_malloc_police_destruct( struct derived_rec_malloc_police *this_rec );
+#rec_malloc_police.h:extern const struct derived_rec_malloc_police *derived_rec_malloc_police_stream( const struct derived_rec_malloc_police *this_rec );
+#rec_malloc_police.h:extern int                                                                                        derived_rec_malloc_police_equal( const struct derived_rec_malloc_police *this_rec, const struct derived_rec_malloc_police *eq_rec );
+#rec_malloc_police.h:
+#rec_malloc_police.h:/* struct/class COMPLETE */
+#rec_malloc_police.h:
+#rec_malloc_police.h:
+#rec_malloc_police.h:#ifdef __cplusplus
+#rec_malloc_police.h:} /* extern "C" */
+#rec_malloc_police.h:#endif
+#rec_malloc_police.h:
+#rec_malloc_police.h:
+#rec_malloc_police.h:#endif /* ndef REC_MALLOC_POLICE_H_INCLUDED */
+#rec_malloc_police.h:
+#rec_malloc_police.h:/*
+#rec_malloc_police.h:  Local Variables:
+#rec_malloc_police.h:  tab-width: 3
+#rec_malloc_police.h:  end:
+#rec_malloc_police.h:*/
+
+
+###########################################################################
+##  Description:                       makeInsertableFile
+##             Use this function to make a file suitable for insertion into this
+##             script.  This file (x), will contain all of the files listed.
+##
+##  Inputs :
+##             None
+##
+##  Outputs :
+##             Return status:  (0) - Everything is Okay, anything else is an error
+###########################################################################
+
+function makeInsertableFile {
+
+       rm -f x
+
+       for i in ${fileList}; do
+               sed -e "s/^/#${i}:/" ${i} >> x
+               echo "" >> x
+               echo "" >> x
+       done
+
+       return 0
+
+}
+
+
+#
+#Local Variables:
+#tab-width: 3
+#end:
+#
diff --git a/cookiefile b/cookiefile
deleted file mode 100644 (file)
index f17f4b0..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# This is /etc/junkbuster/cookefile which was put here by a junkbuster rpm
-#
-# Last modified on Sun Jan 31 22:36:03 1999 (CEST)
-#
-# --------------------------------------------------------------------------
-#
-# Newest version is always available from 
-#
-#          http://www.waldherr.org/cookiefile
-#
-# Read http://www.waldherr.org/junkbuster/update.shtml on how to keep
-# this file up-to-date.
-#
-# For more detail, see http://www.junkbusters.com/ht/en/ijbfaq.html#cookies
-#
-# Empty lines and lines beginning with a # are ignored.
-# To permit an entire site to set cookies, simply include its domain name:
-# really-trustyworthy-people.org
-#
-# You can allow cookies out, but stop them coming in:
-# >send-user-cookies.com
-#
-#>egroups.com
-#>tvguide.com
-#>wired.com/news/
-#americanexpress.com
-#cnn.com
-#www.nytimes.com
-#yahoo.com
-#amazon.de
-#amazon.co.uk
-#slashdot.org
-#www.palmgear.com
-#onelist.com
-#freshmeat.net
-
-# Sites that need cookies
-javasoft.com
-sun.com
-msdn.microsoft.com
-sourceforge.net
-yahoo.com
-anonymizer.com
-
-# Experimenting
-ashleycars.co.uk
-
-# Shopping
-dabs.com
-overclockers.co.uk
-worldpay.com   # for quietpc.com
-jungle.com
-scan.co.uk
-
-#Shopping: Micro Warehouse's site
-#inmac.co.uk
-#technomatic.co.uk
-
-# This is stupid.  Without these two entries, the link from McAfee's website
-# to their online UK shop gives a 500 server error.
-#mcafee.com
-#mcafeestoreuk.beyond.com
-
-
-
-
index 4568ea8..b28dd6a 100644 (file)
--- a/cygwin.h
+++ b/cygwin.h
@@ -1,16 +1,16 @@
-#ifndef _CYGWIN_H
-#define _CYGWIN_H
-#define CYGWIN_H_VERSION "$Id: cygwin.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef CYGWIN_H_INCLUDED
+#define CYGWIN_H_INCLUDED
+#define CYGWIN_H_VERSION "$Id: cygwin.h,v 1.3 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/cygwin.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/cygwin.h,v $
  *
  * Purpose     :  The windows.h file seems to be a *tad* different, so I
  *                will bridge the gaps here.  Perhaps I should convert the
  *                latest SDK too?  Shudder, I think not.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: cygwin.h,v $
+ *    Revision 1.3  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.2  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:51  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 
@@ -53,7 +63,7 @@
  */
 
 #endif /* def __MINGW32__ */
-#endif /* ndef _CYGWIN_H */
+#endif /* ndef CYGWIN_H_INCLUDED */
 
 
 /*
diff --git a/deanimate.c b/deanimate.c
new file mode 100644 (file)
index 0000000..59ed56e
--- /dev/null
@@ -0,0 +1,504 @@
+const char deanimate_rcs[] = "$Id: deanimate.c,v 1.11 2002/03/26 22:29:54 swa Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/deanimate.c,v $
+ *
+ * Purpose     :  Declares functions to deanimate GIF images on the fly.
+ *                
+ *                Functions declared include: gif_deanimate, buf_free,
+ *                buf_copy,  buf_getbyte, gif_skip_data_block, and
+ *                gif_extract_image
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 by the the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the GIF file format specification (see
+ *                http://tronche.com/computer-graphics/gif/gif89a.html)
+ *                and ideas from the Image::DeAnim Perl module by
+ *                Ken MacFarlane, <ksm+cpan@universal.dca.net>
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: deanimate.c,v $
+ *    Revision 1.11  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.10  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.9  2002/03/13 00:27:04  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.8  2002/03/09 19:42:47  jongfoster
+ *    Fixing more warnings
+ *
+ *    Revision 1.7  2002/03/08 17:46:04  jongfoster
+ *    Fixing int/size_t warnings
+ *
+ *    Revision 1.6  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.5  2001/09/10 10:16:06  oes
+ *    Silenced compiler warnings
+ *
+ *    Revision 1.4  2001/07/18 12:28:49  oes
+ *    - Added feature for extracting the first frame
+ *      to gif_deanimate
+ *    - Separated image buffer extension into buf_extend
+ *    - Extended gif deanimation to GIF87a (untested!)
+ *    - Cosmetics
+ *
+ *    Revision 1.3  2001/07/15 13:57:50  jongfoster
+ *    Adding #includes string.h and miscutil.h
+ *
+ *    Revision 1.2  2001/07/13 13:46:20  oes
+ *    Introduced GIF deanimation feature
+ *
+ *
+ **********************************************************************/
+\f
+
+#include "config.h"
+
+#include <string.h>
+#include <fcntl.h>
+
+#include "project.h"
+#include "deanimate.h"
+#include "miscutil.h"
+
+const char deanimate_h_rcs[] = DEANIMATE_H_VERSION;
+
+/*********************************************************************
+ * 
+ * Function    :  buf_free
+ *
+ * Description :  Safely frees a struct binbuffer
+ *
+ * Parameters  :
+ *          1  :  buf = Pointer to the binbuffer to be freed
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void buf_free(struct binbuffer *buf)
+{
+   if (buf == NULL) return;
+
+   if (buf->buffer != NULL)
+   {
+      free(buf->buffer);
+   }
+
+   free(buf);
+
+}
+
+
+/*********************************************************************
+ * 
+ * Function    :  buf_extend
+ *
+ * Description :  Ensure that a given binbuffer can hold a given amount
+ *                of bytes, by reallocating its buffer if necessary.
+ *                Allocate new mem in chunks of 1024 bytes, so we don't
+ *                have to realloc() too often.
+ *
+ * Parameters  :
+ *          1  :  buf = Pointer to the binbuffer
+ *          2  :  length = Desired minimum size
+ *                
+ *
+ * Returns     :  0 on success, 1 on failiure.
+ *
+ *********************************************************************/
+int buf_extend(struct binbuffer *buf, size_t length)
+{
+   char *newbuf;
+
+   if (buf->offset + length > buf->size)
+   {
+      buf->size = ((buf->size + length + (size_t)1023) & ~(size_t)1023);
+      newbuf = (char *)realloc(buf->buffer, buf->size);
+
+      if (newbuf == NULL)
+      {
+         freez(buf->buffer);
+         return 1;
+      }
+      else
+      {
+         buf->buffer = newbuf;
+         return 0;
+      }
+   }
+   return 0;
+
+}
+
+
+/*********************************************************************
+ * 
+ * Function    :  buf_copy
+ *
+ * Description :  Safely copies a given amount of bytes from one
+ *                struct binbuffer to another, advancing the
+ *                offsets appropriately.
+ *
+ * Parameters  :
+ *          1  :  src = Pointer to the source binbuffer
+ *          2  :  dst = Pointer to the destination binbuffer
+ *          3  :  length = Number of bytes to be copied
+ *
+ * Returns     :  0 on success, 1 on failiure.
+ *
+ *********************************************************************/
+int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length)
+{
+
+   /*
+    * Sanity check: Can't copy more data than we have
+    */
+   if (src->offset + length > src->size) 
+   {
+      return 1;
+   }
+
+   /*
+    * Ensure that dst can hold the new data
+    */
+   if (buf_extend(dst, length)) 
+   {
+      return 1;
+   }
+
+   /*
+    * Now that it's safe, memcpy() the desired amount of
+    * data from src to dst and adjust the offsets
+    */
+   memcpy(dst->buffer + dst->offset, src->buffer + src->offset, length);
+   src->offset += length;
+   dst->offset += length;
+
+   return 0;
+
+}
+
+
+/*********************************************************************
+ * 
+ * Function    :  buf_getbyte
+ *
+ * Description :  Safely gets a byte from a given binbuffer at a
+ *                given offset
+ *
+ * Parameters  :
+ *          1  :  src = Pointer to the source binbuffer
+ *          2  :  offset = Offset to the desired byte
+ *
+ * Returns     :  The byte on success, or 0 on failiure
+ *
+ *********************************************************************/
+unsigned char buf_getbyte(struct binbuffer *src, size_t offset)
+{
+   if (src->offset + offset < src->size)
+   {
+      return (unsigned char)*(src->buffer + src->offset + offset);
+   }
+   else
+   {
+      return '\0';
+   }
+
+}
+
+
+/*********************************************************************
+ * 
+ * Function    :  gif_skip_data_block
+ *
+ * Description :  Safely advances the offset of a given struct binbuffer
+ *                that contains a GIF image and whose offset is
+ *                positioned at the start of a data block, behind
+ *                that block.
+ *
+ * Parameters  :
+ *          1  :  buf = Pointer to the binbuffer
+ *
+ * Returns     :  0 on success, or 1 on failiure
+ *
+ *********************************************************************/
+int gif_skip_data_block(struct binbuffer *buf)
+{
+   unsigned char c;
+
+   /* 
+    * Data blocks are sequences of chunks, which are headed
+    * by a one-byte length field, with the last chunk having
+    * zero length.
+    */
+   while((c = buf_getbyte(buf, 0)) != '\0')
+   {
+      if ((buf->offset += c + 1) >= buf->size - 1)
+      {
+         return 1;
+      }
+   }
+   buf->offset++;
+
+   return 0;
+
+}
+
+
+/*********************************************************************
+ * 
+ * Function    :  gif_extract_image
+ *
+ * Description :  Safely extracts an image data block from a given
+ *                struct binbuffer that contains a GIF image and whose
+ *                offset is positioned at the start of a data block 
+ *                into a given destination binbuffer.
+ *
+ * Parameters  :
+ *          1  :  src = Pointer to the source binbuffer
+ *          2  :  dst = Pointer to the destination binbuffer
+ *
+ * Returns     :  0 on success, or 1 on failiure
+ *
+ *********************************************************************/
+int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
+{
+   unsigned char c;
+   
+   /*
+    * Remember the colormap flag and copy the image head
+    */
+   c = buf_getbyte(src, 9);
+   if (buf_copy(src, dst, 10))
+   {
+      return 1;
+   }
+
+   /*
+    * If the image has a local colormap, copy it.
+    */
+   if (c & 0x80)
+   {
+      if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1))))
+      {
+         return 1;
+      }           
+   }
+   if (buf_copy(src, dst, 1)) return 1;
+
+   /*
+    * Copy the image chunk by chunk.
+    */
+   while((c = buf_getbyte(src, 0)) != '\0')
+   {
+      if (buf_copy(src, dst, 1 + (size_t) c)) return 1;
+   }
+   if (buf_copy(src, dst, 1)) return 1;
+
+   /*
+    * Trim and rewind the dst buffer
+    */
+   if (NULL == (dst->buffer = (char *)realloc(dst->buffer, dst->offset))) return 1;
+   dst->size = dst->offset;
+   dst->offset = 0;
+
+   return(0);
+
+}
+
+/*********************************************************************
+ * 
+ * Function    :  gif_deanimate
+ *
+ * Description :  Deanimate a given GIF image, i.e. given a GIF with
+ *                an (optional) image block and an arbitrary number
+ *                of image extension blocks, produce an output GIF with
+ *                only one image block that contains the last image
+ *                (extenstion) block of the original.
+ *                Also strip Comments, Application extenstions, etc.
+ *
+ * Parameters  :
+ *          1  :  src = Pointer to the source binbuffer
+ *          2  :  dst = Pointer to the destination binbuffer
+ *          3  :  get_first_image = Flag: If set, get the first image
+ *                                        If unset (default), get the last
+ *
+ * Returns     :  0 on success, or 1 on failiure
+ *
+ *********************************************************************/
+int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image)
+{
+   unsigned char c;
+   struct binbuffer *image;
+
+   if (NULL == src || NULL == dst)
+   {
+      return 1;
+   }
+
+   c = buf_getbyte(src, 10);
+
+   /*
+    * Check & copy GIF header 
+    */
+   if (strncmp(src->buffer, "GIF89a", 6) && strncmp(src->buffer, "GIF87a", 6)) 
+   {
+      return 1;
+   }
+   else
+   {
+      if (buf_copy(src, dst, 13))
+      {
+         return 1;
+      }
+   }
+
+   /*
+    * Look for global colormap and  copy if found.
+    */
+   if(c & 0x80)
+   {
+      if (buf_copy(src, dst, (size_t) 3 * (1 << ((c & 0x07) + 1))))
+      {
+         return 1;
+      }
+   }
+
+   /*
+    * Reserve a buffer for the current image block
+    */
+   if (NULL == (image = (struct binbuffer *)zalloc(sizeof(*image))))
+   {
+      return 1;
+   }
+
+   /*
+    * Parse the GIF block by block and copy the relevant
+    * parts to dst
+    */
+   while(src->offset < src->size)
+   {
+      switch(buf_getbyte(src, 0))
+      {
+         /*
+          *  End-of-GIF Marker: Append current image and return
+          */
+      case 0x3b:
+         goto write;
+
+         /* 
+          * Image block: Extract to current image buffer.
+          */
+      case 0x2c:
+         image->offset = 0;
+         if (gif_extract_image(src, image)) goto failed;
+         if (get_first_image) goto write;
+         continue;
+
+         /*
+          * Extension block: Look at next byte and decide
+          */
+      case 0x21:
+         switch (buf_getbyte(src, 1))
+         {
+            /*
+             * Image extension: Copy extension  header and image
+             *                  to the current image buffer
+             */
+         case 0xf9:
+            image->offset = 0;
+            if (buf_copy(src, image, 8) || buf_getbyte(src, 0) != 0x2c) goto failed;
+            if (gif_extract_image(src, image)) goto failed;
+            if (get_first_image) goto write;
+            continue;
+
+            /*
+             * Application extension: Skip
+             */
+         case 0xff:
+            if ((src->offset += 14) >= src->size || gif_skip_data_block(src)) goto failed;
+            continue;
+
+            /*
+             * Comment extension: Skip
+             */
+         case 0xfe:
+            if ((src->offset += 2) >= src->size || gif_skip_data_block(src)) goto failed;
+            continue;
+
+            /*
+             * Plain text extension: Skip
+             */
+         case 0x01:
+            if ((src->offset += 15) >= src->size || gif_skip_data_block(src)) goto failed;
+            continue;
+
+            /*
+             * Ooops, what type of extension is that?
+             */
+         default:
+            goto failed;
+
+         }
+
+         /*
+          * Ooops, what type of block is that?
+          */
+      default:
+         goto failed;
+         
+      }
+   } /* -END- while src */
+
+   /*
+    * Either we got here by goto, or because the GIF is
+    * bogus and EOF was reached before an end-of-gif marker 
+    * was found.
+    */
+
+failed:
+   buf_free(image);
+   return 1;
+
+   /*
+    * Append the current image to dst and return
+    */
+
+write:
+   if (buf_copy(image, dst, image->size)) goto failed;
+   if (buf_extend(dst, 1)) goto failed;
+   *(dst->buffer + dst->offset++) = 0x3b;
+   buf_free(image);
+   return 0;
+
+}
+
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/deanimate.h b/deanimate.h
new file mode 100644 (file)
index 0000000..ede9847
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef DEANIMATE_H_INCLUDED
+#define DEANIMATE_H_INCLUDED
+#define DEANIMATE_H_VERSION "$Id: deanimate.h,v 1.7 2002/03/24 13:25:43 swa Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/deanimate.h,v $
+ *
+ * Purpose     :  Declares functions to deanimate GIF images on the fly.
+ *                
+ *                Functions declared include: gif_deanimate, buf_free
+ *                
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 Andreas S. Oesterhelt
+ *                for the Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on ideas from the Image::DeAnim Perl module by
+ *                Ken MacFarlane, <ksm+cpan@universal.dca.net>
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: deanimate.h,v $
+ *    Revision 1.7  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.6  2002/03/08 17:46:04  jongfoster
+ *    Fixing int/size_t warnings
+ *
+ *    Revision 1.5  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.4  2001/07/29 18:50:04  jongfoster
+ *    Fixing "extern C" block, and renaming #define _DEANIMATE_H
+ *
+ *    Revision 1.3  2001/07/18 12:29:05  oes
+ *    Updated prototype for gif_deanimate
+ *
+ *    Revision 1.2  2001/07/13 13:46:20  oes
+ *    Introduced GIF deanimation feature
+ *
+ *
+ *********************************************************************/
+\f
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A struct that holds a buffer, a read/write offset,
+ * and the buffer's capacity.
+ */
+struct binbuffer
+{
+   char *buffer; 
+   size_t offset;   
+   size_t size;    
+};
+
+/*
+ * Function prototypes
+ */
+extern int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image);
+extern void buf_free(struct binbuffer *buf);
+
+/* 
+ * Revision control strings from this header and associated .c file
+ */
+extern const char deanimate_rcs[];
+extern const char deanimate_h_rcs[];
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef DEANIMATE_H_INCLUDED */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..ceaf32a
--- /dev/null
@@ -0,0 +1,44 @@
+privoxy (2.9.15-beta-0) unstable; urgency=low
+
+  * New upstream version.
+  * Use upstream docbook build mechanism now.
+  * Force usage of w3m -dump to convert HTML to ASCII (build depend on it).
+  * Exclude CVS files from dh_installdocs (when compiling from CVS).
+  * Add user.action and standard.action to /etc/privoxy.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sat, 25 May 2002 20:47:33 +0200
+
+privoxy (2.9.14-beta-3) unstable; urgency=low
+
+  * Fix typo ('[' instead of '{') in default.action (Closes: #148122).
+  * Disable edit-actions and remote-toggle in config file by default
+    (Closes: #148125).
+
+ -- Roland Rosenfeld <roland@debian.org>  Sat, 25 May 2002 11:53:49 +0200
+
+privoxy (2.9.14-beta-2) unstable; urgency=low
+
+  * Fix debian/rules clean to really clean.
+  * Change owner of /etc/privoxy/{*.action|trust} to privoxy in postinst,
+    to allow modification of these files web interface (Closes: SF-552144).
+
+ -- Roland Rosenfeld <roland@debian.org>  Thu, 23 May 2002 18:38:27 +0200
+
+privoxy (2.9.14-beta-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sat, 13 Apr 2002 18:05:26 +0200
+
+privoxy (2.9.13-beta-2) unstable; urgency=low
+
+  * Create HTML and ASCII versions of the documentation using docbook now.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sun, 31 Mar 2002 23:53:28 +0200
+
+privoxy (2.9.13-beta-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Roland Rosenfeld <roland@debian.org>  Fri, 29 Mar 2002 11:52:03 +0100
+
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..2d235d7
--- /dev/null
@@ -0,0 +1,23 @@
+Source: privoxy
+Section: web
+Priority: optional
+Maintainer: Roland Rosenfeld <roland@debian.org>
+Build-Depends: debhelper (>> 3.0.0), autoconf, libpcre3-dev, docbook-utils, w3m
+Standards-Version: 3.5.6
+
+Package: privoxy
+Architecture: any
+Depends: ${shlibs:Depends}, logrotate, adduser
+Description: Privacy enhancing HTTP Proxy
+ Privoxy is a web proxy with advanced filtering capabilities for
+ protecting privacy, filtering web page content, managing cookies,
+ controlling access, and removing ads, banners, pop-ups and other
+ obnoxious Internet junk. Privoxy has a very flexible configuration
+ and can be customized to suit individual needs and tastes. Privoxy
+ has application for both stand-alone systems and multi-user networks.
+ .
+ Privoxy is based on the code of the Internet Junkbuster. Junkbuster
+ was originally written by JunkBusters Corporation, and was released
+ as free open-source software under the GNU GPL. Stefan Waldherr made
+ many improvements, and started the SourceForge project to continue
+ development. Several other developers are now contributing.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..2ae2775
--- /dev/null
@@ -0,0 +1,49 @@
+This package was debianized by Roland Rosenfeld <roland@debian.org> on
+Fri, 29 Mar 2002 11:52:03 +0100.
+
+It was downloaded from http://privoxy.org/ and
+http://sourceforge.net/project/showfiles.php?group_id=11118
+
+Upstream Authors: ijbswa-developers@lists.sourceforge.net
+
+Current Project developers:
+
+ Stefan Waldherr
+ Andreas Oesterhelt
+ Jon Foster
+
+ Markus Breitenbach
+ Thomas Steudten
+
+Originally developed by:
+
+ Junkbusters Corp.
+ Anonymous Coders
+
+Copyright:     Written by and Copyright (C) 2001 the SourceForge
+               Privoxy team.  http://ijbswa.sourceforge.net
+
+               Based on the Internet Junkbuster originally written
+               by and Copyright (C) 1997 Anonymous Coders and 
+               Junkbusters Corporation.  http://www.junkbusters.com
+
+               This program is free software; you can redistribute it 
+               and/or modify it under the terms of the GNU General
+               Public License as published by the Free Software
+               Foundation; either version 2 of the License, or (at
+               your option) any later version.
+
+               This program is distributed in the hope that it will
+               be useful, but WITHOUT ANY WARRANTY; without even the
+               implied warranty of MERCHANTABILITY or FITNESS FOR A
+               PARTICULAR PURPOSE.  See the GNU General Public
+               License for more details.
+
+               The GNU General Public License should be included with
+               this file.  If not, you can view it at
+               http://www.gnu.org/copyleft/gpl.html
+               or write to the Free Software Foundation, Inc., 59
+               Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+The complete GNU General Public License can be found at
+/usr/share/common-licenses/GPL
diff --git a/debian/dirs b/debian/dirs
new file mode 100644 (file)
index 0000000..3414d3b
--- /dev/null
@@ -0,0 +1,4 @@
+etc/privoxy
+usr/sbin
+usr/share/doc/privoxy
+var/log/privoxy
diff --git a/debian/doc-base.developer b/debian/doc-base.developer
new file mode 100644 (file)
index 0000000..6a606b9
--- /dev/null
@@ -0,0 +1,12 @@
+Document: privoxy-developer
+Title: Privoxy Developer Manual
+Author: Privoxy Developers
+Abstract: The provoxy developer manual gives the users information on
+ how to help the developer team.  It provides guidance on coding,
+ testing, documentation and other issues.  Privoxy is a filtering web
+ proxy.
+Section: Apps/Net
+
+Format: HTML
+Index: /usr/share/doc/privoxy/developer-manual/index.html
+Files: /usr/share/doc/privoxy/developer-manual/*.html
diff --git a/debian/doc-base.faq b/debian/doc-base.faq
new file mode 100644 (file)
index 0000000..117c2a3
--- /dev/null
@@ -0,0 +1,11 @@
+Document: privoxy-faq
+Title: Privoxy Frequently Asked Questions
+Author: Privoxy Developers
+Abstract: The FAQ document gives users and developers alike answers to
+ frequently asked questions about Privoxy.  Privoxy is a filtering web
+ proxy.
+Section: Apps/Net
+
+Format: HTML
+Index: /usr/share/doc/privoxy/faq/index.html
+Files: /usr/share/doc/privoxy/faq/*.html
diff --git a/debian/doc-base.user b/debian/doc-base.user
new file mode 100644 (file)
index 0000000..2a7f5e6
--- /dev/null
@@ -0,0 +1,10 @@
+Document: privoxy-user
+Title: Privoxy User Manual
+Author: Privoxy Developers
+Abstract: The user manual gives users information on how to install,
+ configure and use Privoxy.  Privoxy is a filtering web proxy.
+Section: Apps/Net
+
+Format: HTML
+Index: /usr/share/doc/privoxy/user-manual/index.html
+Files: /usr/share/doc/privoxy/user-manual/*.html
diff --git a/debian/docs b/debian/docs
new file mode 100644 (file)
index 0000000..2b0dd84
--- /dev/null
@@ -0,0 +1,8 @@
+README
+AUTHORS
+doc/text/faq.txt
+doc/text/user-manual.txt
+doc/text/developer-manual.txt
+doc/webserver/faq
+doc/webserver/user-manual
+doc/webserver/developer-manual
diff --git a/debian/init.d b/debian/init.d
new file mode 100644 (file)
index 0000000..cca3a8b
--- /dev/null
@@ -0,0 +1,59 @@
+#! /bin/sh
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/sbin/privoxy
+NAME=privoxy
+DESC="filtering proxy server"
+OWNER=privoxy
+CONFIGFILE=/etc/privoxy/config
+PIDFILE=/var/run/$NAME.pid
+
+test -f $DAEMON || exit 0
+
+set -e
+
+case "$1" in
+  start)
+       echo -n "Starting $DESC: "
+       $DAEMON --pidfile $PIDFILE --user $OWNER $CONFIGFILE 2>/dev/null
+       echo "$NAME."
+       ;;
+  stop)
+       echo -n "Stopping $DESC: "
+       start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \
+               --exec $DAEMON
+       echo "$NAME."
+       ;;
+  #reload)
+       #
+       #       If the daemon can reload its config files on the fly
+       #       for example by sending it SIGHUP, do it here.
+       #
+       #       If the daemon responds to changes in its config file
+       #       directly anyway, make this a do-nothing entry.
+       #
+       # echo "Reloading $DESC configuration files."
+       # start-stop-daemon --stop --signal 1 --quiet --pidfile \
+       #       /var/run/$NAME.pid --exec $DAEMON
+  #;;
+  restart|force-reload)
+       #
+       #       If the "reload" option is implemented, move the "force-reload"
+       #       option to the "reload" entry above. If not, "force-reload" is
+       #       just the same as "restart".
+       #
+       echo "Restarting $DESC: "
+       start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \
+               --exec $DAEMON
+       sleep 1
+       $DAEMON --pidfile $PIDFILE --user $OWNER $CONFIGFILE
+       ;;
+  *)
+       N=/etc/init.d/$NAME
+       # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
+       echo "Usage: $N {start|stop|restart|force-reload}" >&2
+       exit 1
+       ;;
+esac
+
+exit 0
diff --git a/debian/logrotate b/debian/logrotate
new file mode 100644 (file)
index 0000000..d230a8b
--- /dev/null
@@ -0,0 +1,21 @@
+/var/log/privoxy/logfile {
+       create 0640 privoxy adm
+       missingok
+       weekly
+       rotate 7
+       compress
+       postrotate
+               touch /etc/privoxy/config
+       endscript
+}
+
+/var/log/privoxy/jarfile {
+       create 0640 privoxy adm
+       missingok
+       weekly
+       rotate 7
+       compress
+       postrotate
+               touch /etc/privoxy/config
+       endscript
+}
diff --git a/debian/manpages b/debian/manpages
new file mode 100644 (file)
index 0000000..6670965
--- /dev/null
@@ -0,0 +1 @@
+privoxy.1
diff --git a/debian/postinst b/debian/postinst
new file mode 100644 (file)
index 0000000..8f1028d
--- /dev/null
@@ -0,0 +1,55 @@
+#! /bin/sh
+# postinst script for privoxy
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+#
+# quoting from the policy:
+#     Any necessary prompting should almost always be confined to the
+#     post-installation script, and should be protected with a conditional
+#     so that unnecessary prompting doesn't happen if a package's
+#     installation fails and the `postinst' is called with `abort-upgrade',
+#     `abort-remove' or `abort-deconfigure'.
+
+case "$1" in
+    configure)
+        if ! grep -q '^privoxy:' /etc/passwd
+        then
+            adduser --system --home /etc/privoxy --ingroup nogroup \
+                    --disabled-password privoxy >/dev/null
+        fi
+        chown -R privoxy.adm /var/log/privoxy
+        chmod 750 /var/log/privoxy
+       chown privoxy /etc/privoxy/*.action /etc/privoxy/trust
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/postrm b/debian/postrm
new file mode 100644 (file)
index 0000000..2c9e371
--- /dev/null
@@ -0,0 +1,44 @@
+#! /bin/sh
+# postrm script for privoxy
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    purge)
+        echo "Removing user privoxy"
+        userdel privoxy || echo "WARNING: Problem removing user privoxy."
+
+        echo "Deleting privoxy log files"
+        rm -rf /var/log/privoxy
+        ;;
+
+    remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+        ;;
+
+    *)
+        echo "postrm called with unknown argument \`$1'" >&2
+        exit 1
+
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..06fb8a2
--- /dev/null
@@ -0,0 +1,119 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This is the debhelper compatibility version to use.
+export DH_COMPAT=3
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+DEBDIR=`pwd`/debian/privoxy
+
+CFLAGS="-O2"
+WITHDEBUG=""
+ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -g
+       WITHDEBUG="--with-debug"
+endif
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+
+       autoheader
+       autoconf
+       env CFLAGS=$(CFLAGS) WDUMP=w3m \
+               ./configure --prefix=/usr --sysconfdir=/etc \
+               --mandir=/usr/share/man $(WITHDEBUG) \
+               --with-docbook=/usr/share/sgml/docbook/stylesheet/dsssl/modular
+
+       touch configure-stamp
+
+build: build-stamp
+build-stamp: configure-stamp 
+       dh_testdir
+
+       $(MAKE)
+       $(MAKE) dok-devel dok-user dok-faq
+
+       touch build-stamp
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+
+       -$(MAKE) clean
+       -$(MAKE) distclean
+       rm -f privoxy 
+       rm -f configure config.h GNUmakefile 
+       rm -f doc/source/ldp.dsl
+
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       install -m 0755 privoxy $(DEBDIR)/usr/sbin/privoxy
+
+       sed -e 's/^\(\(trust\|proxy\)-info-url\|admin-address\)/#\1/'  \
+           -e 's/^\(enable-\(edit-actions\|remote-toggle\)\)/#\1/' \
+           -e 's#^confdir \.#confdir /etc/privoxy#' \
+           -e 's#^logdir \.#logdir /var/log/privoxy#' \
+               < config > $(DEBDIR)/etc/privoxy/config
+       install -m 0644 default.action $(DEBDIR)/etc/privoxy/default.action
+       install -m 0644 standard.action $(DEBDIR)/etc/privoxy/standard.action
+       install -m 0644 user.action $(DEBDIR)/etc/privoxy/user.action
+       install -m 0644 default.filter $(DEBDIR)/etc/privoxy/default.filter
+       install -m 0644 trust $(DEBDIR)/etc/privoxy/trust
+
+       cp -r templates $(DEBDIR)/etc/privoxy/
+       rm -f $(DEBDIR)/etc/privoxy/templates/*~
+       rm -rf $(DEBDIR)/etc/privoxy/templates/CVS
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+#      dh_installdebconf       
+       dh_installdocs -XCVS
+       dh_installexamples
+       dh_installmenu
+       dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+       dh_installinit
+       dh_installcron
+       dh_installman
+       dh_installinfo
+#      dh_undocumented
+       dh_installchangelogs ChangeLog
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_makeshlibs
+       dh_installdeb
+#      dh_perl
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/default.action b/default.action
new file mode 100644 (file)
index 0000000..70cd276
--- /dev/null
@@ -0,0 +1,547 @@
+######################################################################
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/default.action,v $
+# 
+#  $Id: default.action,v 1.27 2002/05/03 04:18:49 morcego Exp $
+#
+#  Purpose     :  Default actions file, see
+#                 http://www.privoxy.org/faq/questions.html#CONFIGFILES
+#
+#  Copyright   :  Written by and Copyright
+#                 Privoxy team. http://www.privoxy.org/
+#
+#                 Based on the Internet Junkbuster originally written
+#                 by and Copyright (C) 1997 Anonymous Coders and
+#                 Junkbusters Corporation.  http://www.junkbusters.com
+# 
+# We value your feedback. However, to provide you with the best support,
+# please note:
+#  
+#  * Use the support forum to get help:
+#    http://sourceforge.net/tracker/?group_id=11118&atid=211118
+#  * Submit feedback for this actions file only through our
+#    actions file feedback script: http://www.privoxy.org/actions
+#  * Submit bugs only through our bug forum:
+#    http://sourceforge.net/tracker/?group_id=11118&atid=111118 
+#    Make sure that the bug has not already been submitted. Please try
+#    to verify that it is a Privoxy bug, and not a browser or site
+#    bug first. If you are using your own custom configuration, please
+#    try the stock configs to see if the problem is a configuration
+#    related bug. And if not using the latest development snapshot,
+#    please try the latest one. Or even better, CVS sources.
+#  * Submit feature requests only through our feature request forum:
+#    http://sourceforge.net/tracker/?atid=361118&group_id=11118&func=browse
+#      
+# For any other issues, feel free to use the mailing lists:
+# http://sourceforge.net/mail/?group_id=11118
+#    
+# Anyone interested in actively participating in development and related
+# discussions can join the appropriate mailing list here:
+# http://sourceforge.net/mail/?group_id=11118. Archives are available
+# here too.
+# 
+#############################################################################
+# Syntax
+#############################################################################
+# 
+# To determine which actions apply to a request, the URL of the request is
+# compared to all patterns in this file. Every time it matches, the list of
+# applicable actions for this URL is incrementally updated. You can trace
+# this process by visiting http://i.j.b/show-url-info
+#
+# There are 4 types of lines in this file: comments (like this line),
+# actions, aliases and patterns, all of which are explained below.
+#
+#############################################################################
+# Pattern Syntax
+#############################################################################
+# 
+# 1. On Domains and Paths
+# -----------------------
+#
+# Generally, a pattern has the form <domain>/<path>, where both the <domain>
+# and <path> part are optional. If you only specify a domain part, the "/"
+# can be left out:
+# 
+# www.example.com 
+#   is a domain-only pattern and will match any request to www.yahoo.com
+# 
+# www.example.com/
+#   means exactly the same (but is slightly less efficient)
+# 
+# www.example.com/index.html
+#   matches only the document /index.html on www.example.com
+# 
+# /index.html
+#   matches the document /index.html, regardless of the domain
+# 
+# index.html
+#   matches nothing, since it would be interpreted as a domain name and
+#   there is no top-level domain called ".html".
+# 
+# 2. Domain Syntax
+# ----------------
+# 
+# The matching of the domain part offers some flexible options: If the
+# domain starts or ends with a dot, it becomes unanchored at that end:
+# 
+# www.example.com
+#   matches only www.example.com
+# 
+# .example.com
+#   matches any domain that ENDS in .example.com
+# 
+# www.
+#   matches any domain that STARTS with www.
+# 
+# Additionally, there are wildcards that you can use in the domain names
+# themselves. They work pretty similar to shell wildcards: "*" stands for
+# zero or more arbitrary characters, "?" stands for one, and you can define
+# charachter classes in square brackets and they can be freely mixed:
+# 
+# ad*.example.com
+#   matches adserver.example.com, ads.example.com, etc but not sfads.example.com
+# 
+# *ad*.example.com
+#   matches all of the above
+# 
+# .?pix.com
+#   matches www.ipix.com, pictures.epix.com, a.b.c.d.e.upix.com etc
+# 
+# www[1-9a-ez].example.com
+#   matches www1.example.com, www4.example.com, wwwd.example.com, 
+#   wwwz.example.com etc, but not wwww.example.com
+# 
+# You get the idea?
+# 
+# 2. Path Syntax
+# --------------
+# 
+# Paths are specified as regular expressions. A comprehensive discussion of
+# regular expressions wouldn't fit here, but (FIXME) someone should paste
+# a concise intro to the regex language here.
+# 
+# If Privoxy was compiled with pcre support (default), Perl compatible
+# regular expressions are used. See the pcre/docs/ direcory or man perlre
+# (also available on http://www.perldoc.com/perl5.6/pod/perlre.html) for
+# details.
+# 
+# Please note that matching in the path is CASE INSENSITIVE by default, but
+# you can switch to case sensitive by starting the pattern with the "(?-i)"
+# switch:
+# 
+# www.example.com/(?-i)PaTtErN.*
+#   will match only documents whose path starts with PaTtErN in exactly this
+#   capitalization.
+#
+# Partially case-sensetive and partially case-insensitive patterns are
+# possible, but the rules about splitting them up are extremely complex
+# - see the PCRE documentation for more information.
+# 
+#############################################################################
+# Action Syntax
+#############################################################################
+#
+# There are 3 kinds of action:
+#
+# Boolean (e.g. "block"):
+#   +name  # enable
+#   -name  # disable
+#
+# Parameterized (e.g. "hide-user-agent"):
+#   +name{param}  # enable and set parameter to "param"
+#   -name         # disable
+#
+# Multi-value (e.g. "add-header", "send-wafer"):
+#   +name{param}  # enable and add parameter "param"
+#   -name{param}  # remove the parameter "param"
+#   -name         # disable totally
+#
+# The default (if you don't specify anything in this file) is not to take
+# any actions - i.e completely disabled, so Privoxy will just be a
+# normal, non-blocking, non-anonymizing proxy.  You must specifically
+# enable the privacy and blocking features you need (although the 
+# provided default actions file will do that for you).
+#
+# Later actions always override earlier ones.  For multi-valued actions,
+# the actions are applied in the order they are specified.
+#
+#############################################################################
+# Valid actions are:
+#############################################################################
+#
+# +add-header{Name: value}
+#    Adds the specified HTTP header, which is not checked for validity.
+#    You may specify this many times to specify many headers.
+#
+# +block
+#    Block this URL
+#
+# +deanimate-gifs{last}
+# +deanimate-gifs{first}
+#    Deanimate all animated GIF images, i.e. reduce them to their last
+#    frame. This will also shrink the images considerably. (In bytes,
+#    not pixels!) 
+#    If the option "first" is given, the first frame of the animation
+#    is used as the replacement. If "last" is given, the last frame of
+#    the animation is used instead, which propably makes more sense for
+#    most banner animations, but also has the risk of not showing the
+#    entire last frame (if it is only a delta to an earlier frame).
+#
+# +downgrade-http-version
+#    Downgrade HTTP/1.1 client requests to HTTP/1.0 and downgrade the
+#    responses as well. Use this action for servers that use HTTP/1.1
+#    protocol features that Privoxy currently can't handle yet.
+#
+# +fast-redirects
+#    Many sites, like yahoo.com, don't just link to other sites.
+#    Instead, they will link to some script on their own server,
+#    giving the destination as a parameter, which will then redirect
+#    you to the final target. 
+#
+#    URLs resulting from this scheme typically look like:
+#    http://some.place/some_script?http://some.where-else
+#
+#    Sometimes, there are even multiple consecutive redirects encoded
+#    in the URL. These redirections via scripts make your web browing
+#    more traceable, since the server from which you follow such a link
+#    can see where you go to. Apart from that, valuable bandwidth and
+#    time is wasted, while your browser aks the server for one redirect
+#    after the other. Plus, it feeds the advertisers.
+#
+#    The +fast-redirects option enables interception of these requests
+#    by Privoxy, who will cut off all but the last valid URL in the
+#    request and send a local redirect back to your browser without
+#    contacting the intermediate sites.
+#
+# +filter{name}
+#    Filter the website through one or more regular expression filters.
+#    Repeat for multiple filters.
+#   
+#    Filters predefined in the supplied re_filterfile include:
+#
+#     html-annoyances:  Get rid of particularly annoying HTML abuse
+#     js-annoyances:    Get rid of particularly annoying JavaScript abuse
+#     content-cookies:  Kill cookies that come in the HTML or JS content
+#     popups:           Kill all popups in JS and HTML
+#     frameset-borders: Give frames a border
+#     webbugs:          Squish WebBugs (1x1 invisible GIFs used for user tracking)
+#     refresh-tags:     Kill automatic refresh tags (for dial-on-demand setups)
+#     fun:              Text replacements  for subversive browsing fun!
+#     nimda:            Remove Nimda (virus) code.
+#     banners-by-size:  Kill banners by size (very efficient!)
+#     shockwave-flash:  Kill embedded Shockwave Flash objects
+#     crude-parental:   Kill all web pages that contain the words "sex" or "warez"
+#
+#
+# +hide-forwarded-for-headers
+#    Block any existing X-Forwarded-for header, and do not add a new one.
+#
+# +hide-from-header{block}
+# +hide-from-header{spam@sittingduck.xqq}
+#    If the browser sends a "From:" header containing your e-mail address, 
+#    either completely removes the header ("block"), or change it to the
+#    specified e-mail address.
+#
+# +hide-referer{block}
+# +hide-referer{forge}
+# +hide-referer{http://nowhere.com}
+#    Don't send the "Referer:" (sic) header to the web site.  You can
+#    block it, forge a URL to the same server as the request (which is
+#    preferred because some sites will not send images otherwise) or
+#    set it to a constant string.
+#
+# +hide-referrer{...}
+#    Alternative spelling of +hide-referer.  Has the same parameters,
+#    and can be freely mixed with, "+hide-referer".  ("referrer" is the 
+#    correct English spelling, however the HTTP specification has a 
+#    bug - it requires it to be spelt "referer").
+#
+# +hide-user-agent{browser-type}
+#    Change the "User-Agent:" header so web servers can't tell your
+#    browser type.  (Breaks many web sites).  Specify the user-agent
+#    value you want - e.g., to pretend to be using Netscape on Linux:
+#      +hide-user-agent{Mozilla (X11; I; Linux 2.0.32 i586)}
+#    Or to identify yourself explicitly as a Privoxy user:
+#      +hide-user-agent{Privoxy/1.0}
+#    (Don't change the version number from 1.0 - after all, why tell them?)
+#
+# +handle-as-image
+#    Treat this URL as an image.  This only matters if it's also "+block"ed,
+#    in which case a "blocked" image can be sent rather than a HTML page.
+#    See +set-image-blocker{} for the control over what is actually sent.
+#
+# +set-image-blocker{blank}
+# +set-image-blocker{pattern}
+# +set-image-blocker{<URL>} with <url> being any valid image URL
+#    Decides what to do with URLs that end up tagged with {+block +handle-as-image}.
+#    There are 4 options:
+#      * "-set-image-blocker" will send a HTML "blocked" page, usually
+#         resulting in a "broken image" icon.
+#      * "+set-image-blocker{blank}" will send a 1x1 transparent image
+#      * "+set-image-blocker{pattern}" will send a 4x4 grey/white pattern
+#        which is less intrusive than the logo but easier to recognize
+#        than the transparent one.
+#      * "+set-image-blocker{<URL>}" will send a HTTP temporary redirect
+#        to the specified image URL.
+#
+#
+# +limit-connect{portlist}
+#   The CONNECT methods exists in HTTP to allow access to secure websites
+#   (https:// URLs) through proxies. It works very simply: The proxy
+#   connects to the server on the specified port, and then short-circuits
+#   its connections to the cliant and to the remote proxy.
+#   This can be a big security hole, since CONNECT-enabled proxies can
+#   be abused as TCP relays very easily.
+#   By default, i.e. in the absence of a +limit-connect action, Privoxy
+#   will only allow CONNECT requests to port 443, which is the standard port
+#   for https.
+#   If you want to allow CONNECT for more ports than that, or want to forbid
+#   CONNECT altogether, you can specify a comma separated list of ports and port
+#   ranges (the latter using dashes, with the minimum defaulting to 0 and max to 65K):
+#
+#   +limit-connect{443} # This is the default and need no be specified.
+#   +limit-connect{80,443} # Ports 80 and 443 are OK.
+#   +limit-connect{-3, 7, 20-100, 500-} # Port less than 3, 7, 20 to 100, and above 500 are OK.
+#
+# +prevent-compression
+#    Prevent the website from compressing the data. Some websites do
+#    that, which is a problem for Privoxy, since +filter, +kill-popups
+#    and +gif-deanimate will not work on compressed data. Will slow down
+#    connections to those websites, though.
+#
+# +prevent-keeping-cookies
+# +session-cookies-only
+#    If the website sets cookies, make sure they are erased when you exit
+#    and restart your web browser.  This makes profiling cookies useless,
+#    but won't break sites which require cookies so that you can log in
+#    or for transactions.
+#
+# +crunch-outgoing-cookies
+#    Prevent the website from reading cookies
+#
+# +crunch-incoming-cookies
+#    Prevent the website from setting cookies
+#
+# +kill-popups
+#    Filter the website through a built-in filter to disable
+#    1;''.concat() etc.  The two alternative spellings are
+#    equivalent.
+#
+# +send-vanilla-wafer
+#    This action only applies if you are using a jarfile.  It sends a
+#    cookie to every site stating that you do not accept any copyright
+#    on cookies sent to you, and asking them not to track you.  Of
+#    course, this is a (relatively) unique header they could use to 
+#    track you.
+#
+# +send-wafer{name=value}
+#    This allows you to add an arbitrary cookie.  Specify it multiple
+#    times in order to add several cookies.
+#
+#############################################################################
+
+#############################################################################
+# Settings -- Don't change.
+#############################################################################
+{{settings}}
+#############################################################################
+for-privoxy-version=3.0
+
+#############################################################################
+# Aliases
+#############################################################################
+{{alias}}
+#############################################################################
+#
+# You can define a short form for a list of permissions - e.g., instead
+# of "-crunch-incoming-cookies -crunch-outgoing-cookies -filter -fast-redirects",
+# you can just write "shop". This is called an alias.
+#
+# Currently, an alias can contain any character except space, tab, '=', '{'
+# or '}'.
+# But please use only 'a'-'z', '0'-'9', '+', and '-'.
+#
+# Alias names are not case sensitive.
+#
+# Aliases beginning with '+' or '-' may be used for system permission names 
+# in future releases - so try to avoid alias names like this.  (e.g. 
+# "+crunch-all-cookies" below is not a good name)
+#
+# Aliases must be defined before they are used.
+# 
+
+# Useful aliases
++crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
++imageblock      = +block +handle-as-image
+
+# Fragile sites should have the minimum changes
+fragile     = -block -deanimate-gifs -fast-redirects -filter -hide-referer -crunch-all-cookies -kill-popups
+
+# Shops should be allowed to set persistent cookies
+shop        = -filter -crunch-all-cookies -prevent-keeping-cookies
+
+# Your favourite blend of filters:
+#
+myfilters   = +filter{html-annoyances} +filter{js-annoyances} +filter{popups}\
+              +filter{webbugs} +filter{nimda} +filter{banners-by-size} #+filter{fun}
+#... etc.  Customize to your heart's content.
+#############################################################################
+# Defaults
+#############################################################################
+{-add-header \
+ -block \
+ -crunch-incoming-cookies \
+ -crunch-outgoing-cookies \
+ +deanimate-gifs{last} \
+ -downgrade-http-version \
+ -fast-redirects \
+ -filter{popups} \
+ -filter{fun} \
+ -filter{shockwave-flash} \
+ -filter{crude-prental} \
+ +filter{html-annoyances} \
+ +filter{js-annoyances} \
+ +filter{content-cookies} \
+ +filter{webbugs} \
+ +filter{refresh-tags} \
+ +filter{nimda} \
+ +filter{banners-by-size} \
+ -handle-as-image \
+ +hide-forwarded-for-headers \
+ +hide-from-header{block} \
+ +hide-referer{forge} \
+ -hide-user-agent \
+ -kill-popups \
+ -limit-connect \
+ +prevent-compression \
+ -send-vanilla-wafer \
+ -send-wafer \
+ +session-cookies-only \
+ +set-image-blocker{pattern} \
+}
+/ # Match all URLs
+
+
+#############################################################################
+# Needed for automatic feedback evaluation; Please don't delete!
+#############################################################################
+{+add-header{X-Actions-File-Version: 1.2} -filter -kill-popups}
+.privoxy.org
+.oesterhelt.org/actions
+
+
+#############################################################################
+# These sites are very complex and require
+# minimal interference.
+#############################################################################
+{fragile}
+.office.microsoft.com
+.windowsupdate.microsoft.com
+
+#############################################################################
+# Shopping sites - still want to block ads.
+#############################################################################
+{shop}
+.quietpc.com
+.worldpay.com   # for quietpc.com
+.jungle.com
+.scan.co.uk
+
+#############################################################################
+# These shops require pop-ups
+#############################################################################
+{shop -no-popups -filter{popups}}
+.dabs.com
+.overclockers.co.uk
+
+#############################################################################
+# Sometimes fast-redirects catches things by mistake
+#############################################################################
+{-fast-redirects}
+www.ukc.ac.uk/cgi-bin/wac\.cgi\?
+login.yahoo.com
+edit.europe.yahoo.com
+.google.com
+.altavista.com/.*(like|url|link):http
+.altavista.com/trans.*urltext=http
+.speedfind.de
+.nytimes.com
+
+#############################################################################
+# Don't filter code!
+#############################################################################
+{-filter}
+.cvs.sourceforge.net
+
+#############################################################################
+# These are images:
+#############################################################################
+{+handle-as-image}
+#############################################################################
+/.*\.(gif|jpe?g|png|bmp|ico)$
+
+#############################################################################
+{+imageblock}
+#############################################################################
+#BLOCK-REFERRER: http://www.cnn.com/
+#BLOCK-REFERRER: http://www.aol.com/
+ar.atwola.com 
+
+#BLOCK-REFERRER: http://www.altavista.com/
+.ad.doubleclick.net
+
+.a.yimg.com/(?:(?!/i/).)*$
+.a[0-9].yimg.com/(?:(?!/i/).)*$
+
+#BLOCK-REFERRER: 
+bs*.gsanet.com
+bs*.einets.com
+
+#BLOCK-REFERRER: Opera browser built-in
+.qkimg.net
+
+#BLOCK-REFERRER: http://www.tecchannel.de/index.html
+#BLOCK-REFERRER: and thousands more
+ad.*.doubleclick.net
+
+#############################################################################
+# Blocklist:
+#############################################################################
+{+block}
+#############################################################################
+#BLOCK-GENERIC:
+ad*.
+.*ads.
+banner?.
+count*.
+
+/(?:.*/)?(ads(erver?|tream)?|.*?ads|adv(ert(s|enties|is(ing|e?ments)?)?)?|(ad)?[-_]?banner(s|ads?|farm)?)/
+/.*count(er)?\.(pl|cgi|exe|dll|asp|php[34]?)
+/(?:.*/)?(publicite|werbung|rekla(ma|me|am)|annonse|maino(kset|nta|s)?)/
+
+#BLOCK-REFERRER: http://www.brooksbrothers.com
+#BLOCK-REFERRER: http://www.autodesk.com
+.hitbox.com 
+
+#############################################################################
+{-block}
+#############################################################################
+include.ebay.com
+advogato.org
+adsl.
+ad[ud]*.
+advice.
+.edu
+.ac.uk
+.uni-*.de
+www.ugu.com/sui/ugu/adv
+.*downloads.
+# So many download pages being blocked
+/downloads/
+# adv for globalintersec means advanced, not advertisement
+www.globalintersec.com/adv
+# We all want weather forecast to work
+banners.wunderground.com/banner/gizmotemp/
+
diff --git a/default.filter b/default.filter
new file mode 100644 (file)
index 0000000..485033a
--- /dev/null
@@ -0,0 +1,357 @@
+# ********************************************************************
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/default.filter,v $
+# 
+#  $Id: default.filter,v 1.10 2002/04/18 10:14:19 oes Exp $
+#
+#  Purpose     :  Rules to process the content of web pages
+# 
+#  Copyright   :  Written by and Copyright
+#                 Privoxy team. http://www.privoxy.org/
+#
+# We value your feedback. However, to provide you with the best support,
+# please note:
+#  
+#  * Use the support forum to get help:
+#    http://sourceforge.net/tracker/?group_id=11118&atid=211118
+#  * Submit bugs only thru our bug forum:
+#    http://sourceforge.net/tracker/?group_id=11118&atid=111118 
+#    Make sure that the bug has not already been submitted. Please try
+#    to verify that it is a Privoxy bug, and not a browser or site
+#    bug first. If you are using your own custom configuration, please
+#    try the stock configs to see if the problem is a configuration
+#    related bug. And if not using the latest development snapshot,
+#    please try the latest one. Or even better, CVS sources.
+#  * Submit feature requests only thru our feature request forum:
+#    http://sourceforge.net/tracker/?atid=361118&group_id=11118&func=browse
+#      
+# For any other issues, feel free to use the mailing lists:
+# http://sourceforge.net/mail/?group_id=11118
+#    
+# Anyone interested in actively participating in development and related
+# discussions can join the appropriate mailing list here:
+# http://sourceforge.net/mail/?group_id=11118. Archives are available
+# here too.
+# 
+#################################################################################
+#
+# Syntax:
+#
+# Filters start with a line "FILTER: name description". They are then referrable
+# from the actionsfile with +filter{name}
+#
+# Inside the filters, write one Perl-Style substitution (job) per line.
+# Jobs that precede the first FILTER: line are ignored.
+#
+# For Details see the pcrs manpage contained in this distribution.
+# (and the perlre, perlop and pcre manpages)
+#
+# Note that you are free to choose the delimter as you see fit.
+#
+# Note2: In addidion to the Perl options gimsx, the following nonstandard
+# options are supported:
+# 
+# 'U' turns the default to ungreedy matching.  Add ? to quantifiers to
+#     switch back to greedy.
+# 'T' (trivial) prevents parsing for backreferences in the substitute.
+#     Use if you want to include text like '$&' in your substitute without
+#     quoting.
+# 
+#################################################################################
+
+
+#################################################################################
+#
+# html-annoyances: Get rid of particularly annoying HTML abuse
+#
+#################################################################################
+FILTER: html-annoyances Get rid of particularly annoying HTML abuse
+
+# New browser windows (if allowed -- see no-popups filter below) should be
+# resizeable and have a location and status bar
+#
+s/(<a\s+href[^>]+)resizable=['"]?(no|0|false)['"]?(.*>)/$1resizable="1"$3/igU 
+s/(<a\s+href[^>]+)location=['"]?(no|0)['"]?(.*>)/$1location="1"$3/igU 
+s/(<a\s+href[^>]+)status=['"]?(no|0)['"]?(.*>)/$1status="1"$3/igU
+s/(<a\s+href[^>]+)scrolling=['"]?(no|0|auto)['"]?(.*>)/$1scrolling="no"$3/igU
+s/(<a\s+href[^>]+)menubar=['"]?(no|0)['"]?(.*>)/$1menubar="1"$3/igU
+
+# The <BLINK> tag was a crime!
+#
+s*<blink>|</blink>**ig
+
+
+#################################################################################
+#
+# js-annoyances: Get rid of particularly annoying JavaScript abuse
+#
+#################################################################################
+FILTER: js-annoyances Get rid of particularly annoying JavaScript abuse
+
+# Get rid of Javascript referrer tracking. Test page: http://www.randomoddness.com/untitled.htm
+#
+s|(<script.*)document\.referrer(.*</script>)|$1"Not Your Business!"$2|Usg
+
+# The status bar is for displaying link targets, not pointless blahblah
+#
+s/window.status\s*=\s*['"].*?['"]/dUmMy=1/ig
+
+# Kill OnUnload popups. Yummy. Test: http://www.zdnet.com/zdsubs/yahoo/tree/yfs.html
+#
+s/(<body .*)onunload(.*>)/$1never$2/iU
+
+
+#################################################################################
+#
+# content-cookies: Kill cookies that come in the HTML or JS content
+#
+#################################################################################
+FILTER: content-cookies Kill cookies that come in the HTML or JS content
+
+# JS cookies, like found on privacy.net:
+#
+s|(document\.cookie)([ \t\r\n]*=)|documenZapCooky$2|g
+
+# HTML cookies:
+#
+s|<meta\s+http-equiv=['"]?set-cookie['"]?\s+content=[^>].*>|<!--no cookies here -->|iUT  
+
+
+##################################################################################
+#
+# popups: Kill all popups in JS and HTML
+#
+#################################################################################
+FILTER: popups Kill all popups in JS and HTML
+
+s/window\.open\s*\(/concat(/ig               # JavaScript
+s/([ =;])open\s*\(/$1concat(/ig              # JavaScript alternative
+s/target=['"]?(_blank|_new)['"]?/notarget/ig # HTML
+
+
+#################################################################################
+#
+# frameset-borders: Give frames a border, make them resizable and scrollable
+#
+#################################################################################
+FILTER: frameset-borders Give frames a border and make them resizable
+
+s/(<frameset [^>]+)framespacing=['"]?(no|0)['"]?(.*>)/$1$3/igU
+s/(<frameset [^>]+)(frame)?border=['"]?(no|0)['"]?(.*>)/$1$4/igU
+
+s/(<frame [^>]+)frameborder=['"]?(no|0)['"]?(.*>)/$1$3/igU
+s/(<frame [^>]+)noresize(.*>)/$1$2/igU
+s/(<frame [^>]+)resizable=['"]?(no)['"]?(.*>)/$1$3/igU 
+s/(<frame [^>]+)scrolling=['"]?(no)['"]?(.*>)/$1$3/igU
+
+#################################################################################
+#
+# webbugs: Squish WebBugs (1x1 invisible GIFs used for user tracking)
+#
+#################################################################################
+FILTER: webbugs Squish WebBugs (1x1 invisible GIFs used for user tracking)
+
+s/<img\s+[^>]*?(width|height)\s*=\s*['"]?1\D[^>]*?(width|height)\s*=\s*['"]?1(\D[^>]*?)?>/<!-- Squished WebBug -->/siUg
+
+
+#################################################################################
+#
+# refresh-tags: Kill automatic refresh tags (for dial-on-demand setups)
+#
+#################################################################################
+FILTER: refresh-tags Kill automatic refresh tags (for dial-on-demand setups)
+
+s/<meta\s+http-equiv=['"]?refresh['"]?\s+content=['"]?[0-9]*;\s+url=([^>]*)['"]?>/<link rev="x-refresh" href=$1>/iU   
+s/<meta\s+http-equiv=['"]?page-enter['"]?\s+content=[^>].*>/<!--no page enter for me-->/iU 
+
+
+#################################################################################
+#
+# fun: Text replacements for subversive browsing fun!
+#
+#################################################################################
+FILTER: fun Text replacements for subversive browsing fun!
+
+s/microsoft(?!.com)/MicroSuck/ig
+
+# Buzzword Bingo (example for extended regex syntax)
+#
+s* industry[ -]leading \
+|  cutting[ -]edge \
+|  award[ -]winning # Comments are OK, too! \
+|  high[ -]performance \
+|  solutions[ -]based \
+|  unmatched \
+|  unparalleled \
+|  unrivalled \
+*<font color="red"><b>BINGO!</b></font> \
+*igx
+
+
+#################################################################################
+#
+# nimda: Remove Nimda (virus) code
+#
+#################################################################################
+FILTER: nimda Remove Nimda (virus) code
+
+s%<script language="JavaScript">(window\.open|1;''\.concat)\("readme\.eml", null, "resizable=no,top=6000,left=6000"\)</script>%<br><font size="7"> WARNING: This Server is infected with <a href="http://www.cert.org/advisories/CA-2001-26.html">Nimda</a>!</font>%g
+
+#################################################################################
+#
+# banners-by-size: Kill banners by size
+#
+#################################################################################
+#
+# Standard banner sizes taken from http://www.iab.net/iab_banner_standards/bannersizes.html
+#
+# Note: Use http://config.privoxy.org/send-banner?type=trans for a transparent 1x1 image
+#       Use http://config.privoxy.org/send-banner?type=pattern for a grey/white pattern image
+#       Use http://config.privoxy.org/send-banner?type=auto  to auto-select.
+#
+#################################################################################
+FILTER: banners-by-size Kill banners by size
+
+s|<img\s+[^>]*?(width=['"]?468\D)[^>]*(height=['"]?60[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?234\D)[^>]*(height=['"]?60[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?88\D)[^>]*(height=['"]?31[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?120\D)[^>]*(height=['"]?90[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?120\D)[^>]*(height=['"]?600[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?120\D)[^>]*(height=['"]?60[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?160\D)[^>]*(height=['"]?600[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?125\D)[^>]*(height=['"]?125[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?120\D)[^>]*(height=['"]?240[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?180\D)[^>]*(height=['"]?150[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?300\D)[^>]*(height=['"]?250[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?250\D)[^>]*(height=['"]?250[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?240\D)[^>]*(height=['"]?400[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+s|<img\s+[^>]*?(width=['"]?336\D)[^>]*(height=['"]?280[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+
+# One more. (Where is 200x50 from?)
+#
+s|<img\s+[^>]*?(width=['"]?200\D)[^>]*(height=['"]?50[^>]*?)>|<img src="http://config.privoxy.org/send-banner?type=auto" $1 $2>|sig
+
+
+#################################################################################
+#
+# shockwave-flash: Kill embedded Shockwave Flash objects
+#
+#################################################################################
+FILTER: shockwave-flash Kill embedded Shockwave Flash objects
+
+s|<embed [^>]*application/x-shockwave-flash.*</embed>|<!-- Squished Shockwave Flash Embed -->|sigU
+
+
+#################################################################################
+#
+# crude-parental: Crude parental filtering?  (Use along with a suitable blocklist).
+#                 Shows how to deny access to whole page based on a keyword.
+#
+#################################################################################
+#
+# (Note: Middlesex, Sussex and Essex are counties in the UK, not rude words)
+# (Note #2: Is 'sex' a rude word?!)
+#
+#################################################################################
+FILTER: crude-parental Crude parental filtering (demo only)
+
+s%^.*(?<!middle)(?<!sus)(?<!es)sex.*$%<html><head><title>Blocked</title></head><body><h3>Blocked due to possible adult content. Please see <a href="http://dmoz.org/Kids_and_Teens/">this site</a>.</h3></body></html>%is
+s+^.*warez.*$+<html><head><title>No Warez</title></head><body><h3>You're not searching for illegal stuff, are you?</h3></body></html>+is
+
+############################################################################## 
+#
+#  Revisions   :
+#     $Log: default.filter,v $
+#     Revision 1.10  2002/04/18 10:14:19  oes
+#     renamed some filters
+#
+#     Revision 1.9  2002/04/11 07:36:35  oes
+#     Generalized js-popup filter
+#
+#     Revision 1.8  2002/04/10 17:07:21  oes
+#     Fixed potentially desctructive jobs, added noflash filter
+#
+#     Revision 1.7  2002/04/09 18:34:51  oes
+#     Fixed HTML syntax in replacements
+#
+#     Revision 1.6  2002/04/03 19:49:52  swa
+#     name change
+#
+#     Revision 1.5  2002/03/27 15:30:26  swa
+#     have a consistent appearance
+#
+#     Revision 1.4  2002/03/26 22:29:54  swa
+#     we have a new homepage!
+#
+#     Revision 1.3  2002/03/24 16:08:03  jongfoster
+#     Fixing banners-by-size for new config URLs
+#
+#     Revision 1.2  2002/03/24 13:02:18  swa
+#     name change related issues.
+#
+#     Revision 1.1  2002/03/24 11:37:39  jongfoster
+#     Name change
+#
+#     Revision 1.24  2002/03/16 20:39:54  oes
+#      - Added descriptions to the filters so users will know what they select in the cgi editor
+#      - Added content-cookies filter
+#      - Bugfixed many jobs (Thanks to Al for some hints)
+#
+#     Revision 1.22  2002/03/12 13:42:50  oes
+#     Fixing & Optimizing REs
+#
+#     Revision 1.21  2002/03/12 11:59:20  oes
+#     Beefed up Buzzword Bingo
+#
+#     Revision 1.20  2002/03/12 01:42:50  oes
+#     Introduced modular filters
+#
+#     Revision 1.19  2002/03/10 19:49:24  oes
+#     Added expression to kill referer tracking in JavaScripts
+#
+#     Revision 1.18  2002/03/08 17:14:12  oes
+#     PNG -> image in comments
+#
+#     Revision 1.17  2002/03/07 03:50:54  oes
+#     Adapted comments to new built-in images
+#
+#     Revision 1.16  2002/02/21 00:12:19  jongfoster
+#     Modifying the banner regexps to use long URLS and to autodetect
+#     whether to show a logo or a transparent GIF, based on actionsfile
+#     setting.
+#
+#     Revision 1.15  2001/12/28 23:54:20  steudten
+#     Fix for feature Req #495374: http-equiv problem
+#
+#     Revision 1.14  2001/12/09 18:55:11  david__schmidt
+#     Updated CODE_STATUS to beta, commented out microsuck line in re_filterfile
+#     for 2.9.10 beta
+#
+#     Revision 1.13  2001/10/13 13:11:20  joergs
+#     Fixed WebBug filter.
+#
+#     Revision 1.12  2001/10/07 15:46:42  oes
+#     Followed Guy's proposal to change the document.cookie job
+#
+#     Revision 1.11  2001/09/21 12:34:00  joergs
+#     Added filter to replace "Nimda" code by a warning.
+#
+#     Revision 1.10  2001/07/20 11:04:26  oes
+#     Added Rodneys javascript cookie filter
+#
+#     Revision 1.9  2001/07/13 14:03:48  oes
+#     Elimiated yet another bug in the banner-by-size jobs. Shame on me!
+#
+#     Revision 1.8  2001/06/29 13:34:00  oes
+#     - Added explanation for U and T options
+#     - Added hint on image replacement by CGI call
+#     - Fixed bug in banner-by-size jobs
+#
+#     Revision 1.7  2001/06/19 14:21:56  oes
+#     Fixed microsuck line
+#
+#     Revision 1.6  2001/06/09 14:01:57  swa
+#     header. cosmetics. default: no messing ala microsuck.
+#
+#
+# 
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644 (file)
index 0000000..769562f
--- /dev/null
@@ -0,0 +1,2 @@
+man
+text
diff --git a/doc/changes.txt b/doc/changes.txt
deleted file mode 100644 (file)
index 6aa1482..0000000
+++ /dev/null
@@ -1,991 +0,0 @@
-This file contains details of the changes made to JunkBuster, in
-chronological order.  Scroll down to the bottom for the newest 
-additions!
-
-
-*****************************************************************************
-* Copied from old README                                                    *
-*****************************************************************************
-
-README for the Internet Junkbuster Proxy (TM) Copyright 1997-8 Junkbusters Corp.
-
-   Id: README,v 1.1 2001/04/16 21:10:38 rodney Exp 
-
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 2 of the License,
-   or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-   See the GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-The version of the code with this makefile is Version 2.0.2.
-No CHANGES file is included here; for a history of previous versions see
-   http://www.junkbusters.com/ht/en/ijbdist.html#previous
-This version tightens security over 2.0.1; some multi-user sites will need
-to change the listen-address in the configuration file (see previous URL).
-
-For installation on Windows see http://www.junkbusters.com/ht/en/ijbwin.html
-An executable is provided so you don't need nmake or a C compiler.
-
-For UNIX and other systems see the FAQ. If you just want to test it with its
-defaults of simply stopping cookies and private info, all you need to do now
-on most Unix systems is type make, run junkbuster & and configure your browser.
-
-This directory should contain the following files.  The .html files are also
-in http://www.junkbusters.com/ht/en/ and http://internet.junkbuster.com
-You are welcome to publish copies of the .html files on your local web server,
-according to the GNU General Public License.
-
-gpl.html GNU General Public Licence
-junkbstr.exe   Executable (binary) for Windows 95/NT
-Makefile A very bland Makefile; Most versions of Unix except HP & Suns
-      compile without change. Windows requires the changes indicated.
-ijbman.html Manual for the Internet Junkbuster, HTML format
-junkbuster.1   Manual for the Internet Junkbuster, man macro format:
-         man ./junkbuster.1 # or nroff -man junkbuster.1 | more
-ijbfaq.html FAQ: Frequently Asked Questions on the Internet Junkbuster
-      Includes installation instructions
-junkbstr.ini   Sample configuration file with almost all options commented out
-sblock.ini  Sample blockfile (which doesn't really block much, see FAQ)
-scookie.ini Sample cookiefile (permits little; you decide who to trust)
-saclfile.ini   Sample access control file (block access to everyone)
-sforward.ini   Sample forwardfile (does no fowarding, no gateways, so SOCKS)
-strust.ini  Sample trustfile (has no trusted sites and blocks nothing)
-conn.c, bind.c, encode.c, loaders.c, parsers.c, ssplit.c   Various utilities
-socks4.c Code for SOCKS4 and SOCKS4A gateways
-jcc.c    The main program
-jcc.h    #included declarations etc
-gnu_regex.c, gnu_regex.h:  Regular expression code from the FSF, not us.
-win32.c     A few lines of code specific to the Windows version (95 & NT)
-acl.c    Access controls (new in version 2.0) - doesn't replace firewalls
-filters.c   Strings for the presentation of messages to user
-
-If you find that the Internet Junkbuster improves the quality of your life
-online, we hope you'll visit http://www.junkbusters.com to see how our free
-services can help you bust other kinds of junk out of your life:
-junk mail, spam, telemarketing, and invasions of your private data.
-And please tell your friends about this free product, and help them set it up.
-
-If your company finds this software useful in protecting its confidential
-information and making its people happier and more productive, please consider
-purchasing one of our our commercial support packages:
-   http://www.junkbusters.com/ht/en/ijbfaq.html#commercial
-
-We don't advertise, so please tell others in your community about us.
-
-Junkbusters Corp.    http://www.junkbusters.com
-
-
-*****************************************************************************
-* Copied from old README.too                                                *
-*****************************************************************************
-
-Id: README.TOO,v 1.1 2001/04/16 21:10:38 rodney Exp
-
-This is the README.TOO file for Stefan's version of the Internet
-Junkbuster (from http://www.waldherr.org/junkbuster/).
-
-
-
-Installation:
--------------
-Install the RPM with the usual command `rpm -Uvh foobar.rpm'. Since we
-run the Junkbuster as user `nobody', cd to a directory where `nobody'
-has read access (in particular NOT /root) and issue (as root)
-
-   /etc/rc.d/init.d/junkbuster start
-
-This will be done automagically for you any time you boot your machine.
-
-
-
-Configuration:
---------------
-To let Junkbuster take `care' of the ads, you have to setup your
-browser to use the Junkbuster.
-
-  Short instructions for the advanced user:
-
-   Configure Netscape to use 127.0.0.1 on port 8000 as 
-        a proxy server.
-
-  Detailed instructions for the beginner:
-
-        Remove Internet Explorer and install Netscape. No `real' 
-        user would ever use MSIE. Though the Junkbuster works 
-        with IE as well. Read 
-        http://www.junkbusters.com/ht/en/ijbfaq.html#browser
-
-Check to see if the Junkbuster works correctly by surfing to
-
-   http://127.0.0.1/show-proxy-args
-
-or any other place and add the text `/show-proxy-args' to the URL.
-Ok? Then enjoy your ad-free surfing.
-
-
-
-Mailinglists:
--------------
-In case you are interested in the Junkbuster, there are two
-mailinglists (junkbuster-users and junkbuster-announce). Instructions
-on how to subscribe and unsubscribe are at
-
-   http://www.waldherr.org/junkbuster/
-
-Bugs:
------
-Please fill out
-
-   http://sourceforge.net/bugs/?func=addbug&group_id=11118
-
-Patches:
---------
-Please fill out
-
-   http://sourceforge.net/patch/?func=addpatch&group_id=11118
-
-Need Help?
-----------
-Please fill out
-
-   http://sourceforge.net/support/?func=addsupport&group_id=11118
-
-
-Comments:
----------
-I would greatly appreciate feedback for this program. Send comments to
-Stefan Waldherr <stefan@waldherr.org> (in either German or English). I
-prefer plain text. If you happen to see an ad which got thru the filter
-PLEASE use the `contribute' form at http://www.waldherr.org/junkbuster/.
-
-Have fun,
-Stefan.
-
-
-*****************************************************************************
-* Copied from old README.win                                                *
-*****************************************************************************
-
-$Id: README.WIN,v 1.1 2001/04/16 21:10:38 rodney Exp $
-
-This is the README.WIN file for the Windows version of the Internet
-Junkbuster (from http://www.waldherr.org/junkbuster/).
-
-Installation:
--------------
-Congrats, since you are reading this file, you have already unzipped
-the archive correctly.
-
-Start the Junkbuster with `junkbstr' (i.e., click on the icon in the
-ijb subdirectory). If you want to start Junkbuster automatically,
-make a link to the program in the `Autostart' folder.
-
-
-
-Configuration:
---------------
-To let Junkbuster take `care' of the ads, you have to setup your
-browser to use the Junkbuster.
-
-  Short instructions for the advanced user:
-
-   Configure Netscape to use 127.0.0.1 on port 8000 as 
-        a proxy server.
-
-  Detailed instructions for the beginner:
-
-        Remove Internet Explorer and install Netscape. No `real' 
-        user would ever use MSIE. Though the Junkbuster works 
-        with IE as well. Read 
-        http://www.junkbusters.com/ht/en/ijbfaq.html#browser
-
-Check to see if the Junkbuster works correctly by surfing to
-
-   http://127.0.0.1/show-proxy-args
-
-or any other place and add the text `/show-proxy-args' to the URL.
-Ok? Then enjoy your ad-free surfing.
-
-
-
-Mailinglists:
--------------
-In case you are interested in the Junkbuster, there are two
-mailinglists (junkbuster-users and junkbuster-announce). Instructions
-on how to subscribe and unsubscribe are at
-
-   http://www.waldherr.org/junkbuster/
-
-Bugs:
------
-Please fill out
-
-   http://sourceforge.net/bugs/?func=addbug&group_id=11118
-
-Patches:
---------
-Please fill out
-
-   http://sourceforge.net/patch/?func=addpatch&group_id=11118
-
-Need Help?
-----------
-Please fill out
-
-   http://sourceforge.net/support/?func=addsupport&group_id=11118
-
-Comments:
----------
-I would greatly appreciate feedback for this program. Send comments to
-Stefan Waldherr <stefan@waldherr.org> (in either German or English). I
-prefer plain text. If you happen to see an ad which got thru the filter
-PLEASE use the `contribute' form at http://www.waldherr.org/junkbuster/.
-
-Have fun,
-Stefan.
-
-
-*****************************************************************************
-* Copied from old README.re_filter                                          *
-*****************************************************************************
-
-DISCLAIMER:
-   This is pre-alpha code. Using it in any other way
-   than just reading it is a high risk activity and
-   the author disclaims all liability for any damage.
-
-   See the GNU General Public License at
-   http://www.gnu.org/copyleft/gpl.html for details.
-
-
-Dear alpha-Tester,
-
-Thank you for trying out the experimental re_filter feature of
-Junkbuster. As this is still a very early pre-release version,
-and I'm neither much of an autoconf or make wizard, building
-the patched junkbuster involves some manual work, that is 
-described below. Please also see the Request for Thoughts section,
-as the whole point of this pre-release ist to collect ideas for
-improvement and bug reports.
-
-
-INSTALLATION:
-
-  - Get and install pcre from
-    ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
-    Version 3.1 or any later one will do. I recommend 3.4.
-    It *should* install on Win32 as well, but I haven't tried
-    that. Don't forget to run ldconfig afterwards.
-
-  - Now you have two options:
-
-    A) Install pcrs as a shared library:
-       pcrs.c and pcrs.h are included in the (patched) ijb subdirectory.
-       1.) patch Makefile < Makefile.re_shared.diff  
-       2.) gcc -Wall -fPIC -c pcrs.c  
-       3.) gcc -shared -Wl,-soname,libpcrs.so.1 -o libpcrs.so.1.0.1 pcrs.o -lc -lpcre
-       If this worked OK,
-       4.) copy libpcrs.so.1.0.1 to /usr/local/lib
-       5.) ln -s /usr/local/lib/libpcrs.1.0.1 /usr/local/lib/libpcrs.so
-       6.) ldconfig (Or whatever the equivalent on your platform might be)
-       7.) cp pcrs.h /usr/local/include
-
-    OR
-
-    B) Incorporate pcrs into the junkbuster (much easier):
-       Smile and relax. You're done.
-
-  - Edit the provided re_filterfile to suit your needs and place it
-    with the rest of junkbusters configfiles.
-
-  - Now junkbuster should build with a simple 'make'.
-    Note: Setting debug = REF in jcc.c will enable debugging
-    for the re_filter.
-
-  - Include a line "re_filterfile <wherever>" in your junkbuster
-    config file, pointing at the re_filterfile
-
-  - (Optional:) Include a line "re_filter_all" in the config
-    file. This will set the Policy to filter content from all sites.
-    Default is to filter only from sites that you wouldn't send a
-    cookie either. 
-
-  - Fire up junkbuster.
-
-HOW IT WORKS:
-
-    Nah, not tonight anymore ;-)
-
-REQUEST FOR THOUGHTS:
-
-  - The main decision is whether to filter on-the-fly or to buffer
-    up the whole document and then run the filter on it. I've built
-    both versions and currently prefer buffering.
-
-    The advantage of on-the-fly-filtering is obviously that the
-    document begins to display before it's fully loaded. The big
-    disadvantage is that with arbitraty content altering in place,
-    you don't know the size that the document will have after
-    altering when the Content-Length Header is to be sent. Only
-    option is to chew it altogether.
-
-    Apart from preserving the ability to generate a valid Content-Length
-    header (which the patch currently does not yet do), buffering up
-    the document has some advantages from the filtering point of view:
-
-     - Reliability. Patterns in the document cannot be ripped apart
-       and are reliably found. (If you look at the document fragment-wise
-       while it's being transmitted, you miss any pattern that spans
-       a fragment border) This is especially bad for patterns that do
-       serious HTML reformatting, as fragments are typically in the order
-       of 1500 bytes each.
-
-     - Flexibility: The re_filter gives you the choice whether you want
-       to replace only the pattern's first occurance or replace it globally.
-       This becomes meningless with fragments. (Solution possible, though.)
-
-    As the filter only processes objects of MIME type text/*, which are typically
-    rather small compared to binary multimedia (sic) type data, I don't think
-    that the disadvantage of delayed display of the first bytes is really grave.
-
-    What do you think?
-
-  - Is the choice between a radical (filter all) and semi-smart (filter only when
-    also crunching cookies) flexible enough? Should I really introduce yet another
-    configfile for specifying the domains to filter content from? Would anyone use
-    that?
-
-  - Should I use pcre as a shared library and work out a nice installation
-    automagic, or should the relevant functions be incorporated in re_filter.c?
-
-  - Even if yes, do we really want an extension that relies on an external library
-    like pcre?
-
-  - Any bugs, stupid parts in the code ?
-
-  - Cool suggestions for the re_filterfile? (PLEASE!)
-
-  - Should character set translation along the lines of Perl's 'tr' operator
-    be included?
-
-  - Is the whole feature just pathetic?
-
-FEEDBACK:
-
-    A whole lot of work has gone into this feature (the pcrs code was also
-    just written for this) and I'd really like to know if and how you like
-    it. Since I'm more of a perl than C programmer (and after doing so much
-    string manipulation in C I'm once again glad abaout that!), I'm sure there
-    is much to improve. Please send any suggestions/observations/hellos to
-    oes@paradis.rhein.de. I would also be very glad about any assistance for
-    a autoconf/make procedure for prcs.
-
-Well, have fun!
---Andreas
-
-
-*****************************************************************************
-* Copied from old README.cygwin                                             *
-*****************************************************************************
-
-Id: README.cygwin,v 1.2 2001/04/29 23:16:29 rodney Exp
-
-
-What I did:  I saw too many "personalities" in IJB; so I
-ran the code through a couple of regexp's and then let XEmacs
-reformat the whole shebang!  The results is a uniform
-looking code base; aka. as if 1 person created the whole
-project.
-
-Why I did it:  (1) it is easier to maintain  (2) easier for
-a new person to make changes/additions  (3) it *looks* more
-professional  (4) IMHO, it is easier to read (this is very
-much a personal preference).
-
-What I propose: A IJB standards list be included in the
-distro and all source/patch checkins be checked for
-compliance.  We don't need to be an arse on this point, but
-submitters should make a valiant attempt to support the
-standards.
-
-Note: do not even try to diff my code with another code
-base, you will be overwhelmed.  After all, the regexps did a
-good bit of changing and XEmacs reformatter did a great deal
-more.
-
-One more note: these changes include conditional compilation for
-un?x (namely Linux), cygwin (un?x like compile for WIN32), and
-mingw32 (WIN32 like compilation w/o VC++).  Right now, all seems
-fully functional except cygwin.  The cygwin compile will work,
-but includes code to make it single threaded.  I need to debug
-the fork issues, but that will have to come later.
-
-
-Specific changes to expect:
-
-
-1: I've majorly reworked the Makefiles.  The existing Makefile was
-too *spaghetti* for me!  For one, I eliminated the "-I." from the
-include path (ugly).  Use #include "" for local directory files
-and #include <> for path found files (that's basic even to c).
-
-
-2: In accordance with #1, I changed #include "windows.h" to
-#include <windows.h> and #include <gnu_regex.h> to #include
-"gnu_regex.h".
-
-
-3: As part of my standards suggestions (to come later in this
-file), I added a standard comment block to every function.  There
-were too many functions with *no* comment and about 20 different
-styles to those that did.  This is an example of the block I used:
-/*********************************************************************
- *
- * Function    :  block_acl
- *
- * Description :  Block this request?
- *                Decide yes or no based on ACL file.
- *
- * Parameters  :
- *          1  :  src = Address the browser/user agent is requesting.
- *          2  :  dst = The proxy or gateway address this is going to.
- *          3  :  csp = Current client state (buffers, headers, etc...)
- *
- * Returns     : 0 = FALSE (don't block) and 1 = TRUE (do block)
- *
- *********************************************************************/
-
-
-4: Some files prototyped like this:
-      void
-      func(param1)
-      int param1;
-      {
-      }
-and other like this:
-      void func(int param1)
-      {
-      }
-I made all look like the second.
-
-
-5: Made:
-      if(  to be  if (
-      while(  to be  while (
-      switch(  to be switch (
-      etc ...
-The former looks too much like a function call.
-
-
-6: Put braces on their own line and aligned under the
-reserved word:
-      if () {
-      } else {
-      }
-to be:
-      if ()
-      {
-      }
-      else
-      {
-      }
-The same for while, do, etc...
-
-
-7: Casted malloc in several places, e.g.:
-      p = malloc(n);
-to be:
-      p = (char *)malloc(n);
-This eliminates compiler warnings.
-
-
-8: Applied the Perl regexp patch and made it fully conditionally
-compiled (-DPCRS=TRUE).
-
-
-9: It *appears* that if MINGW32 sees a "main" function, it will
-try to link it and start with main (ala console mode).  Since I
-need MINGW32 to find WinMain instead, I conditionally changed
-"main" to "_main" (for MINGW32 only!).
-
-
-10: Changed popup.c to be killpopup.c.  This was necessary to
-clean up the Makefile.  Since there was an ini type file called
-"popup" and "popup.c", make got confused on target names.  No
-other ini file has a .c file with the same name, so I hope this
-isn't a big deal.  Plus, it fits its config variable
-(kill_all_popups) much better.
-
-
-11: Added:
-  /*
-    Local Variables:
-    tab-width: 3
-    end:
-  */
-to all .c and .h files.  I use 3 character tabs and this will make
-the files display correctly in Emacs editors.  This is just my
-default setting.  Perhaps I will filter all files via "expand
--t3", so not to pi$$ everyone off.  Vi is capable of using 3
-character tabs, as I am sure VC++ would be.
-
-
-12: Several places included regexp code with out "#ifdef REGEX"
-which broke the ability to compile w/o regexp's.  I fixed the code
-and can compile w/o regexp (which I don't normally do, but now I
-*can*).
-
-
-13: In WinMain, changed:
-      pszLastTok = strchr(pszLastTok, ' ');
-to be:
-      pszLastTok = strchr(pszLastTok+1, ' ');
-The former causes an infinite loop with 2 or more parameters.
-
-
-14: Added my own strdup for Cygwin, see jcc.c for why.
-
-
-15: Added defines in the Makefile and this to jcc.h:
-      #define VERSION VERSION_MAJOR "." VERSION_MINOR "." VERSION_POINT
-This makes "update the numbers also in jcc.h manually" unnecessary
-(see your Makefile for this quote).
-
-
-16: Split the "inifiles" target in Makefile into separate targets,
-this way each file can be regenerated individually according to
-the same implicit rule.
-
-
-17: With the Makefile restructure, I can only provide for
-Cygwin/gcc.  Hopefully this is a bit cleaner and others can add
-their compilers w/o re-spaghetting the file.  I have provided
-several makefiles as examples only, I do not intend for the
-project to start maintaining multiple Makefiles.  Perhaps some of
-the platform specific Makefile code could be split out into
-separate files and we could use the "include" directive to read in
-the correct one.
-
-Better than this, let's get a configure.in guru on the project and
-dynamically create the Makefiles!
-
-
-18: In an effort to get this to market (you knew this was coming
-eh?), I am going to put the standards suggestions in another file
-and ship this one as is.  But then, you can probably guess most of
-the standards by the changes you see.
-
-
-19: Added a really quick and dirty "install" target to the
-Makefile.  This needs to be cleaned up and proper directories put
-in for each platform.
-
-
--- release 1 (obsoleted) --
-
-
-20: Incorporated the TOGGLE and webDAV support patches into my
-Cygwin patch.  I added conditional compilation to both features.
-I changed "extern BOOL g_bToggleIJB;" to be of type "int".  This
-makes jcc.h independent of "windows.h".  The inclusion of such
-should not (and is not) necessary for compilation on all
-platforms.  Besides, BOOL is really only a char or an int anyway!
-
-
-21: Added a new ini!  I modified the usual un?x type config file
-to M$ type ini file for a Perl regexp compile.  This was necessary
-to call EditFile on the Perl regexp config file.  The new ini
-filename is "sregexp.ini" (naturally).  I then added menu items to
-edit the popup.ini and sregexp.ini files.
-
-
-22: I made "dot h" files for all the "dot c" files.  I used this
-command to do the *dirty* work:
-    grep -e "^[A-z]" *.c | sed -e "/=/d" -e "/^[^(]*$/d" \
-         -e "/^extern/d" -e "/^static/d" -e "/;$/d"
-
-And I made each "dot h" file be immune to multiple inclusion via
-conditional compilation.  Ie. the "jcc.h" file will only include
-itself if _JCC_H is undefined.
-
-After this was done, I compiled the project source by source and
-let the compiler tell me what each file was dependent on.  Once I
-got all the objects to compile, I included the new dependencies in
-the Makefiles.
-
-BTW, I intend to get the Makefile to be generated by a configure
-script.  Whether this is a GNU "configure.in" type file or a shell
-script, I do not know.  All I do know is that this is a must for a
-"Go/No go" type decision.  We cannot proceed with the philosophy
-"leave it up to the user to get it to work".
-
-
-23: I broke out the code to load the config file from main.  I put
-this code into a function called load_config.  I made this routine
-be called from a signal "HUP".  This means we can restart
-junkbusters from the command line or from the daemon script via
-"restart" without actually killing it and restarting it.  This is
-common behavior to un?x daemons (see inetd for example).  I fixed
-the junkbusters.init script to take advantage of this.  I intend
-to make a M$ menu complement to this as soon as I can.
-
-
-24: BTW, if you have not already noticed by my postings and/or
-code, I have added patches and made them all conditionally
-compiled.  Ie. #ifdef TOGGLE, #ifdef WEBDAV, #ifdef PCRS, etc...
-I think that all extensions to IJB should be submitted in this
-way.  Not only can you compile IJB to be as "tight" as you want,
-it also gives the user a "smorgasbord" of options to
-choose from.  This is quite common in the free software world (you
-need look no farther than emacs to see this) and provides maximum
-flexibility.
-
-
-25: As promised, I obsoleted the "ijbw32.ini" file.  I was a bit
-confused by the "close-behaviour=1" entry.  It seems to me that it
-duplicated the "close-button-minimizes=1" entry.  And (by looking
-at the code) it was unused.  Anyway, I eliminated the "ijbw32.ini"
-file and assimilated the settings into the config file.  Bye Bye
-"ijbw32.ini", hello "config" (aka. don't unnecessarily duplicate
-files and/or data types).
-
-
-26: Eliminated re_filter.c.  This only defined
-(un)load_re_filterfile and re_process_buffer.  I moved
-(un)load_re_filterfile to loaders.c and re_process_buffer to
-filters.c. I also modified the Makefiles to reflect this.  In the
-doing, I modified the loader and unloader to use the "files"
-variable and moved joblist to "re_filterfile_spec" struct.  I
-added "plist" to the client_state so that all Perl regexp code
-could find the latest parsing of the re_filterfile ini.
-
-This is in keeping with the IJB data structures philosophies.
-
-
-27: Eliminated acl.c.  This (as pcre) only defined
-(un)load_aclfile and block_acl.  I moved (un)load_aclfile to
-loaders.c and block_acl to filters.c.  I also modified the
-Makefiles to reflect this.
-
-
-28: Since I created "dot h" files for all the "dot c" files, I
-eliminated all the "extern ...variable;" and all the "extern
-...function;" statements that I could find in the "dot c" files.
-Instead, I included the proper "dot h" files to do this for us.
-
-
-29: Corrected the "install" Makefile target for un?x.  I will do
-the same for WIN32 targets.
-
-
-30: Note on the "TOGGLE" patch: since I made IJB fully restartable
-via a NOHUP signal; I thought the TOGGLE patch should apply to
-both un?x and WIN32.  Thus, I eliminated the WIN32 dependencies in
-that patch and added "toggle" to the config file.  Now everything
-works fine for either platform.  Still to come is a restart menu
-command in WIN32 (See: note 23).
-
-
-31: Just a possible programmer note, we REALLY need a generic
-linked list module.  Since text lists, client states, filter
-files, etc... implement list creation and destruction over and
-over; I suggest a generic list that can handle *any* type of list
-(ala template classes in C++).  If this module included an
-iterator (of sorts), we could eliminate the myriad of "for ( top=x;
-NULL != x->next; x=x->next )" type statements that are all over
-IJB.
-
-After all, this was taught in the basic "Intro to Data Types"
-class (for all you CS majors).
-
-
-32: Renamed all of the .INI files to be .TXT files.  I did this
-because the .INI files were NOT *really* ini files; which
-potentially be confusing.  I used the .TXT extension to make sure
-that EditFile still worked.
-
-
-33: Removed the "initialed comments", such as "/* swa */".  This
-leads to less readable code (because it becomes fragmented) and
-retains the "multiple personality" syndrome.  Comments such as
-this can always be figured out from the versioning system.  Also,
-these comments really should be pooled in one place : the README
-files.
-
-
-34: Perhaps we should break with the current versioning tactic of 
-a "tail version" and start fresh.  Perhaps a new major version
-release is in order?  Version = 3.0.0?
-
-
-35: Added a "Accept-Encoding: gzip" cruncher.  If a stream is
-compressed via gzip (Netscape specific I think), then it cannot
-be modified with Perl regexps.  So I added this as an option in
-the Makefiles.
-
-
-36: As promised in one of my postings, I have make a
-configure-esk script to generate the Makefiles.  I would still
-like to have a full blown configure.in compatible system, but this 
-will do in the meantime.  Note: this configure script covers
-linux, cygwin, and mingw32.  At this point I do not have VC++ to
-test any of my changes.  But the configure script should be
-flexible enough to handle this platform.
-
-
---
-
-Please give any feedback to the ijb egroups and, if you feel you
-need quicker contact, CC me at IwantToKeepAnon@yahoo.com
-
-Let me say once more, this has a *lot* of changes and may (aka
-WILL) break a lot of existing patches.  But I hope the "idea" will
-catch on.  Perhaps this could be made the baseline code base and
-other patches added and standardized later.
-
-*****************************************************************************
-* Date:        7 May 2001                                                   *
-* Version:     ??                                                           *
-* Description: Changes for MS Visual C++                                    *
-* Author:      Jon Foster <jon@jon-foster.co.uk>                            *
-*****************************************************************************
-(Based on Stromlund's version 0.20)
-
-I have made several changes to make this compile under VC++ 97, and add new
-features.
-
-Code changes:
-
-1) If you disable IJB (using the TOGGLE patch) it now turns PCRS off.
-2) "Missing function prototype" warnings have been corrected by adding
-   appropriate #include statements
-3) The _DIST_URL define removed and hardcoded.  There are hardcoded URLs all 
-   over the place that need fixing - one more doesn't matter.  We do really 
-   need to come up with a long-term solution though.  (Suggestion: Host a 
-   redirector on the SourceForge web space.  e.g 
-   "http://ijbswa.sourceforge.net/redirect.php?ver=2.0.2-10&target=faq",
-   "http://ijbswa.sourceforge.net/redirect.php?ver=2.0.2-10&target=download",
-   etc.  This allows us to move the pages around easily, and the SourceForge
-   space can be maintained by anyone who's interested, it's not tied to a 
-   particular individual.  This is similar to the approach taken by 
-   Microsoft and Netscape in their browsers.)
-4) New file ijbconfig.h is #included everywhere.  This provides me with a
-   place to define VERSION, PCRS, etc.  You can still define VERSION_xxx
-   on the command line, but the other defines are in the header file.
-   There were just too many #defines - so many that the VC++ 97 IDE 
-   broke when I tried to define them on the command line.  We probably 
-   should fix the configure script so that it modifies this file.
-5) Deleted empty file afxres.h - we needed to use the VC++ system header 
-   file of that name.  However, it's easier to just delete it and put 
-   the relevent #defines in w32res.h.
-6) New #define: NO_PROGRAM_NAME_DISPLAY uses "IJB" as the program name in 
-   the log file instead of "H:\Documents and Settings\Administrator\My 
-   Documents\Prog\VC\ijb2\Release\junkbuter.exe" or similar.  The reason 
-   for this should be obvious!
-7) New #define: STATISTICS enables the statistics feature
-8) Statistics is thread-safe, I think.  However, loading up the
-   statistics page now counts as a blocked request.
-9) New, shorter message if a setting in the config file is recognised 
-   but unsupported by the current build.  It doesn't have "WARNING:" in
-   front of it either.  We may want to actually take this message out 
-   and have it just silently ignore these entries.
-10) New feature: #define SPLIT_PROXY_ARGS and the show-proxy-settings 
-    page will split each file out to a seperate page.  This is 
-    because the files are quite big, and having to do 1 extra click to 
-    get to them is no problem.  This #define also disables the 
-    suppress_blocklists feature (because I believe the original intent 
-    of suppress_blocklists was similar?).  It also saves memory by 
-    reading the config files to generate the HTML on the fly, rather 
-    than storing prepared HTML constantly in memory.
-11) Marked global constants with "const" attribute.  This has a 
-    knock-on effect on pointers in function prototypes, so these have
-    also been marked const where needed.
-12) Rewrote encode.c to have tables pre-initialized, so it can be 
-    marked constant.  Also split into 3 distinct functions so that
-    the tables (which are realy an implementation detail) are not
-    visible outside that file.
-13) Changes to how files are reloaded when you reload the config 
-    file.  Previous method didn't free memory (or if you uncommented 
-    the free() calls, it was not thread-safe.)  It is now handled 
-    automatically - files are reloaded whenever the filename to 
-    read changes, or the file's timestamp changes.  The code in
-    loaders.c which handles this test has been moved to a single
-    utility function.
-14) killpopup changes:
-     * Only compiled if you #define KILLPOPUPS
-     * Call to filter_popups() moved from read_socket() to chat().
-     * Writing 1 past end of buffer bug fixed.
-     * It was scanning the whole buffer even if only partially filled.
-     * Moved load/unload to loaders.c and changed file handling to 
-       follow standard.
-15) Auto-detect whether we want an image or HTML implemented for 
-    Microsoft IE.  :-)
-    There doesn't seem to be a way to tell with the latest build 
-    of Mozilla. :-(
-16) Image file code conditionally compiled.
-17) Provided option (SPLIT_PROXY_ARGS) to split the show-proxy-args
-    page into a main page, and then a page for each config file.  
-    This option will also save memory by loading the files when 
-    required for display, rather than saving them in memory when
-    they are initially loaded.
-18) Force page loading ("noijb.") patch applied.  #define FORCE_LOAD
-
-
-Packaging changes:
-
-1) PCRE 3.4 (less it's test and demo programs) is now included in the 
-   pcre directory.  It will be statically linked with Junkbuster.  (On 
-   win32, DLLs cause a lot of hassle - with a library this small it isn't 
-   worth it.  I don't know if it would be better to dynamically link under
-   UNIX?)
-2) junkbustr.dsp and junkbustr.dsw VC++97 project and workspace files are
-   included.
-3) win32build/junkbustr.exe Win32 binary is included.  It should not require
-   any DLLs.  It was compiled with all features supported.
-4) All README.xyz files put together in this file.
-5) Unused files (acl.c, pthread.c, ...) deleted.
-6) My block & cookie files used (based on the Waldherr ones).
-
-Known bug: The Adobe Acrobat 4 plug-in fails when I try to view PDF files in
-MSIE.  Workaround: disable "web browser integration" in the Adobe Acrobat 
-settings.
-
-*****************************************************************************
-* Date:        14 May 2001 (early morning)                                  *
-* Version:     Reported as 2.9.0                                            *
-* Description: Various updates                                              *
-* Author:      Jon Foster <jon@jon-foster.co.uk>                            *
-*****************************************************************************
-
-1)  Now use PCRE, not GNU REGEX.  I have not yet had chance to check the
-    syntax of the block/image/cookie file to ensure that they match what
-    is expected - however they seem to work.
-2)  Replaced "configure" script with one generated by "autoconf".  Also 
-    use a header "config.h" (was ijbconfig.h in my previous release) for 
-    the #defines.  "config.h" is now generated with "autoheader" from 
-    "acconfig.h" and "configure.in".  (Note that to install you do not
-    need autoconf or autoheader - just run "./configure".)
-    To see command-line options, run "./configure --help".
-    This is my first ever autoconf script, so it has some rough edges
-    (how PCRE is handled is the roughest).
-3)  Error logging code replaced with new module errlog.c, based on the
-    one from JunkBusterMT (but with the threading code removed).
-4)  Most of Rodney's 0.21 and 0.21A patches applied. (Marked *).  I did not
-    apply all of these, since I had already independently done conditional
-    popup file, conditional image file, and integration of popup code.
-5*) ACL, Jar and trust files conditionally compiled.
-6*) New source file headers.
-7*) Various cosmetic changes.  (But I have not consistently ordered the 
-    config files - I think that's worthwhile, but it's 1am and I want to
-    get this released!)
-8*) RCS tags on .h files.
-9)  RCS tags are const char[] rather than const char *.  (Saves 4 bytes
-    per tag ;-)
-10) VC++ project files renamed to vc_junkbuster.*.
-11) show-proxy-args now shows status of all conditionals, not just REGEX
-12) Various functions moved around.  Most notably all the system-specific
-    sockets code which was spread between jcc.c, bind.c, and connect.c,
-    has been moved to "jbsockets.c".  The non-system-specific code from
-    connect.c and socks4.c has been movet to "gateway.c".  Also, the
-    config file loader and the global variables it writes to have been
-    moved to "loadcfg.c".  (Maybe this should go into loaders.c?)
-    And candidate for the "worst filename ever" award is "miscutil.c",
-    which contains, well, miscellaneous utility functions like zalloc.
-    (Suggestions for a better name for this file are welcome!)
-13) Loaders now use a common function to read a line and skip comments,
-    and this function also stores the proxy_args.
-14) Added ./junkbuster --help     (Not for Win32 GUI)
-15) Added ./junkbuster --version  (Not for Win32 GUI)
-16) Win32 resources are now all marked as "U.S. English", rather than
-    being a mix of "U.S. English", "U.K. English" and "Irish English".
-17) Version number changes to 2.9.0
-
-Known bugs:
-- See (1) above about blockfiles.
-- Sending SIGHUP (under Red Hat Linux 7.1) causes a crash.  v0.21A hangs
-  after a SIGHUP.  This needs investigating, but pthreads support will 
-  almost certainly help here, so it may not be worth investigating
-  immediately.
-- Compiling with shared system pcre and pcreposix libraries is supported
-  via a switch to configure, but completely untested.
-
-Please note that there are now 2^14 == 16384 combinations of conditional 
-defines, and 4 major compilers (VC, Linux, mingw32, cygwin) for a total 
-of 65536 different builds.  We cannot possibly test all of them!  My 
-standard build is "everything on", and I've tested that on each compiler,
-along with a few variants.  You may uncover new bugs (probably compiler 
-errors) if you use an exotic combination of switches.
-
-*****************************************************************************
-* Date:        14 May 2001                                                  *
-* Version:     2.9.1                                                        *
-* Description: Various updates                                              *
-* Author:      Andreas S. Oesterhelt <oes@oesterhelt.org>                   *
-*****************************************************************************
-(From his e-mail:)
-
- - in parsers.c, fixed two #ifdef FORCE to #ifdef FORCE_LOAD
-   (BTW: I think FORCE is precise enough, since loading remote
-   data is the whole purpose of a proxy..)
- - Set the FORCE_PREFIX (back) to 'IJB-FORCE-LOAD-'. While 'noijb.'
-   is more elegant and looks like a hostname in the URL, it doesn't
-   make clear to the inexperienced user that the proxy is bypassed. It
-   also has a higher name collision risk.
- - Filled in the function header templates for my functions in
-   parsers.c (again). They obviously got lost in our current
-   patch war ;-)
- - Cut the credit for the Â§-referrer-option from the config file,
-   that Stefan had placed there.
- - Improved the re_filterfile 
-
-*****************************************************************************
-* Date:        14 May 2001                                                  *
-* Version:     2.9.2                                                        *
-* Description: FORCE patch (again!)                                         *
-* Author:      Andreas S. Oesterhelt <oes@oesterhelt.org>                   *
-*****************************************************************************
-(These notes written by Jon)
-
-- Andreas applied the latest version of the FORCE patch.
-
-*****************************************************************************
-* Date:        14 May 2001 (late afternoon)                                 *
-* Version:     2.9.3                                                        *
-* Description: Various updates                                              *
-* Author:      Jon Foster <jon@jon-foster.co.uk>                            *
-*****************************************************************************
-
-1) Incorporated updates from current CVS tree, including:
-   - Amiga support (completely untested by me - I don't have an Amiga)
-   - "tinygif 3" support (redirects blocked images to a specified URL, so
-     the browser doesn't have to load and cache many copies of the same
-     image).
-   - one case where there were both local and global "referrer" variables
-     (yuck!) clarified by renaming the local one to "refer".
-   - Fixed some places where close() was used instead of close_socket().
-   Thanks to Jörg Strohmayer (joergs at users.sourceforge.net) for these.
-2) Temporary hack to get FORCE_LOAD to work with IE.  I just lowercased the
-   FORCE_LOAD_PREFIX.  Needs fixing properly.
-3) Most URLs hardcoded into JunkBuster were changed to go through a script
-   e.g. http://ijbswa.sourceforge.net/redirect.php?v=2.9.3&to=faq
-   The only other URLs left are the GNU GPL:
-     http://www.fsf.org/copyleft/gpl.html
-   and the home page:
-     http://ijbswa.sourceforge.net/
-   ... and various URLs which will be intercepted by JunkBuster anyway.
-   TODO: Still need to do something with the URLs in JunkBuster Corp's 
-   copyright/trademark notice on the bottom of the show-proxy-args page.
-4) PCRE or GNU Regex is now a #define option.
-
-*****************************************************************************
-* End of file                                                               *
-*****************************************************************************
-
index 7f0b610..830fa2f 100644 (file)
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
+<!-- $Id: gpl.html,v 1.3 2002/03/26 22:29:55 swa Exp $\r
+\r
+     See copyright details at end of file\r
+\r
+     After changing this file, please run it through "HTML Tidy"\r
+     (from http://www.w3.org/People/Raggett/tidy/)\r
+     It should have no warnings or errors.\r
+-->\r
+\r
 <html>\r
-<head>\r
-<!-- Copyright 1996-8 Junkbusters Corporation -->\r
-<!-- This work comes with NO WARRANTY -->\r
-<!-- It may be redistributed and modified under the GNU GPL-->\r
-<!-- See the body of http://www.junkbusters.com/ht/en/gpl.html for details-->\r
-<!-- Junkbusters is a registered trade mark of Junkbusters Corporation -->\r
-<!-- Generated 1998/10/31 03:58:25 UTC -->\r
-<meta name="Generator" content="Junkbusters Ebira $Revision: 1.1 $ $Date: 2001/04/16 21:10:38 $">\r
-<!-- Document  ID: $Revision: 1.1 $ $Date: 2001/04/16 21:10:38 $ -->\r
-<title>\r
-The GNU General Public License\r
-</title>\r
-<base href="http://www.junkbusters.com/ht/en/gpl.html">\r
-<meta name="description" content="We did not write the GPL: the Free Software Foundation did | The GPL allows copying and changing of copyrighted documents | Version 2, June 1991 | Preamble | GNU General Public License: Terms and Conditions for Copying, Distribution and Modification | Appendix: How to Apply These Terms to Your New Programs">\r
-<meta name="keywords" content="stop, junk, busters, junkbusters, junkbuster, mail, email, e-mail, direct, spam, spamoff, declare, telemarketing, telemarketers, privacy, sharing, names, renting, direct, marketing, database, databases, junk mail, lists, environment, conservation, recycling, catalogs, consumer, sending, opt out ">\r
-<link rel="next" href="precre.html">\r
-<link rel="previous" href="precre.html">\r
-<link rel="contents" href="toc.html">\r
-</head>\r
-<body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink="#787878">\r
-<p align="center">\r
-<a name="top_of_page" href="legal.html#marks">\r
-<img border=0 width=160 height=34 src="/images/trans_tn.gif" alt="Junkbusters"></a>\r
-</p>\r
-\r
-<center>\r
-<h1>The GNU General Public License\r
-</h1>\r
-</center>\r
-<!-- Translators: no -->\r
-<center>\r
-<h2><a name="notus"><font face="arial, helvetica">\r
-We did not write the GPL: the Free Software Foundation did\r
-</font></a>\r
-</h2>\r
-</center>\r
-\r
-<h3><a name="allows" href="/cgi-bin/gp?pg=gpl&pr=allows"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-The GPL allows copying and changing of copyrighted documents\r
-</h3>\r
-<p>\r
-<a name="fsf">The Free Software Foundation</a>\r
-<a href="http://www.fsf.org/fsf/fsf.html">(FSF)</a>\r
-is a non-profit institution\r
-that designed the GNU General Public License (GPL) to promote the\r
-publication of free software.\r
-The GPL is used by thousands of programmers\r
-who want to give others the right to copy and modify\r
-the source code of their programs. Millions of people benefit from this.\r
-<p>\r
-<a name="junkbuster">We use the GPL</a>\r
-to allow everyone to use, copy and modify the\r
-<a href="ijb.html">Internet Junkbuster</a>\r
-as they wish.\r
-<a name="separate">Companies can use it for commercial purposes,</a>\r
-but they are not permitted to use it in products that they claim\r
-as their property\r
-without negotiating a separate agreement with us beforehand.\r
-<p>\r
-<a name="text">The GPL</a>\r
-<a href="http://dsl.org/copyleft/">can also be used</a>\r
-on documents written in human languages.\r
-We give everyone permission to use everything on our web site under the GPL.\r
-This means that you do not have to break copyright laws in order\r
-to print a page or email a screen of the text to someone, for example.\r
-Many sites do not permit you to do these things.\r
-<p>\r
-<a name="best">If you have a home page,</a>\r
-we recommend that you consider using the GPL to\r
-allow others the right to copy and use all the documents you create for it.\r
-If you just mark a page as copyright, they won't even\r
-legally be able to print it.\r
-If you don't state you are its copyright owner,\r
-they could change it slightly and claim it as their own property. \r
-By marking it with both copyright and GPL notices\r
-you allow them to copy it but not to claim\r
-anything derived from it as their own.\r
-<p>\r
-<a name="protect">The GPL protects your</a>\r
-<a href="declare.html">J<small>UNK<i>BUSTERS</i></small> D<small>ECLARATION</small></a>,\r
-<a href="spamoff.html">Spam Offer</a>,\r
-and all documents from us that you publish on your home page\r
-or distribute to direct marketers by any other means.\r
-By making your\r
-D<small>ECLARATION</small>\r
-available to them under the GPL, you are\r
-<a href="precre.html#gpl">permitting them use to it, but never to claim it as their property,</a>\r
-even if they transform it.\r
-<p>\r
-<a name="rest">The</a>\r
-remainder of this page is the text of the GPL.\r
-As legal documents go it's relatively clear,\r
-but unfortunately it's fairly long because it has to cover\r
-a lot of details specific to computer programs\r
-that may not be relevant to\r
-D<small>ECLARATION</small>s.\r
-The hypertext links are ours, and should not be misinterpreted\r
-as an indication of emphasis by the FSF.\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<center>\r
-<h2><a name="v2"><font face="arial, helvetica">\r
-Version 2, June 1991\r
-</font></a>\r
-</h2>\r
-</center>\r
-<blockquote>\r
-<a name="crn">Copyright 1989, 1991</a>\r
-<br>\r
-<a name="address">Free Software Foundation, Inc.</a>\r
-<br>\r
-675 Mass Ave.\r
-<br>\r
-Cambridge, MA 02139\r
-<br>\r
-USA\r
-</blockquote>\r
-<a name="changing">Everyone</a>\r
-is permitted to copy and distribute verbatim copies\r
-of this license document, but changing it is not allowed.\r
-\r
-<h3><a name="pream" href="/cgi-bin/gp?pg=gpl&pr=pream"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Preamble\r
-</h3>\r
-<p>\r
-The licenses for most software are designed to take away your\r
-freedom to share and change it.  By contrast, the GNU General Public\r
-License is intended to guarantee your freedom to share and change free\r
-software--to make sure the software is free for all its users.  This\r
-General Public License applies to most of the Free Software\r
-Foundation's software and to any other program whose authors commit to\r
-using it.  (Some other Free Software Foundation software is covered by\r
-the GNU Library General Public License instead.)  You can apply it to\r
-your programs, too.\r
-<p>\r
-<a name="freedom">When we speak of free software,</a>\r
-we are referring to freedom, not\r
-price.  Our General Public Licenses are designed to make sure that you\r
-have the freedom to distribute copies of free software (and charge for\r
-this service if you wish), that you receive source code or can get it\r
-if you want it, that you can change the software or use pieces of it\r
-in new free programs; and that you know you can do these things.\r
-<p>\r
-<a name="forbid">To protect your rights,</a>\r
-we need to make restrictions that forbid\r
-anyone to deny you these rights or to ask you to surrender the rights.\r
-These restrictions translate to certain responsibilities for you if you\r
-distribute copies of the software, or if you modify it.\r
-<p>\r
-<a name="allrights">For example,</a>\r
-if you distribute copies of such a program, whether\r
-gratis or for a fee, you must give the recipients all the rights that\r
-you have.  You must make sure that they, too, receive or can get the\r
-source code.  And you must show them these terms so they know their\r
-rights.\r
-<p>\r
-<a name="steps">We protect your rights with two steps:</a>\r
-(1) copyright the software, and\r
-(2) offer you this license which gives you legal permission to copy,\r
-distribute and/or modify the software.\r
-<p>\r
-<a name="protection">Also,</a>\r
-for each author's protection and ours, we want to make certain\r
-that everyone understands that there is no warranty for this free\r
-software.  If the software is modified by someone else and passed on, we\r
-want its recipients to know that what they have is not the original, so\r
-that any problems introduced by others will not reflect on the original\r
-authors' reputations.\r
-<p>\r
-<a name="threat">Finally,</a>\r
-any free program is threatened constantly by software\r
-patents.  We wish to avoid the danger that redistributors of a free\r
-program will individually obtain patent licenses, in effect making the\r
-program proprietary.  To prevent this, we have made it clear that any\r
-patent must be licensed for everyone's free use or not licensed at all.\r
-<p>\r
-<a name="terms">The precise terms and conditions</a>\r
-for copying, distribution and\r
-modification follow.\r
-</p>\r
-\r
-<h3><a name="tnc" href="/cgi-bin/gp?pg=gpl&pr=tnc"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-GNU General Public License: Terms and Conditions for Copying, Distribution and Modification\r
-</h3>\r
-<p>\r
-<a name="applies">O.</a>\r
-This License applies to any program or other work which contains\r
-a notice placed by the copyright holder saying it may be distributed\r
-under the terms of this General Public License.  The "Program", below,\r
-refers to any such program or work, and a "work based on the Program"\r
-means either the Program or any derivative work under copyright law:\r
-that is to say, a work containing the Program or a portion of it,\r
-either verbatim or with modifications and/or translated into another\r
-language.  (Hereinafter,\r
-<a href="bus-ops.html#trans">translation</a>\r
-is included without limitation in\r
-the term "modification".)  Each licensee is addressed as "you".\r
-<p>\r
-<a name="scope">Activities</a>\r
-<a href="faqs.html#copying">other than copying, distribution and modification are not covered by this License;</a>\r
-they are outside its scope.  The act of\r
-running the Program is not restricted, and the output from the Program\r
-is covered only if its contents constitute a work based on the\r
-Program (independent of having been made by running the Program).\r
-<p>\r
-<a name="depends">Whether that is true depends on what the Program does.</a>\r
-<br><ol  type="1">\r
-<li>\r
-<a name="verbatim">You may copy</a>\r
-and distribute verbatim copies of the Program's\r
-source code as you receive it, in any medium, provided that you\r
-conspicuously and appropriately publish on each copy an appropriate\r
-copyright notice and disclaimer of warranty; keep intact all the\r
-notices that refer to this License and to the absence of any warranty;\r
-and give any other recipients of the Program a copy of this License\r
-along with the Program.\r
-<p>\r
-<a name="fee">You may charge a fee</a>\r
-for the physical act of transferring a copy, and\r
-you may at your option offer warranty protection in exchange for a fee.\r
-<li>\r
-<a name="modify">You may modify</a>\r
-your copy or copies of the Program or any portion\r
-of it, thus forming a work based on the Program, and copy and\r
-distribute such modifications or work under the terms of Section 1\r
-above, provided that you also meet all of these conditions:\r
-<br><ol  type="a">\r
-<li>\r
-<a name="notices">You must cause</a>\r
-the modified files to carry prominent notices\r
-stating that you changed the files and the date of any change.\r
-<li>\r
-<a name="nocharge">You must</a>\r
-cause any work that you distribute or publish, that in\r
-whole or in part contains or is derived from the Program or any\r
-part thereof, to be licensed as a whole at no charge to all third\r
-parties under the terms of this License.\r
-<li>\r
-<a name="interactive">If the modified program</a>\r
-normally reads commands interactively\r
-when run, you must cause it, when started running for such\r
-interactive use in the most ordinary way, to print or display an\r
-announcement including an appropriate copyright notice and a\r
-notice that there is no warranty (or else, saying that you provide\r
-a warranty) and that users may redistribute the program under\r
-these conditions, and telling the user how to view a copy of this\r
-License.  (Exception: if the Program itself is interactive but\r
-does not normally print such an announcement, your work based on\r
-the Program is not required to print an announcement.)\r
-</ol>\r
-<p>\r
-<a name="sections">These requirements</a>\r
-apply to the modified work as a whole.  If\r
-identifiable sections of that work are not derived from the Program,\r
-and can be reasonably considered independent and separate works in\r
-themselves, then this License, and its terms, do not apply to those\r
-sections when you distribute them as separate works.  But when you\r
-distribute the same sections as part of a whole which is a work based\r
-on the Program, the distribution of the whole must be on the terms of\r
-this License, whose permissions for other licensees extend to the\r
-entire whole, and thus to each and every part regardless of who wrote it.\r
-<p>\r
-<a name="intent">Thus,</a>\r
-it is not the intent of this section to claim rights or contest\r
-your rights to work written entirely by you; rather, the intent is to\r
-exercise the right to control the distribution of derivative or\r
-collective works based on the Program.\r
-<p>\r
-<a name="aggregation">In addition,</a>\r
-mere aggregation of another work not based on the Program\r
-with the Program (or with a work based on the Program) on a volume of\r
-a storage or distribution medium does not bring the other work under\r
-the scope of this License.\r
-<li>\r
-<a name="exeutable">You may copy</a>\r
-and distribute the Program (or a work based on it,\r
-under Section 2) in object code or executable form under the terms of\r
-Sections 1 and 2 above provided that you also do one of the following:\r
-<br><ol  type="a">\r
-<li>\r
-<a name="medium">Accompany it</a>\r
-with the complete corresponding machine-readable\r
-source code, which must be distributed under the terms of Sections\r
-1 and 2 above on a medium customarily used for software interchange; or,\r
-<li>\r
-<a name="written">Accompany it with a written offer,</a>\r
-valid for at least three\r
-years, to give any third party, for a charge no more than your\r
-cost of physically performing source distribution, a complete\r
-machine-readable copy of the corresponding source code, to be\r
-distributed under the terms of Sections 1 and 2 above on a medium\r
-customarily used for software interchange; or,\r
-<li>\r
-<a name="distrib">Accompany it</a>\r
-with the information you received as to the offer\r
-to distribute corresponding source code.  (This alternative is\r
-allowed only for noncommercial distribution and only if you\r
-received the program in object code or executable form with such\r
-an offer, in accord with Subsection b above.)\r
-</ol>\r
-<p>\r
-<a name="preferred">The source code</a>\r
-for a work means the preferred form of the work for\r
-making modifications to it.  For an executable work, complete source\r
-code means all the source code for all modules it contains, plus any\r
-associated interface definition files, plus the scripts used to\r
-control compilation and installation of the executable.  However, as a\r
-special exception, the source code distributed need not include\r
-anything that is normally distributed (in either source or binary\r
-form) with the major components (compiler, kernel, and so on) of the\r
-operating system on which the executable runs, unless that component\r
-itself accompanies the executable.\r
-<p>\r
-<a name="access">If distribution of executable or object code is made</a>\r
-by offering\r
-access to copy from a designated place, then offering equivalent\r
-access to copy the source code from the same place counts as\r
-distribution of the source code, even though third parties are not\r
-compelled to copy the source along with the object code.\r
-<li>\r
-<a name="otherwise">You may not copy,</a>\r
-modify, sublicense, or distribute the Program\r
-except as expressly provided under this License.  Any attempt\r
-otherwise to copy, modify, sublicense or distribute the Program is\r
-void, and will automatically terminate your rights under this License.\r
-However, parties who have received copies, or rights, from you under\r
-this License will not have their licenses terminated so long as such\r
-parties remain in full compliance.\r
-<li>\r
-<a name="voluntary">You are not required</a>\r
-to accept this License, since you have not\r
-signed it.  However, nothing else grants you permission to modify or\r
-distribute the Program or its derivative works.  These actions are\r
-prohibited by law if you do not accept this License.  Therefore, by\r
-modifying or distributing the Program (or any work based on the\r
-Program), you indicate your acceptance of this License to do so, and\r
-all its terms and conditions for copying, distributing or modifying\r
-the Program or works based on it.\r
-<li>\r
-<a name="redistrib">Each time you redistribute</a>\r
-the Program (or any work based on the\r
-Program), the recipient automatically receives a license from the\r
-original licensor to copy, distribute or modify the Program subject to\r
-these terms and conditions.  You may not impose any further\r
-restrictions on the recipients' exercise of the rights granted herein.\r
-You are not responsible for enforcing compliance by third parties to\r
-this License.\r
-<li>\r
-<a name="patent">If, as a consequence of a court judgment</a>\r
-or allegation of patent\r
-infringement or for any other reason (not limited to patent issues),\r
-conditions are imposed on you (whether by court order, agreement or\r
-otherwise) that contradict the conditions of this License, they do not\r
-excuse you from the conditions of this License.  If you cannot\r
-distribute so as to satisfy simultaneously your obligations under this\r
-License and any other pertinent obligations, then as a consequence you\r
-may not distribute the Program at all.  For example, if a patent\r
-license would not permit royalty-free redistribution of the Program by\r
-all those who receive copies directly or indirectly through you, then\r
-the only way you could satisfy both it and this License would be to\r
-refrain entirely from distribution of the Program.\r
-<p>\r
-<a name="invalid">If any portion</a>\r
-of this section is held invalid or unenforceable under\r
-any particular circumstance, the balance of the section is intended to\r
-apply and the section as a whole is intended to apply in other\r
-circumstances.\r
-<p>\r
-<a name="induce">It is not the purpose</a>\r
-of this section to induce you to infringe any\r
-patents or other property right claims or to contest validity of any\r
-such claims; this section has the sole purpose of protecting the\r
-integrity of the free software distribution system, which is\r
-implemented by public license practices.  Many people have made\r
-generous contributions to the wide range of software distributed\r
-through that system in reliance on consistent application of that\r
-system; it is up to the author/donor to decide if he or she is willing\r
-to distribute software through any other system and a licensee cannot\r
-impose that choice.\r
-<p>\r
-<a name="clarify">This section</a>\r
-is intended to make thoroughly clear what is believed to\r
-be a consequence of the rest of this License.\r
-<li>\r
-<a name="geog">If the distribution</a>\r
-and/or use of the Program is restricted in\r
-certain countries either by patents or by copyrighted interfaces, the\r
-original copyright holder who places the Program under this License\r
-may add an explicit geographical distribution limitation excluding\r
-those countries, so that distribution is permitted only in or among\r
-countries not thus excluded.  In such case, this License incorporates\r
-the limitation as if written in the body of this License.\r
-<li>\r
-<a name="revise">The Free Software Foundation</a>\r
-may publish revised and/or new versions   \r
-of the General Public License from time to time.  Such new versions will\r
-be similar in spirit to the present version, but may differ in detail to\r
-address new problems or concerns.\r
-Each version is given a distinguishing version number.  If the Program\r
-specifies a version number of this License which applies to it and "any\r
-later version", you have the option of following the terms and conditions\r
-either of that version or of any later version published by the Free\r
-Software Foundation.  If the Program does not specify a version number of\r
-this License, you may choose any version ever published by the Free Software\r
-Foundation.\r
-<li>\r
-<a name="permission">If you wish to incorporate parts</a>\r
-of the Program into other free\r
-programs whose distribution conditions are different, write to the author\r
-to ask for permission.  For software which is copyrighted by the Free\r
-Software Foundation, write to the Free Software Foundation; we sometimes\r
-make exceptions for this.  Our decision will be guided by the two goals\r
-of preserving the free status of all derivatives of our free software and\r
-of promoting the sharing and reuse of software generally.\r
-<p>\r
-<a name="nowarr">NO WARRANTY</a>\r
-<li>\r
-<a name="foc">BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,</a>\r
-THERE IS NO WARRANTY\r
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\r
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\r
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\r
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r
-REPAIR OR CORRECTION.\r
-<li>\r
-<a name="liable">IN NO EVENT UNLESS REQUIRED</a>\r
-BY APPLICABLE LAW OR AGREED TO IN WRITING\r
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r
-POSSIBILITY OF SUCH DAMAGES.\r
-</ol>\r
-END OF TERMS AND CONDITIONS\r
-</p>\r
-\r
-<h3><a name="append" href="/cgi-bin/gp?pg=gpl&pr=append"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Appendix: How to Apply These Terms to Your New Programs\r
-</h3>\r
-<p>\r
-If you develop a new program, and you want it to be of the greatest\r
-possible use to the public, the best way to achieve this is to make it\r
-free software which everyone can redistribute and change under these terms.\r
-<p>\r
-<a name="attach">To do so,</a>\r
-attach the following notices to the program.  It is safest\r
-to attach them to the start of each source file to most effectively\r
-convey the exclusion of warranty; and each file should have at least\r
-the "copyright" line and a pointer to where the full notice is found.\r
-<blockquote>\r
-&lt;one line\r
-to give the program's name and a brief idea of what it\r
-does.&gt;\r
-Copyright (C) 19yy\r
-&lt;name of\r
-author&gt;\r
-<p>\r
-<a name="free">This program is free software;</a>\r
-you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-<p>\r
-<a name="merchant">This program</a>\r
-is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-<p>\r
-<a name="ifnot">You should</a>\r
-have received a copy of the GNU General Public License\r
-along with this program; if not, write to the Free Software\r
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
-</blockquote>\r
-<p>\r
-<a name="contact">Also add</a>\r
-information on how to contact you by electronic and paper mail.\r
-<p>\r
-<a name="short">If the program is interactive,</a>\r
-make it output a short notice like this\r
-when it starts in an interactive mode:\r
-<blockquote>\r
-Gnomovision version 69, Copyright (C) 19yy name of author\r
-Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\r
-This is free software, and you are welcome to redistribute it\r
-under certain conditions; type `show c' for details.\r
-</blockquote>\r
-<p>\r
-<a name="hypo">The hypothetical</a>\r
-commands `show w' and `show c' should show the appropriate\r
-parts of the General Public License.  Of course, the commands you use may\r
-be called something other than `show w' and `show c'; they could even be\r
-mouse-clicks or menu items--whatever suits your program.\r
-<p>\r
-<a name="disclaimer">You should also get your employer</a>\r
-(if you work as a programmer) or your\r
-school, if any, to sign a "copyright disclaimer" for the program, if\r
-necessary.  Here is a sample; alter the names:\r
-<blockquote>\r
-Yoyodyne, Inc., hereby disclaims all copyright interest in the program\r
-`Gnomovision' (which makes passes at compilers) written by James Hacker.\r
-\r
-&lt;signature\r
-of\r
-Ty Coon&gt;,\r
-1 April 1989\r
-<br>\r
-Ty Coon, President of Vice\r
-</blockquote>\r
-<p>\r
-<a name="library">This General Public License</a>\r
-does not permit incorporating your program into\r
-proprietary programs.  If your program is a subroutine library, you may\r
-consider it more useful to permit linking proprietary applications with the\r
-library.  If this is what you want to do, use the GNU Library General\r
-Public License instead of this License.\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<font face="arial, helvetica">\r
-<a rel="begin" href="index.html">Home</a> <font color="#ff0000">\r
-<b> &#183; </b></font>\r
-<a rel="next" href="precre.html">Next</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="lopt.html">Site Map</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="legal.html">Legal</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkdata.html">Privacy</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="cookies.html">Cookies</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="ijb.html">Banner Ads</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="telemarketing.html">Telemarketing</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkmail.html">Mail</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkemail.html">Spam</a>\r
-\r
-</font><form action="/cgi-bin/search" method="GET">\r
-<input type="text" name="q" size=60 maxlength=120 value="">\r
-<input type="submit" value="Search"></form>\r
-<small>\r
-<small>\r
-<p>\r
-<a href="legal.html#copy">Copyright</a> &#169; 1996-8 Junkbusters\r
-<a href="legal.html#marks">&#174;</a> Corporation.\r
-Copying and distribution permitted under\r
-the <a href="gpl.html"><small>GNU</small></a>\r
-General Public License.\r
-</small>\r
-<tt>\r
-1998/10/31\r
-http://www.junkbusters.com/ht/en/gpl.html\r
-</tt>\r
-<address><kbd>webmaster&#64;junkbusters.com</kbd></address>\r
-</small>\r
-</body>\r
+  <head>\r
+    <title>The GNU General Public License</title>\r
+    <meta name="description" content=\r
+    "GNU General Public License, as used by Junkbuster">\r
+    <meta name="keywords" content="">\r
+<style type="text/css">\r
+<!--\r
+h2           { text-align: Center; font-family: arial, helvetica, sans-serif }\r
+p.sans       { font-family: arial, helvetica, sans-serif }\r
+b.dot        { color: #FF0000 }\r
+-->\r
+</style>\r
+  </head>\r
+\r
+  <body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink=\r
+  "#787878">\r
+    <p class="sans"><a href="http://www.privoxy.org/">\r
+    Website</a> <b class="dot">&middot;</b> <a href="ijbman.html">\r
+    Manual</a> <b class="dot">&middot;</b> <a href="ijbfaq.html">\r
+    FAQ</a> <b class="dot">&middot;</b> <b>GPL</b></p>\r
+\r
+    <h1 align="center"><a name="top_of_page">Internet J<small>UNK<i\r
+    style="color: #FF0000">BUSTER</i></small> License</a></h1>\r
+\r
+    <h1>This document is out of date</h1>\r
+\r
+    <p><b>Development of Junkbuster is ongoing and this document is\r
+    no longer current. However, it may provide some assistance. If\r
+    you have problems, please use the <a href=\r
+    "http://groups.yahoo.com/group/junkbuster-users/">Yahoo Groups\r
+    mailing list</a> (which includes an archive of mail), the\r
+    SourceForge.net <a href=\r
+    "http://sourceforge.net/projects/ijbswa/">project page</a>, or\r
+    see the project's <a href="http://www.privoxy.org/">home\r
+    page</a>. Please also bear in mind that versions 2.9.x of\r
+    Junkbuster are development releases, and are not production\r
+    quality.</b></p>\r
+\r
+    <h3 align="center">The GNU General Public License</h3>\r
+\r
+    <p class="sans"><a name="notus"><b>We did not write the GPL:\r
+    the <a href="http://www.fsf.org/fsf/fsf.html">Free Software\r
+    Foundation</a> did</b></a></p>\r
+\r
+    <h3><img border="0" width="14" height="14" src="fb.gif" alt=\r
+    "*">&nbsp; The GPL allows copying and changing of copyrighted\r
+    documents</h3>\r
+\r
+    <p><a name="fsf">The Free Software Foundation</a> <a href=\r
+    "http://www.fsf.org/fsf/fsf.html">(FSF)</a> is a non-profit\r
+    institution that designed the GNU General Public License (GPL)\r
+    to promote the publication of free software. The GPL is used by\r
+    thousands of programmers who want to give others the right to\r
+    copy and modify the source code of their programs. Millions of\r
+    people benefit from this.</p>\r
+\r
+    <p><a name="junkbuster">We use the GPL</a> to allow everyone to\r
+    use, copy and modify the Internet Junkbuster as they wish. <a\r
+    name="separate">Companies can use it for commercial\r
+    purposes,</a> but they are not permitted to use it in products\r
+    that they claim as their property.</p>\r
+\r
+    <p><a name="text">The GPL</a> can also be used on documents\r
+    written in human languages. This documentation for the Internet\r
+    Junkbuster is also under the GPL. This means that you do not\r
+    have to break copyright laws in order to print a page or email\r
+    a screen of the text to someone, for example.</p>\r
+\r
+    <p><a name="rest">The</a> remainder of this page is the text of\r
+    the GPL. As legal documents go it's relatively clear, but\r
+    unfortunately it's fairly long because it has to cover a lot of\r
+    details. The HTML formatting is ours, and should not be\r
+    misinterpreted as changing the license in any way.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" width=\r
+    "250" height="15" src="top.gif" alt=\r
+    "--- Back to Top of Page ---"></a></p>\r
+\r
+    <h2><a name="v2">Version 2, June 1991</a></h2>\r
+\r
+    <blockquote>\r
+      <a name="crn">Copyright 1989, 1991</a><br>\r
+       <a name="address">Free Software Foundation, Inc.</a><br>\r
+       675 Mass Ave.<br>\r
+       Cambridge, MA 02139<br>\r
+       USA\r
+    </blockquote>\r
+    <a name="changing">Everyone</a> \r
+\r
+    <p>is permitted to copy and distribute verbatim copies of this\r
+    license document, but changing it is not allowed.</p>\r
+\r
+    <h3><a name="pream"><img border="0" width="14" height="14" src=\r
+    "fb.gif" alt="*"></a>&nbsp; Preamble</h3>\r
+\r
+    <p>The licenses for most software are designed to take away\r
+    your freedom to share and change it. By contrast, the GNU\r
+    General Public License is intended to guarantee your freedom to\r
+    share and change free software--to make sure the software is\r
+    free for all its users. This General Public License applies to\r
+    most of the Free Software Foundation's software and to any\r
+    other program whose authors commit to using it. (Some other\r
+    Free Software Foundation software is covered by the GNU Library\r
+    General Public License instead.) You can apply it to your\r
+    programs, too.</p>\r
+\r
+    <p><a name="freedom">When we speak of free software,</a> we are\r
+    referring to freedom, not price. Our General Public Licenses\r
+    are designed to make sure that you have the freedom to\r
+    distribute copies of free software (and charge for this service\r
+    if you wish), that you receive source code or can get it if you\r
+    want it, that you can change the software or use pieces of it\r
+    in new free programs; and that you know you can do these\r
+    things.</p>\r
+\r
+    <p><a name="forbid">To protect your rights,</a> we need to make\r
+    restrictions that forbid anyone to deny you these rights or to\r
+    ask you to surrender the rights. These restrictions translate\r
+    to certain responsibilities for you if you distribute copies of\r
+    the software, or if you modify it.</p>\r
+\r
+    <p><a name="allrights">For example,</a> if you distribute\r
+    copies of such a program, whether gratis or for a fee, you must\r
+    give the recipients all the rights that you have. You must make\r
+    sure that they, too, receive or can get the source code. And\r
+    you must show them these terms so they know their rights.</p>\r
+\r
+    <p><a name="steps">We protect your rights with two steps:</a>\r
+    (1) copyright the software, and (2) offer you this license\r
+    which gives you legal permission to copy, distribute and/or\r
+    modify the software.</p>\r
+\r
+    <p><a name="protection">Also,</a> for each author's protection\r
+    and ours, we want to make certain that everyone understands\r
+    that there is no warranty for this free software. If the\r
+    software is modified by someone else and passed on, we want its\r
+    recipients to know that what they have is not the original, so\r
+    that any problems introduced by others will not reflect on the\r
+    original authors' reputations.</p>\r
+\r
+    <p><a name="threat">Finally,</a> any free program is threatened\r
+    constantly by software patents. We wish to avoid the danger\r
+    that redistributors of a free program will individually obtain\r
+    patent licenses, in effect making the program proprietary. To\r
+    prevent this, we have made it clear that any patent must be\r
+    licensed for everyone's free use or not licensed at all.</p>\r
+\r
+    <p><a name="terms">The precise terms and conditions</a> for\r
+    copying, distribution and modification follow.</p>\r
+\r
+    <h3><a name="tnc"><img border="0" width="14" height="14" src=\r
+    "fb.gif" alt="*"></a>&nbsp; GNU General Public License: Terms\r
+    and Conditions for Copying, Distribution and Modification</h3>\r
+\r
+    <p><a name="applies">O.</a> This License applies to any program\r
+    or other work which contains a notice placed by the copyright\r
+    holder saying it may be distributed under the terms of this\r
+    General Public License. The "Program", below, refers to any\r
+    such program or work, and a "work based on the Program" means\r
+    either the Program or any derivative work under copyright law:\r
+    that is to say, a work containing the Program or a portion of\r
+    it, either verbatim or with modifications and/or translated\r
+    into another language. (Hereinafter, translation is included\r
+    without limitation in the term "modification".) Each licensee\r
+    is addressed as "you".</p>\r
+\r
+    <p><a name="scope">Activities</a> other than copying,\r
+    distribution and modification are not covered by this License;\r
+    they are outside its scope. The act of running the Program is\r
+    not restricted, and the output from the Program is covered only\r
+    if its contents constitute a work based on the Program\r
+    (independent of having been made by running the Program).</p>\r
+\r
+    <p><a name="depends">Whether that is true depends on what the\r
+    Program does.</a><br>\r
+    </p>\r
+\r
+    <ol type="1">\r
+      <li>\r
+        <a name="verbatim">You may copy</a> and distribute verbatim\r
+        copies of the Program's source code as you receive it, in\r
+        any medium, provided that you conspicuously and\r
+        appropriately publish on each copy an appropriate copyright\r
+        notice and disclaimer of warranty; keep intact all the\r
+        notices that refer to this License and to the absence of\r
+        any warranty; and give any other recipients of the Program\r
+        a copy of this License along with the Program. \r
+\r
+        <p><a name="fee">You may charge a fee</a> for the physical\r
+        act of transferring a copy, and you may at your option\r
+        offer warranty protection in exchange for a fee.</p>\r
+      </li>\r
+\r
+      <li>\r
+        <a name="modify">You may modify</a> your copy or copies of\r
+        the Program or any portion of it, thus forming a work based\r
+        on the Program, and copy and distribute such modifications\r
+        or work under the terms of Section 1 above, provided that\r
+        you also meet all of these conditions:<br>\r
+         \r
+\r
+        <ol type="a">\r
+          <li><a name="notices">You must cause</a> the modified\r
+          files to carry prominent notices stating that you changed\r
+          the files and the date of any change.</li>\r
+\r
+          <li><a name="nocharge">You must</a> cause any work that\r
+          you distribute or publish, that in whole or in part\r
+          contains or is derived from the Program or any part\r
+          thereof, to be licensed as a whole at no charge to all\r
+          third parties under the terms of this License.</li>\r
+\r
+          <li><a name="interactive">If the modified program</a>\r
+          normally reads commands interactively when run, you must\r
+          cause it, when started running for such interactive use\r
+          in the most ordinary way, to print or display an\r
+          announcement including an appropriate copyright notice\r
+          and a notice that there is no warranty (or else, saying\r
+          that you provide a warranty) and that users may\r
+          redistribute the program under these conditions, and\r
+          telling the user how to view a copy of this License.\r
+          (Exception: if the Program itself is interactive but does\r
+          not normally print such an announcement, your work based\r
+          on the Program is not required to print an\r
+          announcement.)</li>\r
+        </ol>\r
+\r
+        <p><a name="sections">These requirements</a> apply to the\r
+        modified work as a whole. If identifiable sections of that\r
+        work are not derived from the Program, and can be\r
+        reasonably considered independent and separate works in\r
+        themselves, then this License, and its terms, do not apply\r
+        to those sections when you distribute them as separate\r
+        works. But when you distribute the same sections as part of\r
+        a whole which is a work based on the Program, the\r
+        distribution of the whole must be on the terms of this\r
+        License, whose permissions for other licensees extend to\r
+        the entire whole, and thus to each and every part\r
+        regardless of who wrote it.</p>\r
+\r
+        <p><a name="intent">Thus,</a> it is not the intent of this\r
+        section to claim rights or contest your rights to work\r
+        written entirely by you; rather, the intent is to exercise\r
+        the right to control the distribution of derivative or\r
+        collective works based on the Program.</p>\r
+\r
+        <p><a name="aggregation">In addition,</a> mere aggregation\r
+        of another work not based on the Program with the Program\r
+        (or with a work based on the Program) on a volume of a\r
+        storage or distribution medium does not bring the other\r
+        work under the scope of this License.</p>\r
+      </li>\r
+\r
+      <li>\r
+        <a name="exeutable">You may copy</a> and distribute the\r
+        Program (or a work based on it, under Section 2) in object\r
+        code or executable form under the terms of Sections 1 and 2\r
+        above provided that you also do one of the following:<br>\r
+         \r
+\r
+        <ol type="a">\r
+          <li><a name="medium">Accompany it</a> with the complete\r
+          corresponding machine-readable source code, which must be\r
+          distributed under the terms of Sections 1 and 2 above on\r
+          a medium customarily used for software interchange;\r
+          or,</li>\r
+\r
+          <li><a name="written">Accompany it with a written\r
+          offer,</a> valid for at least three years, to give any\r
+          third party, for a charge no more than your cost of\r
+          physically performing source distribution, a complete\r
+          machine-readable copy of the corresponding source code,\r
+          to be distributed under the terms of Sections 1 and 2\r
+          above on a medium customarily used for software\r
+          interchange; or,</li>\r
+\r
+          <li><a name="distrib">Accompany it</a> with the\r
+          information you received as to the offer to distribute\r
+          corresponding source code. (This alternative is allowed\r
+          only for noncommercial distribution and only if you\r
+          received the program in object code or executable form\r
+          with such an offer, in accord with Subsection b\r
+          above.)</li>\r
+        </ol>\r
+\r
+        <p><a name="preferred">The source code</a> for a work means\r
+        the preferred form of the work for making modifications to\r
+        it. For an executable work, complete source code means all\r
+        the source code for all modules it contains, plus any\r
+        associated interface definition files, plus the scripts\r
+        used to control compilation and installation of the\r
+        executable. However, as a special exception, the source\r
+        code distributed need not include anything that is normally\r
+        distributed (in either source or binary form) with the\r
+        major components (compiler, kernel, and so on) of the\r
+        operating system on which the executable runs, unless that\r
+        component itself accompanies the executable.</p>\r
+\r
+        <p><a name="access">If distribution of executable or object\r
+        code is made</a> by offering access to copy from a\r
+        designated place, then offering equivalent access to copy\r
+        the source code from the same place counts as distribution\r
+        of the source code, even though third parties are not\r
+        compelled to copy the source along with the object\r
+        code.</p>\r
+      </li>\r
+\r
+      <li><a name="otherwise">You may not copy,</a> modify,\r
+      sublicense, or distribute the Program except as expressly\r
+      provided under this License. Any attempt otherwise to copy,\r
+      modify, sublicense or distribute the Program is void, and\r
+      will automatically terminate your rights under this License.\r
+      However, parties who have received copies, or rights, from\r
+      you under this License will not have their licenses\r
+      terminated so long as such parties remain in full\r
+      compliance.</li>\r
+\r
+      <li><a name="voluntary">You are not required</a> to accept\r
+      this License, since you have not signed it. However, nothing\r
+      else grants you permission to modify or distribute the\r
+      Program or its derivative works. These actions are prohibited\r
+      by law if you do not accept this License. Therefore, by\r
+      modifying or distributing the Program (or any work based on\r
+      the Program), you indicate your acceptance of this License to\r
+      do so, and all its terms and conditions for copying,\r
+      distributing or modifying the Program or works based on\r
+      it.</li>\r
+\r
+      <li><a name="redistrib">Each time you redistribute</a> the\r
+      Program (or any work based on the Program), the recipient\r
+      automatically receives a license from the original licensor\r
+      to copy, distribute or modify the Program subject to these\r
+      terms and conditions. You may not impose any further\r
+      restrictions on the recipients' exercise of the rights\r
+      granted herein. You are not responsible for enforcing\r
+      compliance by third parties to this License.</li>\r
+\r
+      <li>\r
+        <a name="patent">If, as a consequence of a court\r
+        judgment</a> or allegation of patent infringement or for\r
+        any other reason (not limited to patent issues), conditions\r
+        are imposed on you (whether by court order, agreement or\r
+        otherwise) that contradict the conditions of this License,\r
+        they do not excuse you from the conditions of this License.\r
+        If you cannot distribute so as to satisfy simultaneously\r
+        your obligations under this License and any other pertinent\r
+        obligations, then as a consequence you may not distribute\r
+        the Program at all. For example, if a patent license would\r
+        not permit royalty-free redistribution of the Program by\r
+        all those who receive copies directly or indirectly through\r
+        you, then the only way you could satisfy both it and this\r
+        License would be to refrain entirely from distribution of\r
+        the Program. \r
+\r
+        <p><a name="invalid">If any portion</a> of this section is\r
+        held invalid or unenforceable under any particular\r
+        circumstance, the balance of the section is intended to\r
+        apply and the section as a whole is intended to apply in\r
+        other circumstances.</p>\r
+\r
+        <p><a name="induce">It is not the purpose</a> of this\r
+        section to induce you to infringe any patents or other\r
+        property right claims or to contest validity of any such\r
+        claims; this section has the sole purpose of protecting the\r
+        integrity of the free software distribution system, which\r
+        is implemented by public license practices. Many people\r
+        have made generous contributions to the wide range of\r
+        software distributed through that system in reliance on\r
+        consistent application of that system; it is up to the\r
+        author/donor to decide if he or she is willing to\r
+        distribute software through any other system and a licensee\r
+        cannot impose that choice.</p>\r
+\r
+        <p><a name="clarify">This section</a> is intended to make\r
+        thoroughly clear what is believed to be a consequence of\r
+        the rest of this License.</p>\r
+      </li>\r
+\r
+      <li><a name="geog">If the distribution</a> and/or use of the\r
+      Program is restricted in certain countries either by patents\r
+      or by copyrighted interfaces, the original copyright holder\r
+      who places the Program under this License may add an explicit\r
+      geographical distribution limitation excluding those\r
+      countries, so that distribution is permitted only in or among\r
+      countries not thus excluded. In such case, this License\r
+      incorporates the limitation as if written in the body of this\r
+      License.</li>\r
+\r
+      <li><a name="revise">The Free Software Foundation</a> may\r
+      publish revised and/or new versions of the General Public\r
+      License from time to time. Such new versions will be similar\r
+      in spirit to the present version, but may differ in detail to\r
+      address new problems or concerns. Each version is given a\r
+      distinguishing version number. If the Program specifies a\r
+      version number of this License which applies to it and "any\r
+      later version", you have the option of following the terms\r
+      and conditions either of that version or of any later version\r
+      published by the Free Software Foundation. If the Program\r
+      does not specify a version number of this License, you may\r
+      choose any version ever published by the Free Software\r
+      Foundation.</li>\r
+\r
+      <li>\r
+        <a name="permission">If you wish to incorporate parts</a>\r
+        of the Program into other free programs whose distribution\r
+        conditions are different, write to the author to ask for\r
+        permission. For software which is copyrighted by the Free\r
+        Software Foundation, write to the Free Software Foundation;\r
+        we sometimes make exceptions for this. Our decision will be\r
+        guided by the two goals of preserving the free status of\r
+        all derivatives of our free software and of promoting the\r
+        sharing and reuse of software generally. \r
+\r
+        <p><a name="nowarr">NO WARRANTY</a></p>\r
+      </li>\r
+\r
+      <li><a name="foc">BECAUSE THE PROGRAM IS LICENSED FREE OF\r
+      CHARGE,</a> THERE IS NO WARRANTY FOR THE PROGRAM, TO THE\r
+      EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE\r
+      STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
+      PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,\r
+      EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\r
+      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+      PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND\r
+      PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM\r
+      PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY\r
+      SERVICING, REPAIR OR CORRECTION.</li>\r
+\r
+      <li><a name="liable">IN NO EVENT UNLESS REQUIRED</a> BY\r
+      APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT\r
+      HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE\r
+      THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
+      INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL\r
+      DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\r
+      PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\r
+      BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\r
+      PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
+      PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN\r
+      ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</li>\r
+    </ol>\r
+\r
+    <p>END OF TERMS AND CONDITIONS<br>\r
+    <br>\r
+    </p>\r
+\r
+    <h3><a name="append"><img border="0" width="14" height="14"\r
+    src="fb.gif" alt="*"></a>&nbsp; Appendix: How to Apply These\r
+    Terms to Your New Programs</h3>\r
+\r
+    <p>If you develop a new program, and you want it to be of the\r
+    greatest possible use to the public, the best way to achieve\r
+    this is to make it free software which everyone can\r
+    redistribute and change under these terms.</p>\r
+\r
+    <p><a name="attach">To do so,</a> attach the following notices\r
+    to the program. It is safest to attach them to the start of\r
+    each source file to most effectively convey the exclusion of\r
+    warranty; and each file should have at least the "copyright"\r
+    line and a pointer to where the full notice is found.</p>\r
+\r
+    <blockquote>\r
+      &lt;one line to give the program's name and a brief idea of\r
+      what it does.&gt; Copyright (C) 19yy &lt;name of author&gt; \r
+\r
+      <p><a name="free">This program is free software;</a> you can\r
+      redistribute it and/or modify it under the terms of the GNU\r
+      General Public License as published by the Free Software\r
+      Foundation; either version 2 of the License, or (at your\r
+      option) any later version.</p>\r
+\r
+      <p><a name="merchant">This program</a> is distributed in the\r
+      hope that it will be useful, but WITHOUT ANY WARRANTY;\r
+      without even the implied warranty of MERCHANTABILITY or\r
+      FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\r
+      License for more details.</p>\r
+\r
+      <p><a name="ifnot">You should</a> have received a copy of the\r
+      GNU General Public License along with this program; if not,\r
+      write to the Free Software Foundation, Inc., 675 Mass Ave,\r
+      Cambridge, MA 02139, USA.</p>\r
+    </blockquote>\r
+\r
+    <p><a name="contact">Also add</a> information on how to contact\r
+    you by electronic and paper mail.</p>\r
+\r
+    <p><a name="short">If the program is interactive,</a> make it\r
+    output a short notice like this when it starts in an\r
+    interactive mode:</p>\r
+\r
+    <blockquote>\r
+      Gnomovision version 69, Copyright (C) 19yy name of author\r
+      Gnomovision comes with ABSOLUTELY NO WARRANTY; for details\r
+      type `show w'. This is free software, and you are welcome to\r
+      redistribute it under certain conditions; type `show c' for\r
+      details.\r
+    </blockquote>\r
+\r
+    <p><a name="hypo">The hypothetical</a> commands `show w' and\r
+    `show c' should show the appropriate parts of the General\r
+    Public License. Of course, the commands you use may be called\r
+    something other than `show w' and `show c'; they could even be\r
+    mouse-clicks or menu items--whatever suits your program.</p>\r
+\r
+    <p><a name="disclaimer">You should also get your employer</a>\r
+    (if you work as a programmer) or your school, if any, to sign a\r
+    "copyright disclaimer" for the program, if necessary. Here is a\r
+    sample; alter the names:</p>\r
+\r
+    <blockquote>\r
+      Yoyodyne, Inc., hereby disclaims all copyright interest in\r
+      the program `Gnomovision' (which makes passes at compilers)\r
+      written by James Hacker. &lt;signature of Ty Coon&gt;, 1\r
+      April 1989<br>\r
+       Ty Coon, President of Vice\r
+    </blockquote>\r
+\r
+    <p><a name="library">This General Public License</a> does not\r
+    permit incorporating your program into proprietary programs. If\r
+    your program is a subroutine library, you may consider it more\r
+    useful to permit linking proprietary applications with the\r
+    library. If this is what you want to do, use the GNU Library\r
+    General Public License instead of this License.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" width=\r
+    "250" height="15" src="top.gif" alt=\r
+    "--- Back to Top of Page ---"></a></p>\r
+\r
+    <p class="sans"><a href="http://www.privoxy.org/">\r
+    Website</a> <b class="dot">&middot;</b> <a href="ijbman.html">\r
+    Manual</a> <b class="dot">&middot;</b> <a href="ijbfaq.html">\r
+    FAQ</a> <b class="dot">&middot;</b> <b>GPL</b></p>\r
+\r
+    <p class="sans"><small><small><a href="gpl.html#text">\r
+    Copyright</a> &copy; 1996-8 <a href=\r
+    "http://www.junkbusters.com/">Junkbusters</a> <a href=\r
+    "http://www.junkbusters.com/ht/en/legal.html#marks">&reg;</a>\r
+    Corporation. <a href="gpl.html#text">Copyright</a> &copy; 2001\r
+    <a href="http://sourceforge.net/projects/ijbswa/">Jon\r
+    Foster</a>. Copying and distribution permitted under the <a\r
+    href="gpl.html">GNU</a> General Public License. The text of the\r
+    GNU GPL itself is copyrighted by the FSF, and may be copied but\r
+    not modified.</small></small></p>\r
+\r
+    <p><small><code><a href=\r
+    "http://sourceforge.net/projects/ijbswa/">\r
+    http://sourceforge.net/projects/ijbswa/</a></code></small></p>\r
+  </body>\r
 </html>\r
+\r
diff --git a/doc/ijbfaq.html b/doc/ijbfaq.html
deleted file mode 100644 (file)
index ab7e798..0000000
+++ /dev/null
@@ -1,3186 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<html>\r
-<head>\r
-<!-- Copyright 1996-8 Junkbusters Corporation -->\r
-<!-- This work comes with NO WARRANTY -->\r
-<!-- It may be redistributed and modified under the GNU GPL-->\r
-<!-- See the body of http://www.junkbusters.com/ht/en/gpl.html for details-->\r
-<!-- Junkbusters is a registered trade mark of Junkbusters Corporation -->\r
-<!-- Generated 1998/10/31 03:58:25 UTC -->\r
-<meta name="Generator" content="Junkbusters Ebira $Revision: 1.1 $ $Date: 2001/04/16 21:10:38 $">\r
-<!-- Document  ID: $Revision: 1.1 $ $Date: 2001/04/16 21:10:38 $ -->\r
-<title>\r
-Internet Junkbuster Frequently Asked Questions\r
-</title>\r
-<base href="http://www.junkbusters.com/ht/en/ijbfaq.html">\r
-<meta name="description" content="An extensive FAQ on the Internet Junkbuster, free software to removes banner ads, cookies, and other stuff you don't want from your web browser.">\r
-<meta name="keywords" content="stop, junk, busters, junkbusters, junkbuster, mail, email, e-mail, direct, spam, spamoff, declare, telemarketing, telemarketers, privacy, sharing, names, renting, direct, marketing, database, databases, junk mail, lists, environment, conservation, recycling, catalogs, consumer, sending, opt out , privacy, advertising, direct, marketing, targeting, through, click, trails, http_referer, cookie, cutter, iff, internet fast forward, Cookie Management Tool">\r
-<link rel="next" href="ijbman.html">\r
-<link rel="previous" href="ijb.html">\r
-<link rel="contents" href="toc.html">\r
-</head>\r
-<body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink="#787878">\r
-<center>\r
-<h1><a name="top_of_page">Internet J<small>UNK<i><font color=red>BUSTER</font></i></small> Frequently Asked Questions\r
-</a></h1>\r
-</center>\r
-<font face="arial, helvetica">\r
-<p align="center">\r
-<a href="#u">Download for UNIX</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="ijbwin.html#zip">(Download for Windows 95/NT)</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="ijbdist.html#top_of_page">(Other OS)</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#browser">Configuring Browsers</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#local">Installation</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#companies">For Companies</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#blocking">Blocking</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#cookies">Cookies</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#anonymity">Anonymity</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#security">Security</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="ijbman.html#top_of_page">(Technical Manual)</a>\r
-</p>\r
-</font><br>\r
-<center>\r
-<h2><a name="top"><font face="arial, helvetica">\r
-The Top Ten Questions\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>For a list of the questions on this page (without the answers),\r
-see our\r
-<a href="toc.html#ijbfaq">Table of Contents.</a>\r
-It also contains detailed pointers into our pages\r
-on\r
-<a href="cookies.html">cookies</a>\r
-and on busting \r
-<a href="junkemail.html">junk e-mail,</a>\r
-<a href="junkmail.html">junk mail</a>\r
-and\r
-<a href="telemarketing.html">telemarketing calls.</a>\r
-\r
-<h3><a name="what" href="/cgi-bin/gp?pg=ijbfaq&pr=what"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What is the Internet Junkbuster Proxy and what does it do for me?\r
-</h3>\r
-<p>\r
-The\r
-Internet Junkbuster\r
-Proxy\r
-<a href="legal.html#marks"><small><sup>TM</sup></small></a>\r
-is\r
-<a href="ijbfaq.html#free">free</a>\r
-privacy-enhancing software that can be run on your PC or by your\r
-<small>ISP</small>\r
-or company.\r
-It blocks requests for\r
-<small>URL</small>s\r
-(typically banner ads)\r
-that match its\r
-<a href="ijbfaq.html#blocking">blockfile.</a>\r
-It also deletes unauthorized\r
-<a href="ijbfaq.html#cookies">cookies</a>\r
-and other\r
-unwanted identifying\r
-<a href="ijbfaq.html#anonymity">header information</a>\r
-that is exchanged between web servers and browsers.\r
-These headers are not normally accessible to users\r
-(even though they may contain information that's important to your privacy),\r
-but with the\r
-Internet Junkbuster\r
-you can see almost\r
-<a href="ijbman.html#o_d">anything you want</a>\r
-and control everything you're likely to need.\r
-<b>You</b>\r
-<a href="over.html#you_def">decide what's junk.</a>\r
-<a href="legal.html#marks"><small><sup>SM</sup></small></a>\r
-Many people\r
-<a href="ijbfaq.html#readymade">publish</a>\r
-their blockfiles to help others get started.\r
-</p>\r
-\r
-<h3><a name="free" href="/cgi-bin/gp?pg=ijbfaq&pr=free"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Is there a license fee / warranty / registration form / expiration?\r
-</h3>\r
-<p>\r
-No, none of these.\r
-It's completely free of charge.\r
-Junkbusters\r
-offers you the software to copy, use, modify and distribute\r
-as you wish, forever, at\r
-<a href="over.html#nobucks">no charge</a>\r
-under the\r
-<a href="gpl.html">GNU General Public License.</a>\r
-<p>\r
-<a name="warranty">It comes with</a>\r
-<a href="gpl.html#nowarr">no warranty of any kind.</a>\r
-<p>\r
-<a name="register">You don't have to register,</a>\r
-in fact we don't even provide a way to do so:\r
-the practice of registering software is\r
-usually just an\r
-excuse\r
-to send you solicitations and\r
-<a href="self.html#warranty">sell your name</a>\r
-and information about your behavior.\r
-You are welcome to obtain and use our software as anonymously you wish.\r
-(Your\r
-<small>IP</small>\r
-address will naturally be\r
-<a href="http://www.junkbusters.com/cgi-bin/privacy">disclosed</a>\r
-when you download it,\r
-so if you work for a web ad company\r
-you might want to use a service such as the\r
-<a href="ijbfaq.html#anonymizing">lpwa.com</a>\r
-when you get it.\r
-We\r
-<a href="over.html#nopriv">never</a>\r
-want to be given any information that you consider private or confidential.)\r
-<p>\r
-<a name="why">We are often asked why we give away a product that many</a>\r
-would happily pay for.\r
-The answer is that we are determined to carry out our\r
-<a href="over.html">mission:</a>\r
-to free the world from junk communications.\r
-</p>\r
-\r
-<h3><a name="windows" href="/cgi-bin/gp?pg=ijbfaq&pr=windows"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Does it run on Windows? On a Mac? On the AOL browser?\r
-</h3>\r
-<p>\r
-For the latest information on availability, see the\r
-<a href="ijbdist.html">Distribution Information</a>\r
-page.\r
-We\r
-<a href="ijbdist.html#win3.1">don't</a>\r
-think it will ever run on\r
-Windows 3.1.\r
-But you don't need to have it running on your computer\r
-if you get your\r
-<small>ISP</small>\r
-or Systems Administrator at\r
-<a href="ijbfaq.html#companies">work</a>\r
-to run it.\r
-</p>\r
-\r
-<h3><a name="isp" href="/cgi-bin/gp?pg=ijbfaq&pr=isp"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How can I get my ISP to run the Internet Junkbuster?\r
-</h3>\r
-<p>\r
-Try their sales or support department\r
-(depending on whether you are already a customer).\r
-<a name="unaware">You might send them email including the following</a>\r
-<small>URL</small>:\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>http://www.junkbusters.com/ht/en/ijbfaq.html#isps</kbd></big>\r
-<br>\r
-<a name="switch">You could mention that many</a>\r
-<a href="ijbfaq.html#does">other</a>\r
-<small>ISP</small>s\r
-provide it,\r
-and that you regard it as an important part of your decision on\r
-where to buy Internet service.\r
-</p>\r
-\r
-<h3><a name="who" href="/cgi-bin/gp?pg=ijbfaq&pr=who"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Who chooses the options that control what is blocked?\r
-</h3>\r
-<p>\r
-Whoever starts the\r
-Internet Junkbuster\r
-chooses the options and the blockfile.\r
-If your \r
-<small>ISP</small>\r
-runs it for you, they have to make these decision\r
-(though\r
-<a href="http://www.lunatech.com/proxy/">some</a>\r
-may give you a choice of proxies,\r
-and a way to suggest new\r
-<small>URL</small>s\r
-to block).\r
-If you run it on your computer,\r
-<b>You</b>\r
-<a href="over.html#you_def">decide what's junk.</a>\r
-<a href="legal.html#marks"><small><sup>SM</sup></small></a>\r
-</p>\r
-\r
-<h3><a name="self" href="/cgi-bin/gp?pg=ijbfaq&pr=self"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I download and run the program on my computer?\r
-</h3>\r
-<p>\r
-It depends on your platform.\r
-If you are using Windows 95 or NT,\r
-see our separate page on\r
-<a href="ijbwin.html">installing under Windows.</a>\r
-If you have a C compiler and are using almost any flavor of\r
-<small>UNIX <a href="legal.html#not_our_trademark">&#174;</a></small>\r
-you\r
-<a href="ijbfaq.html#local">download it, compile it, start it running,</a>\r
-and then\r
-<a href="ijbfaq.html#browser">configure your browser.</a>\r
-Several precompiled packages are also available through links in our\r
-<a href="ijbdist.html">distribution page</a>,\r
-which lists all available platforms.\r
-<p>\r
-<a name="port">If you are using a platform for which we have no current</a>\r
-availability,\r
-you are welcome to port the code.\r
-If you do this and you would like us to consider publishing your ported version,\r
-please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=port">tell us.</a>\r
-</p>\r
-\r
-<h3><a name="show" href="/cgi-bin/gp?pg=ijbfaq&pr=show"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How can I tell which blockfile and options are being used?\r
-</h3>\r
-<p>\r
-Just point your browser to\r
-<a href="http://internet.junkbuster.com/cgi-bin/show-proxy-args">http://internet.junkbuster.com/cgi-bin/show-proxy-args</a>\r
-or to any\r
-<small>URL</small>\r
-ending in\r
-<big><kbd>show-proxy-args</kbd></big>\r
-(even if it doesn't exist).\r
-It needn't exist because the\r
-Internet Junkbuster 2.0\r
-intercepts the request, blocks it,\r
-and returns in its place\r
-information about itself.\r
-Using the\r
-<small>URL</small>\r
-above is useful for checking that your browser really is\r
-going through an\r
-Internet Junkbuster,\r
-because the\r
-<big><kbd>junkbuster.com</kbd></big>\r
-server returns a warning if the request actually gets to it.\r
-Some people set the home page of their browser to such a\r
-<small>URL</small>\r
-to be sure that it is configured to use the proxy.\r
-<p>\r
-<a name="headers">If you wish to check the header information</a>\r
-your proxy is actually sending,\r
-a visit to\r
-<a href="http://internet.junkbuster.com/cgi-bin/show-http-headers">http://internet.junkbuster.com/cgi-bin/show-http-headers</a>\r
-will give you the more relevant ones first.\r
-You might also like to turn the proxy\r
-<a href="ijbfaq.html#discontinue">off</a>\r
-and compare the difference. (Don't forget to turn it back on again.)\r
-</p>\r
-\r
-<h3><a name="responding" href="/cgi-bin/gp?pg=ijbfaq&pr=responding"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-My browser started giving me ``server not responding'' messages\r
-</h3>\r
-<p>\r
-Once your browser is told to use a proxy such as the\r
-Internet Junkbuster,\r
-it thinks of it as its server for everything,\r
-so this message means it can't talk to the proxy.\r
-The\r
-Internet Junkbuster\r
-may not be running,\r
-or you may have specified its proxy\r
-<a href="ijbfaq.html#address">address</a>\r
-incorrectly.\r
-Check that the details you entered are correct.\r
-If you have\r
-<big><kbd>telnet</kbd></big>\r
-you can try connecting to the appropriate port to see if the\r
-Internet Junkbuster\r
-is running.\r
-If your\r
-<small>ISP</small>\r
-is running the\r
-Internet Junkbuster,\r
-you may want to check with them.\r
-If you are running it yourself under\r
-<small>UNIX <a href="legal.html#not_our_trademark">&#174;</a></small>,\r
-try looking at a\r
-<big><kbd>ps ax</kbd></big>\r
-to see if it is running.\r
-The\r
-<a href="ijbman.html#o_h">port</a>\r
-specified in its options should be the same one as your\r
-browser has configured.\r
-</p>\r
-\r
-<h3><a name="idea" href="/cgi-bin/gp?pg=ijbfaq&pr=idea"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-I've got this great idea for a new feature. Who do I tell?\r
-</h3>\r
-<p>\r
-We'd be very interested to hear it, but please bear a few things in mind.\r
-<br><ul  type="1">\r
-<li>\r
-<a name="considered">Please check this FAQ to see if we've already considered</a>\r
-the idea,\r
-such as\r
-<a href="ijbfaq.html#size">automatic detection</a>\r
-of banner ads\r
-and\r
-<a href="ijbfaq.html#broken">replacing ads</a>\r
-with something else such as a\r
-transparent\r
-<small>GIF</small>.\r
-<li>\r
-<a name="confidential">Don't tell us anything you want to keep confidential</a>\r
-or retain some right over.\r
-<li>\r
-<a name="wish">We currently have a</a>\r
-long wish list of things that we may or may not do\r
-in the near future, including\r
-a version for your favorite computer and a plug-in version.\r
-<li>\r
-<a name="go4it">If you don't want to wait</a>\r
-you're welcome to improve on our code, publish your version on the Web,\r
-and\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=idea">tell us</a>\r
-where to find it.\r
-Projects that are especially welcome\r
-include\r
-a port to the Mac\r
-and extensions for\r
-<small>HTTP</small>\r
-1.1.\r
-</ul>\r
-</p>\r
-\r
-<h3><a name="other" href="/cgi-bin/gp?pg=ijbfaq&pr=other"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-My question isn't listed here. Who do I ask for support?\r
-</h3>\r
-<p>\r
-<a name="harder">If you find using our free product</a>\r
-harder than you're used to for consumer software,\r
-there are many\r
-<a href="links.html#WebWiper">commercial alternatives</a>\r
-that you could consider.\r
-<p>\r
-<a name="RTM">The answer to detailed technical questions may be answered in</a>\r
-<a href="ijbman.html">manual page</a>,\r
-or in the source code.\r
-Also double-check this page for an answer:\r
-using the ``find'' feature on your browser for likely keywords may help.\r
-Our site also has a\r
-<a href="search.html">search</a>\r
-feature.\r
-<p>\r
-<a name="Use">Many people post requests for help and responses on</a>\r
-<a href="http://search.dejanews.com/dnquery.xp?query=junkbuster&site=excite">Usenet.</a>\r
-<p>\r
-<a name="them">If your</a>\r
-<small>ISP</small>\r
-is providing\r
-the\r
-Internet Junkbuster\r
-for you,\r
-and your question is about how to use it,\r
-check their web page before asking them.\r
-<p>\r
-<a name="us">Even though we don't offer the kind of</a>\r
-support you might expect if you paid a lot of money for a software product,\r
-you can still ask us.\r
-But before you do, please consider whether\r
-you could ask someone closer to you.\r
-And please be patient if we're slow to reply: we\r
-<a href="over.html#nobucks">never charge consumers </a>\r
-for our services,\r
-so we have to subsidize consumers with revenue from companies,\r
-and our resources are limited.\r
-<p>\r
-<a name="quote">If your company or organization</a>\r
-would be interested in a maintenance contract\r
-with phone and email support,\r
-hard copy documentation and source code and pre-compiled binaries on tape\r
-or disk,\r
-please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=quote">ask us</a>\r
-for a quote.\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<br>\r
-<center>\r
-<h2><a name="browser"><font face="arial, helvetica">\r
-Configuring your browser to talk to the Internet Junkbuster\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>\r
-<h3><a name="address" href="/cgi-bin/gp?pg=ijbfaq&pr=address"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What is the proxy address of the Internet Junkbuster?\r
-</h3>\r
-<p>\r
-<a name="localhost">If you set up</a>\r
-the\r
-Internet Junkbuster\r
-to run on the computer you browse from\r
-(rather than your\r
-<small>ISP</small>'s server\r
-or some networked computer at work),\r
-the proxy will be on\r
-<big><kbd>localhost</kbd></big>\r
-(which is the special name used by every computer on the Internet to\r
-refer to itself)\r
-and\r
-the port will be\r
-<big><kbd>8000</kbd></big>\r
-(unless you have told the\r
-Internet Junkbuster\r
-to\r
-run on a different port with the\r
-<a href="ijbman.html#listen-address">listen-address</a>\r
-option).\r
-So you when\r
-<a href="ijbfaq.html#set">configuring your browser's proxy settings</a>\r
-you typically enter the word\r
-<big><kbd>localhost</kbd></big>\r
-in the two boxes next to\r
-<b><font face="arial, helvetica">\r
-HTTP</font></b>\r
-and\r
-<b><font face="arial, helvetica">\r
-Secure</font></b>,\r
-and the number\r
-<big><kbd>8000</kbd></big>\r
-in the two boxes labelled\r
-to the right of those boxes.\r
-<p>\r
-<a name="remote">If your</a>\r
-<small>ISP</small>\r
-or company is running \r
-the\r
-Internet Junkbuster\r
-for you,\r
-they will tell you the address to use.\r
-It will be the name of the computer it's running on\r
-(or possibly its numeric IP address),\r
-plus a port number.\r
-Port 8000 is the default, so assume this number if it is not specified.\r
-Sometimes a colon is used to glue them together,\r
-as in\r
-<big><kbd>junkbuster.fictitous-pro-privacy-isp.net:8000</kbd></big>\r
-but\r
-with most browsers\r
-you do not type the colon,\r
-you enter the address and port number in separate boxes.\r
-</p>\r
-\r
-<h3><a name="set" href="/cgi-bin/gp?pg=ijbfaq&pr=set"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I tell the browser where to find the Internet Junkbuster?\r
-</h3>\r
-<p>\r
-All current browsers can be told the address of a proxy to use.\r
-You enter the same information in two fields in your browser's proxy\r
-configuration screen (see list below): one for\r
-<small>HTTP</small>,\r
-and one for the Secure Protocol (assuming your browser supports\r
-<small>SSL</small>).\r
-If you find some information already entered for your proxy,\r
-see the\r
-<a href="ijbfaq.html#already">next question.</a>\r
-Here are the menus you go through to get to the proxy configuration settings.\r
-(We also recommend that you\r
-<a href="links.html#java">disable Java</a>,\r
-which is a separate operation.)\r
-<strong>Make notes on the changes you make so you know how to undo them!</strong>\r
-You will need to know what you did\r
-in case you wish to\r
-<a href="ijbfaq.html#discontinue">discontinue</a>\r
-using the proxy.\r
-<br><ul  type="1">\r
-<li>\r
-<a name="netscape">For</a>\r
-<a href="http://www.netscape.com/comprod/products/navigator/version_3.0/index.html">Netscape</a>\r
-2.01, 2.02 and 3.0\r
-<a href="/images/pcn30.gif">[Graphic Illustration]:</a>\r
-<b><font face="arial, helvetica">\r
-Options</font></b>;\r
-<b><font face="arial, helvetica">\r
-Network Preferences</font></b>;\r
-<b><font face="arial, helvetica">\r
-Proxies</font></b>;\r
-<b><font face="arial, helvetica">\r
-Manual Proxy Configuration View ;</font></b>\r
-enter\r
-<a href="ijbfaq.html#address">proxy address details</a>\r
-under\r
-<b><font face="arial, helvetica">\r
-HTTP</font></b>\r
-and\r
-<b><font face="arial, helvetica">\r
-Security Proxy</font></b>;\r
-click on\r
-<b><font face="arial, helvetica">\r
-OK</font></b>;\r
-click on the next\r
-<b><font face="arial, helvetica">\r
-OK</font></b>.\r
-<br>\r
-With Netscape 2.0,\r
-follow with\r
-<b><font face="arial, helvetica">\r
-Options</font></b>,\r
-<b><font face="arial, helvetica">\r
-Save Options</font></b>.\r
-<br>\r
-<a name="Netscape4.02">With Netscape 4.X series, you first have to go through</a>\r
-<b><font face="arial, helvetica">\r
-Edit/Preferences</font></b>.\r
-<a href="/images/pcn405.gif">[Graphic Illustration]</a>\r
-Then in the frame on the left,\r
-click on triangle pointing to the right towards the word\r
-<b><font face="arial, helvetica">\r
-Advanced</font></b>;\r
-it will switch to a triangle pointing down;\r
-and the words\r
-<b><font face="arial, helvetica">\r
-Cache</font></b>,\r
-<b><font face="arial, helvetica">\r
-Proxies</font></b>\r
-and\r
-<b><font face="arial, helvetica">\r
-Disk Space</font></b>\r
-appear.\r
-Click on\r
-<b><font face="arial, helvetica">\r
-Proxies</font></b>\r
-and the frame on the right will\r
-display a banner saying\r
-<b><font face="arial, helvetica">\r
-Proxies Configure proxies to access the Internet</font></b>.\r
-Click the radio button labeled\r
-<b><font face="arial, helvetica">\r
-Manual proxy configuration</font></b>\r
-then click the button labeled\r
-<b><font face="arial, helvetica">\r
-View</font></b>;\r
-enter\r
-<a href="ijbfaq.html#address">proxy address details</a>\r
-under\r
-<b><font face="arial, helvetica">\r
-HTTP</font></b>\r
-and\r
-<b><font face="arial, helvetica">\r
-Security Proxy</font></b>;\r
-click on\r
-<b><font face="arial, helvetica">\r
-OK</font></b>;\r
-click on the next\r
-<b><font face="arial, helvetica">\r
-OK</font></b>.\r
-<li>\r
-<a name="explorer3">For</a>\r
-<a href="http://www.microsoft.com/ie/support/docs/tech30/">Internet Explorer 3.0:</a>\r
-<b><font face="arial, helvetica">\r
-View</font></b>;\r
-<b><font face="arial, helvetica">\r
-Options</font></b>;\r
-<b><font face="arial, helvetica">\r
-Connections</font></b>;\r
-tick\r
-<b><font face="arial, helvetica">\r
-Connect through proxy server</font></b>\r
-box;\r
-<b><font face="arial, helvetica">\r
-Settings</font></b>;\r
-enter\r
-<a href="ijbfaq.html#address">proxy address details</a>\r
-<b><font face="arial, helvetica">\r
-HTTP</font></b>\r
-Box, with port number in the second box;\r
-same with\r
-<b><font face="arial, helvetica">\r
-Secure</font></b>;\r
-click on\r
-<b><font face="arial, helvetica">\r
-OK</font></b>.\r
-<li>\r
-<a name="explorer2">For Internet Explorer 2.0: </a>\r
-<b><font face="arial, helvetica">\r
-View</font></b>;\r
-<b><font face="arial, helvetica">\r
-Options</font></b>;\r
-<b><font face="arial, helvetica">\r
-Proxy</font></b>;\r
-enter\r
-<a href="ijbfaq.html#address">proxy address details</a>\r
-click on\r
-<b><font face="arial, helvetica">\r
-OK</font></b>.\r
-<li>\r
-<a name="nt">On NT for MS-IE:</a>\r
-<b><font face="arial, helvetica">\r
-Control Panel</font></b>;\r
-<b><font face="arial, helvetica">\r
-Internet</font></b>;\r
-<b><font face="arial, helvetica">\r
-Advanced</font></b>;\r
-<b><font face="arial, helvetica">\r
-Proxy</font></b>.\r
-<li>\r
-<a name="if">For MS-IE 4.0: seems to be almost the same as for</a>\r
-<a href="ijbfaq.html#explorer3">3.0</a>,\r
-<b><font face="arial, helvetica">\r
-View</font></b>;\r
-<b><font face="arial, helvetica">\r
-Internet Options</font></b>;\r
-<b><font face="arial, helvetica">\r
-Connections</font></b>;\r
-tick\r
-<b><font face="arial, helvetica">\r
-Connect through proxy server</font></b>\r
-box;\r
-<b><font face="arial, helvetica">\r
-Settings</font></b>;\r
-enter\r
-<a href="ijbfaq.html#address">proxy address details</a>\r
-<b><font face="arial, helvetica">\r
-HTTP</font></b>\r
-Box, with port number in the second box;\r
-same with\r
-<b><font face="arial, helvetica">\r
-Secure</font></b>;\r
-click on\r
-<b><font face="arial, helvetica">\r
-OK</font></b>.\r
-Note that 4.0 has\r
-<b><font face="arial, helvetica">\r
-Advanced</font></b>\r
-settings to allow\r
-<small>HTTP</small>\r
-1.1 through proxies;\r
-these must be disabled because the proxy does not currently understand\r
-<small>HTTP</small>\r
-1.1.\r
-Please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=set">tell us</a>\r
-if you see any other differences.\r
-<li>\r
-<a name="mosaic">For NCSA Mosaic for Windows:</a>\r
-<b><font face="arial, helvetica">\r
-Options</font></b>,\r
-<b><font face="arial, helvetica">\r
-Preferences</font></b>,\r
-<b><font face="arial, helvetica">\r
-Proxy</font></b>;\r
-enter\r
-<a href="ijbfaq.html#address">proxy address details</a>\r
-under\r
-<b><font face="arial, helvetica">\r
-HTTP</font></b>.\r
-<li>\r
-<a name="Opera">For</a>\r
-Opera:\r
-<b><font face="arial, helvetica">\r
-Preferences</font></b>,\r
-<b><font face="arial, helvetica">\r
-Proxy servers</font></b>;\r
-check the box next to HTTP;\r
-enter the server and port number in the box on the other side;\r
-click on\r
-<b><font face="arial, helvetica">\r
-OK</font></b>.\r
-<li>\r
-<a name="lynx">For</a>\r
-<a href="http://www.yahoo.com/Computers_and_Internet/Software/Internet/World_Wide_Web/Browsers/Lynx">Lynx,</a>\r
-<a href="http://www.yahoo.com/Computers_and_Internet/Software/Internet/World_Wide_Web/Browsers/Mosaic/">Mosaic/X,</a>\r
-<a name ="grail" href="http://monty.cnri.reston.va.us/grail-0.3/">Grail,</a>\r
-and\r
-W3O\r
-<a href="http://www.w3.org/pub/WWW/Arena/">Arena,</a>\r
-you can specify the proxy via environment variables\r
-before starting the application.\r
-This will probably be done with something like either\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>setenv http_proxy http://localhost:8000/</kbd></big>\r
-<br>\r
-or\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>http_proxy=http://junkbuster.fictitous-pro-privacy-isp.net:8000/ export http_proxy</kbd></big>\r
-<br>\r
-depending on your shell and where the\r
-Internet Junkbuster\r
-lives.\r
-</ul>\r
-If your browser is not listed here,\r
-or if you notice an error, please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=set">tell us</a>\r
-the correct procedure.\r
-</p>\r
-\r
-<h3><a name="already" href="/cgi-bin/gp?pg=ijbfaq&pr=already"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What should I do if I find another proxy is already configured?\r
-</h3>\r
-<p>\r
-Some\r
-<small>ISP</small>s\r
-and companies require all Web traffic to go through their proxy.\r
-In this case you would find your proxy configuration with values already set,\r
-possibly under\r
-<a name="Automatic">Automatic Proxy Configuration</a>\r
-(in the case of \r
-<a href="http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html">Netscape</a>\r
-and\r
-<a href="http://ieak.microsoft.com/">MS-IE 3.0</a>\r
-and above).\r
-It's probably a firewall proxy between your company and the outside world,\r
-<a name="cache">or a</a>\r
-<a href="http://vancouver-webpages.com/CacheNow/">caching proxy</a>\r
-if you're using an \r
-<small>ISP</small>.\r
-<p>\r
-<a name="f">What needs to be done in this case is to</a>\r
-use the\r
-<a href="ijbman.html#forwardfile">forwardfile</a>\r
-option\r
-to tell the\r
-Internet Junkbuster\r
-the address of the other proxy.\r
-Specify a different (unused) port number\r
-with the\r
-<a href="ijbman.html#listen-address">listen-address</a>\r
-option,\r
-and configure your browser to\r
-<a href="ijbfaq.html#chain">use that port.</a>\r
-If you haven't done this kind of thing before,\r
-it's probably best to consult your systems administrator or \r
-<small>ISP</small>\r
-about it;\r
-check their web page first.\r
-</p>\r
-\r
-<h3><a name="discontinue" href="/cgi-bin/gp?pg=ijbfaq&pr=discontinue"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What if I want to stop using the Internet Junkbuster?\r
-</h3>\r
-<p>\r
-Just go through the same procedure you used to start your\r
-browser using the\r
-Internet Junkbuster,\r
-but remove the details you put in\r
-(or if there was something there before, restore it).\r
-You may need to use\r
-<b><font face="arial, helvetica">\r
-Save Options</font></b>\r
-to make this change permanent.\r
-On Netscape 3.0 you can go through\r
-<b><font face="arial, helvetica">\r
-Options</font></b>;\r
-<b><font face="arial, helvetica">\r
-Network Preferences</font></b>;\r
-<b><font face="arial, helvetica">\r
-Proxies</font></b>\r
-and click on\r
-<b><font face="arial, helvetica">\r
-No Proxy</font></b>\r
-to turn it off, and later click on\r
-<b><font face="arial, helvetica">\r
-Manual Proxy Configuration</font></b>\r
-if you want to start using it again.\r
-(No need to enter the again details under\r
-<b><font face="arial, helvetica">\r
-View</font></b>\r
-as you did the\r
-<a href="ijbfaq.html#netscape">first time;</a>\r
-they should remain there unchanged.)\r
-<p>\r
-<a name="shut">This stops your browser talking to the proxy;</a>\r
-<a href="ijbfaq.html#shutdown">shutting down the proxy</a>\r
-is a different matter.\r
-</p>\r
-\r
-<h3><a name="dial" href="/cgi-bin/gp?pg=ijbfaq&pr=dial"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Automatic dialing isn't working any more. How do I fix it?\r
-</h3>\r
-<p>\r
-Some browsers (such as MSIE-4) can be configured to dial your\r
-<small>ISP</small>\r
-automatically when you click on a link,\r
-but this feature gets disabled if you specify a proxy running on your\r
-own computer\r
-(with address\r
-<big><kbd>localhost</kbd></big>\r
-or\r
-<big><kbd>127.0.0.1</kbd></big>)\r
-because these addresses don't require dialing.\r
-The\r
-Internet Junkbuster\r
-knows nothing about dialing, so it doesn't work.\r
-To make automatic dialing work,\r
-make up a name such as\r
-<big><kbd>junkbuster.ijb</kbd></big>\r
-and use that name in the proxy settings\r
-instead of\r
-<big><kbd>localhost</kbd></big>,\r
-and then add the line\r
-<big><kbd>127.0.0.1 junkbuster.ijb</kbd></big>\r
-to the file\r
-<big><kbd>c:\windows\hosts</kbd></big>\r
-(if there already is a line beginning with\r
-<big><kbd>127.0.0.1</kbd></big>\r
-just add\r
-<big><kbd>junkbuster.ijb</kbd></big>\r
-at the end of it.)\r
-<p>\r
-<a name="also">This should also work Netscape Communicator 4 on</a>\r
-machines where IE-4 has been installed.\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<br>\r
-<center>\r
-<h2><a name="local"><font face="arial, helvetica">\r
-Setting up the Internet Junkbuster on your local computer\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>The next two sections assume you wish to compile the code\r
-with your own C compiler.\r
-<a name="install">If you just want to use the</a>\r
-<big><kbd>.exe</kbd></big>\r
-file provided for Windows,\r
-see the\r
-<a href="ijbwin.html">Windows Installation page.</a>\r
-\r
-<h3><a name="u" href="/cgi-bin/gp?pg=ijbfaq&pr=u"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I compile the code under Unix?\r
-</h3>\r
-<p>\r
-If you are running Redhat\r
-<a href="aboutus.html#linux">Linux</a>\r
-you may prefer to use the\r
-<a href="ijbdist.html#red">rpm</a>\r
-instead of the following procedure.\r
-<br><ol  type="1">\r
-<li>\r
-<a name="download">First</a>\r
-<a href="ijb20.tar.Z">download the tar file</a>\r
-(~286k)\r
-<a name="tar">and</a>\r
-uncompress and extract the files from it with this command\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>uncompress -c ijb20.tar.Z | tar xf -</kbd></big>\r
-<p>\r
-<li>\r
-<a name="sun">If your operating system is from</a>\r
-<a href="legal.html#not_our_trademark">Sun</a>\r
-or\r
-<a href="legal.html#not_our_trademark">HP</a>\r
-examine the\r
-<big><kbd>Makefile</kbd></big>\r
-and make any changes indicated inside.\r
-<li>\r
-<a name="make">Run</a>\r
-<br>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>make</kbd></big>\r
-<p>\r
-<li>\r
-<a name="defaults">Copy the sample configuration file</a>\r
-(<big><kbd>junkbstr.ini</kbd></big>,\r
-previously called\r
-<big><kbd>sconfig.txt</kbd></big>\r
-and other names in earlier releases)\r
-to some convenient place such as\r
-<big><kbd>/usr/local/lib/junkbuster/configfile</kbd></big>\r
-or whatever you choose.\r
-The sample file has all the options commented out.\r
-You can remove the\r
-<big><kbd>#</kbd></big>\r
-character on any that you want, but it may be better to\r
-leave this until to later.\r
-Run it asynchronously:\r
-<br>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>junkbuster configfile &</kbd></big>\r
-<p>\r
-If you are running a version earlier than 2.0 you can start it with\r
-<big><kbd>junkbuster &</kbd></big>\r
-<p>\r
-<li>\r
-<a name="config">Configure your browser (described</a>\r
-<a href="ijbfaq.html#browser">above).</a>\r
-<li>\r
-<a name="test">Verify that the</a>\r
-Internet Junkbuster\r
-is working (described\r
-<a href="ijbfaq.html#show">above).</a>\r
-<li>\r
-<a name="restart">Decide on the options you really want,</a>\r
-<big><kbd>kill</kbd></big>\r
-the\r
-<a href="ijbfaq.html#pid">process</a>\r
-and start it again. The most popular option is\r
-<a href="ijbman.html#blockfile">blockfile</a>\r
-to block ads.\r
-<a name="comprehensive">A sample blockfile is provided as an illustration,</a>\r
-but it doesn't really stop many ads.\r
-More comprehensive ones are available\r
-<a href="ijbfaq.html#readymade">elsewhere</a>.\r
-<li>\r
-<a name="rc">You'll probably want to add an entry to</a>\r
-<big><kbd>/etc/rc.d/rc.local</kbd></big>\r
-or equivalent to start it at boot time.\r
-(Any output you specify should be redirected to a file.\r
-And don't forget the\r
-&amp;\r
-at the end to run it asynchronously or your system will seize\r
-up after the next reboot.)\r
-</ol>\r
-</p>\r
-\r
-<h3><a name="win" href="/cgi-bin/gp?pg=ijbfaq&pr=win"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I compile the code under Windows?\r
-</h3>\r
-<p>\r
-A binary is currently being supplied with the source code,\r
-but if you prefer to compile it yourself here is the likely procedure.\r
-Most of these steps are repeated in our checklist for\r
-<a href="ijbwin.html">installation under Windows.</a>\r
-<br><ol  type="1">\r
-<li>\r
-<a name="zip">First</a>\r
-<a href="ijb20.zip">click here to download the zip file</a>\r
-called\r
-<big><kbd>ijb20.zip</kbd></big>\r
-(~208k),\r
-then uncompress and unpack the zip archive using a tool like\r
-<a href="http://www.winzip.com/">WinZip</a>.\r
-<li>\r
-<a name="change">Now the distribution (source and sample files)</a>\r
-will be in a folder\r
-called\r
-<big><kbd>ijb20</kbd></big>.\r
-Go into that folder and then edit the Makefile for\r
-your system,\r
-removing the comment character\r
-(<big><kbd>#</kbd></big>)\r
-in the lines related to Win32.\r
-Then type:\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>nmake</kbd></big>\r
-<br>\r
-This should create an executable called\r
-<big><kbd>junkbstr.exe</kbd></big>.\r
-<a name="compilers">For information on issues with various compilers, see the</a>\r
-<a href="ijbdist.html#compilers">Distribution Information</a>\r
-page.\r
-<li>\r
-<a name="attempt">Run the executable with the command:</a>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>junkbstr</kbd></big>\r
-<br>\r
-The program will produce a message\r
-indicating that it has started and is ready to serve.\r
-<p>\r
-<a name="ini">(Version 2.0.1 and above uses</a>\r
-the file\r
-<big><kbd>junkbstr.ini</kbd></big>\r
-as the config file\r
-if it exists and no argument was given. If you have an earlier\r
-version or if you want it to use a different config file,\r
-simply specify that file as the argument.)\r
-<li>\r
-<a name="configures">Configure your browser (described</a>\r
-<a href="ijbfaq.html#browser">above).</a>\r
-<li>\r
-<a name="work">Check the proxy is working (described</a>\r
-<a href="ijbfaq.html#check">below</a>).\r
-<li>\r
-<a name="shortcut">To have the proxy start itself automatically</a>\r
-when you login to Win95,\r
-drop the ``shortcut'' to the\r
-<big><kbd>junkbstr</kbd></big>\r
-executable into the StartUp folder:\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>C:\Windows\Start Menu\Programs\StartUp</kbd></big>\r
-<br>\r
-You might want to change the shortcut's\r
-<big><kbd>Properties-&gt;Shortcut</kbd></big>\r
-to\r
-<big><kbd>Run: Minimized</kbd></big>.\r
-If you specify the\r
-<a href="ijbman.html#hide-console">hide-console</a>\r
-option then the\r
-<small>DOS</small>\r
-window will vanish after it starts.\r
-<p>\r
-<a name="NT">WinNT users can put it into their own</a>\r
-StartUp folders or the Administrator\r
-can put it into the system's global StartUp folder.\r
-For details on how to make this a service under NT\r
-see our\r
-<a href="ijbwin.html#service">Windows page</a>.\r
-</ol>\r
-</p>\r
-\r
-<h3><a name="check" href="/cgi-bin/gp?pg=ijbfaq&pr=check"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I check that the proxy is working?\r
-</h3>\r
-<p>\r
-Pick a page from somewhere (such as your bookmarks, or just one\r
-that your browser was pointing to)\r
-and\r
-<b><font face="arial, helvetica">\r
-Reload</font></b>\r
-it.\r
-If you get a message along the lines of ``server not responding,\r
-using cached copy instead,'' see the advice\r
-<a href="ijbfaq.html#responding">above.</a>\r
-If the page reloads OK, check that your browser is actually\r
-talking to the proxy by going to\r
-<a href="http://internet.junkbuster.com/cgi-bin/show-proxy-args">http://internet.junkbuster.com/cgi-bin/show-proxy-args</a>\r
-or any\r
-<small>URL</small>\r
-ending in\r
-<big><kbd>show-proxy-args</kbd></big>\r
-(as described\r
-<a href="ijbfaq.html#show">below</a>,\r
-the proxy should intercept the request.)\r
-When you see ``Internet Junkbuster Proxy Status,''\r
-you'll know it's working.\r
-</p>\r
-\r
-<h3><a name="chain" href="/cgi-bin/gp?pg=ijbfaq&pr=chain"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How and why would I have this proxy chained with other proxies?\r
-</h3>\r
-<p>\r
-You may need the \r
-<a href="ijbman.html#forwardfile">forwarding</a>\r
-feature to ``daisy chain'' the\r
-Internet Junkbuster\r
-to another proxy, perhaps an\r
-<a href="ijbfaq.html#anonymizing">anonymizing</a>\r
-proxy to\r
-<a href="ijbfaq.html#conceal">conceal</a>\r
-your\r
-<small>IP</small>\r
-address,\r
-or a\r
-<a href="ijbfaq.html#cache">caching proxy</a>\r
-from your\r
-<small>ISP</small>,\r
-or a\r
-<a href="ijbfaq.html#firewall">firewall</a>\r
-proxy between your company and the outside world.\r
-Version 2.0\r
-can be even configured to forward\r
-<a href="ijbman.html#forwardfile">selectively</a>\r
-according to the\r
-<small>URL</small>\r
-requested:\r
-for example, connecting directly to trusted hosts,\r
-but going through an anonymizing or firewall proxy for all other hosts.\r
-<p>\r
-<a name="administrator">Network administrators might use it to provide</a>\r
-transparent access to multiple networks without\r
-modifying browser configurations.\r
-<a name="direct">Most browsers also provide a way of</a>\r
-specifying hosts that the browser\r
-connects to directly, bypassing the proxy. Some provide a method for\r
-<a href="ijbfaq.html#Automatic">Automatic Proxy Configuration.</a>\r
-A well written\r
-Internet Junkbuster\r
-configuration can be much more flexible and powerful.\r
-<p>\r
-<a name="example">An</a>\r
-<small>ISP</small>'s\r
-caching proxy\r
-would typically be called something like\r
-<big><kbd>cache.your-isp.net:8080</kbd></big>\r
-(as described on you\r
-<small>ISP</small>'s\r
-web page);\r
-you would put this information in your\r
-<a href="ijbman.html#forwardfile">forwardfile</a>\r
-as described in our manual.\r
-Your browser would be configured to\r
-the\r
-Internet Junkbuster\r
-for\r
-<small>HTTP</small>\r
-and Security Proxies as before,\r
-but you probably want to tell it to use the caching proxy\r
-for\r
-<small>FTP</small>\r
-and other protocols.\r
-<a name="nonlocal">If your</a>\r
-<small>ISP</small>\r
-is running\r
-the\r
-Internet Junkbuster\r
-for you,\r
-they have probably already decided whether to chain with a caching proxy.\r
-</p>\r
-\r
-<h3><a name="socks" href="/cgi-bin/gp?pg=ijbfaq&pr=socks"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How does the Internet Junkbuster work with SOCKS gateways?\r
-</h3>\r
-<p>\r
-There is support for some\r
-<a href="http://www.leverage.com/users/tlod/ssockd/ssockd.html">gateways</a>\r
-in\r
-Version <a href="ijbdist.html#c4">1.4</a>\r
-and above.\r
-The gateway protocol used to be specified on the command line;\r
-it is\r
-now specified\r
-in the same file as\r
-<a href="ijbman.html#forwardfile">forwarding.</a>\r
-Note that the browser's proxy configuration must\r
-<em>not</em>\r
-specify a\r
-<big><kbd>SOCKS</kbd></big>\r
-host;\r
-it should specify the proxy as described\r
-<a href="ijbfaq.html#set">above.</a>\r
-</p>\r
-\r
-<h3><a name="plain" href="/cgi-bin/gp?pg=ijbfaq&pr=plain"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I configure it to be just a plain old proxy?\r
-</h3>\r
-<p>\r
-To get the proxy to do as little as possible (which means not deleting any\r
-sensitive headers), place in your\r
-configuration file the following three lines (each ending in a space\r
-then a period) to stop it changing sensitive headers:\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>referer .</kbd></big>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>from .</kbd></big>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>user-agent .</kbd></big>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>cookiefile mycookiefile</kbd></big>\r
-<br>\r
-The fourth line is also needed to specify a\r
-<a href="ijbman.html#o_c">cookiefile</a>\r
-that might be called\r
-<big><kbd>mycookiefile</kbd></big>\r
-containing a single line with a\r
-<big><kbd>*</kbd></big>\r
-character, to allow all cookies through.\r
-</p>\r
-\r
-<h3><a name="shutdown" href="/cgi-bin/gp?pg=ijbfaq&pr=shutdown"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I shut down the proxy (to restart it)?\r
-</h3>\r
-<p>\r
-It depends on your platform. Under Windows, use\r
-<b><font face="arial, helvetica">\r
-Ctrl-Break</font></b>\r
-in the \r
-<small>DOS</small>\r
-window or\r
-the old three-fingered salute of\r
-<b><font face="arial, helvetica">\r
-Ctrl-Alt-Delete</font></b>\r
-and select\r
-<b><font face="arial, helvetica">\r
-End Task</font></b>.\r
-Under\r
-<small>UNIX <a href="legal.html#not_our_trademark">&#174;</a></small>\r
-you'll need to\r
-<big><kbd>kill</kbd></big>\r
-the\r
-<b><kbd>junkbuster</kbd></b>\r
-process.\r
-<a name="pid">If you don't know the process number to give to</a>\r
-<big><kbd>kill</kbd></big>, try this:\r
-<big><kbd>ps ax | grep junkbuster</kbd></big>\r
-<br>\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<br>\r
-<center>\r
-<h2><a name="companies"><font face="arial, helvetica">\r
-Information for companies\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>\r
-<h3><a name="think" href="/cgi-bin/gp?pg=ijbfaq&pr=think"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What do advertising companies think of this kind of technology?\r
-</h3>\r
-<p>\r
-We've seen only a few public comments from the advertising industry on this,\r
-other than\r
-<a href="links.html#adverse">SEC filings.</a>\r
-First, the president of the Internet Advertising Bureau told\r
-<a href="new.html#Rich">CNET</a>\r
-that he wasn't worried by banner blockers.\r
-Second, after the Federal Trade Commission's\r
-<a href="ftc.html">workshop</a>\r
-where we gave a live demonstration of our proxy before\r
-many eminent representatives of the industry,\r
-the\r
-<a href="self.html#dma">Direct Marketing Association</a>\r
-made the following\r
-statement in the closing paragraphs\r
-of their\r
-<a href="http://www.ftc.gov/bcp/privacy/wkshp97/comments2/dma027a.htm">summary comments</a>\r
-to the Commission.\r
-<blockquote>\r
-Clever shareware developers have come up with products that\r
-can obliterate cookies and advertisements for those consumers\r
-who have these concerns.\r
-The Internet is a market that is so democratic and flexible\r
-that it is easy for companies and software\r
-developers to respond to a perceived market need. \r
-</blockquote>\r
-Their attitude seems to be that they would prefer that\r
-people use technical solutions\r
-to protect their privacy than have protections\r
-imposed by legislation or government regulations.\r
-So, do you perceive a market need?\r
-Then here are some ways to flex your democratic muscles.\r
-</p>\r
-\r
-<h3><a name="nobrainer" href="/cgi-bin/gp?pg=ijbfaq&pr=nobrainer"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Should we provide the Internet Junkbuster for our employees?\r
-</h3>\r
-<p>\r
-That depends. Try this quick three-point test.\r
-<br><ol  type="1">\r
-<li>\r
-<a name="waste">Do you want to spend your communications budget</a>\r
-on bandwidth that wastes your employees' time by forcing them to wait\r
-for a lot of annoying distractions while they're trying to\r
-do their jobs?\r
-<li>\r
-<a name="surveillance">Do you want current and potential vendors</a>\r
-to know quantitative details about the\r
-<a href="ijbfaq.html#agent">software and hardware platforms</a>\r
-that you have?\r
-<li>\r
-<a name="intelligence">Do you want your competitors to be able to</a>\r
-<a href="cookies.html">track</a>\r
-exactly which of your\r
-employees are checking out their web sites?\r
-</ol>\r
-If the answer to all three questions is yes,\r
-then you probably don't have any need for this kind of product.\r
-</p>\r
-\r
-<h3><a name="commercial" href="/cgi-bin/gp?pg=ijbfaq&pr=commercial"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Can our company get commercial support for the software?\r
-</h3>\r
-<p>\r
-Yes,\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=commercial">ask us</a>\r
-for a quote on a maintenance contract with your choice of\r
-phone and email support,\r
-hard copy documentation,\r
-source code and pre-compiled binaries on tape or disk,\r
-and email alerting of upgrades and issues.\r
-We also offer consulting services to help set up ``stealth browsing''\r
-capabilities to help reduce the footprints left while doing competitive\r
-analysis and other Web work where confidentiality is critical.\r
-</p>\r
-\r
-<h3><a name="isps" href="/cgi-bin/gp?pg=ijbfaq&pr=isps"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-I run an ISP. What issues should I consider before offering it?\r
-</h3>\r
-<p>\r
-Many\r
-<small>ISP</small>s\r
-who offer the proxy to their customers have told us that\r
-most of their customers are \r
-delighted with it\r
-(although one reported that a customer complaint that without banner ads,\r
-surfing was like reading a novel: we recommend making it optional).\r
-Many\r
-<small>ISP</small>s\r
-like it because it reduces bandwidth requirements.\r
-To help get you started,\r
-here's a checklist we've developed from working with a few\r
-<small>ISP</small>s.\r
-You may think of more,\r
-and we'd be interested if you're willing to\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=isps">share them</a>\r
-with us.\r
-<br><ol  type="1">\r
-<li>\r
-<a name="pending">If you get more than one request for</a>\r
-the\r
-Internet Junkbuster\r
-you may want to tell your customers on your News page that you\r
-<a href="ijbfaq.html#isp">already</a>\r
-know about it and are assessing it.\r
-<li>\r
-<a name="try">Try the software and</a>\r
-<a href="ijbfaq.html#install">verify</a>\r
-that it performs satisfactorily.\r
-<li>\r
-<a name="value">Determine whether your customers perceive the service as</a>\r
-<a href="ijbfaq.html#switch">valuable</a>\r
-(and therefore worth the time to set up).\r
-We've had reports of many delighted customers.\r
-<li>\r
-<a name="secure">Assess the</a>\r
-level of\r
-<a href="ijbfaq.html#others">security</a>\r
-associated with the software.\r
-If access is to be\r
-<a href="ijbfaq.html#restrict">restricted</a>\r
-(to just dial-in ports, for example)\r
-how is this to be done?\r
-<li>\r
-<a name="costs">Consider</a>\r
-whether to expect any additional load on computing resources required,\r
-and any change in use of bandwidth due to the blocking of large\r
-<small>GIF</small>s.\r
-<li>\r
-<a name="opt">Choose the</a>\r
-<a href="ijbman.html">options</a>\r
-you wish to provide.\r
-<li>\r
-<a name="multiple">Decide whether you want</a>\r
-to offer a choice of configurations, such some of these four.\r
-<br><ol  type="A">\r
-<li>\r
-<a name="banner">Banners</a>\r
-<a href="ijbfaq.html#blocking">Blocked,</a>\r
-Wafer with\r
-<a href="ijbfaq.html#notice">No-Cookie-Copyright</a>\r
-notice\r
-<li>\r
-<a name="low">Cookies</a>\r
-not stopped\r
-(<a href="ijbman.html#cookiefile">cookiefile</a>\r
-with just a\r
-<big><kbd>*</kbd></big>\r
-in it),\r
-<a href="ijbfaq.html#header">User Agent</a>\r
-specified as\r
-<a href="ijbfaq.html#lynx">Lynx</a>\r
-<li>\r
-<a name="oneway">Cookies from browser</a>\r
-<a href="ijbfaq.html#one">allowed</a>,\r
-permitting\r
-<a href="ijbfaq.html#registration">registered services</a>\r
-<li>\r
-<a name="kid">A proxy for</a>\r
-<a href="ijbfaq.html#children">kids.</a>\r
-</ol>\r
-<a name="caching">If you run a</a>\r
-<a href="ijbfaq.html#chain">caching proxy,</a>\r
-decide whether the \r
-Internet Junkbuster\r
-will chain with it by default,\r
-and whether to offer an alternate with no caching.\r
-(Some\r
-<small>ISP</small>s\r
-don't, because they want to give customers an incentive to use caching\r
-and save bandwidth.)\r
-<li>\r
-<a name="naming">Decide on a naming scheme for your</a>\r
-proxies.\r
-If you're running only one\r
-proxy on one machine,\r
-the simplest way is to just use port 8000 on your main machine,\r
-such as\r
-<big><kbd>our-isp.net.</kbd></big>\r
-But it would probably be safer to put an entry in your name server\r
-and call it something like\r
-<big><kbd>junkbuster.our-isp.net.</kbd></big>\r
-If running several proxies, you could either use different ports\r
-on the same machine, or if you have\r
-the opportunity to distribute the load over\r
-a few machines \r
-you could\r
-use different hostname aliases such as\r
-<big><kbd>banner.junkbuster.our-isp.net</kbd></big>,\r
-<big><kbd>lynx.junkbuster.our-isp.net</kbd></big>\r
-and\r
-<big><kbd>oneway.junkbuster.our-isp.net</kbd></big>\r
-(corresponding to the examples in the previous point).\r
-You may want to set up\r
-<a href="ijbfaq.html#Automatic">Automatic Proxy Configuration.</a>\r
-<li>\r
-<a name="document">Prepare a page</a>\r
-explaining the\r
-Internet Junkbuster\r
-to your customers.\r
-<a name="does">Here's are some examples from</a>\r
-<a href="http://www.cia.com.au/us/help/faq-proxy.html">Australia</a>,\r
-<a href="http://www.rhein-ruhr.de/info/junkbuster.html">Germany</a>,\r
-<a href="http://www.packet.net/ijb/">Florida</a>,\r
-<a href="http://www.eclipse.net/adfilter/index.html">New York/New Jersey/Pennsylvania,</a>\r
-<a href="http://a-o.com/proxy/proxy.html">North Carolina</a>,\r
-<a href="http://www.trip.net/junkbuster/">Texas</a>,\r
-and\r
-<a href="http://www.inconnect.com/proxy.html">Utah</a>.\r
-<a name="reuse">You are welcome to copy and modify</a>\r
-material\r
-from\r
-Junkbusters\r
-according to the\r
-<a href="gpl.html">GPL</a>.\r
-You might want to set up a process to check this page periodically\r
-and update it when it changes.\r
-(A few links can probably serve as well as lot of copying however.)\r
-A typical page would probably specify the following.\r
-<br><ul  type="1">\r
-<li>\r
-<a name="abstract">A brief explanation stating what</a>\r
-the\r
-Internet Junkbuster\r
-does, with a link to this page.\r
-<li>\r
-<a name="addresses">The addresses of the proxy or proxies,</a>\r
-with their port number(s).\r
-<li>\r
-<a name="options">The options used,</a>\r
-and how to view the contents of the blockfile (which you can place on\r
-your web pages,\r
-preferably in a file called\r
-<big><kbd>blocklist.html</kbd></big>\r
-or\r
-<big><kbd>blocklist.txt</kbd></big>).\r
-<li>\r
-<a name="additions">An indication</a>\r
-of whether suggestions for the blocklist are considered,\r
-and if so, how to submit them: to a particular email address,\r
-via web-based form, etc.\r
-<li>\r
-<a name="configuration">Instructions</a>\r
-on how to\r
-configure a browser.\r
-You may want to include details for only the two major browsers\r
-and leave the others to a link.\r
-<li>\r
-<a name="service">Procedures on how to report problems, give feedback etc.</a>\r
-</ul>\r
-<li>\r
-<a name="beta">Invite a small number of technologically sophisticated</a>\r
-customers to beta-test the service.\r
-<li>\r
-<a name="announce">Announce general availability on your ``News'' page.</a>\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=isps">Tell us</a>\r
-if you would like to be included on a list of\r
-<small>ISP</small>s\r
-offering the\r
-Internet Junkbuster.\r
-</ol>\r
-</p>\r
-\r
-<h3><a name="ps2" href="/cgi-bin/gp?pg=ijbfaq&pr=ps2"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What's a Proxy Server Server and how can I make money as one?\r
-</h3>\r
-<p>\r
-Other organizations with web presence and some bandwidth to spare\r
-can set up as\r
-<i><dfn>Proxy Server Servers</dfn></i>\r
-<!-- Aside: All this, and... -->\r
-(<small>PS<sup>2</sup></small>s).\r
-The idea here is to allow users to choose their proxy configuration,\r
-and provide it to them on a semi-permanent basis.\r
-Users would fill in a form specifying what options they want in\r
-their proxy,\r
-possibly even at a very high level, such as\r
-``no ads''\r
-or ``no nudity.''\r
-This information is sent to a\r
-<small>CGI</small>\r
-script that\r
-configures a proxy, starts it running, and returns its address and port number\r
-(possibly along with configuration instructions for the browser\r
-that the user specified.)\r
-<p>\r
-<a name="revenue">Users</a>\r
-could be charged\r
-a subscription fee,\r
-or the service could be thrown in free in the hope of\r
-improving customer retention for some existing business\r
-(which is what\r
-<small>ISP</small>s\r
-are doing).\r
-It might be possible to make money by\r
-inserting new ads in the holes left where others were blocked,\r
-but the original owners might object.\r
-<small>PS<sup>2</sup></small>s\r
-could differentiate themselves\r
-by providing frequently updated and comprehensive\r
-blocking of ads, or of offensive material based on their own grading system.\r
-Some content providers might do it for the chance to be the\r
-only company that the consumer permits to set cookies.\r
-(Identification could even be done via cookies,\r
-but this might not be popular with the kind of user who wants a proxy.)\r
-<small>PS<sup>2</sup></small>s\r
-might sell specific or aggregate information about their\r
-users' browsing habits,\r
-so the agreement with users on whether they are permitted to do this\r
-would be important to both sides.\r
-<p>\r
-<a name="publicize">If your organization</a>\r
-establishes a \r
-Proxy Server Service\r
-you would like publicized,\r
-please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=publicize">notify us.</a>\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<br>\r
-<center>\r
-<h2><a name="blocking"><font face="arial, helvetica">\r
-Blocking\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>\r
-<h3><a name="readymade" href="/cgi-bin/gp?pg=ijbfaq&pr=readymade"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Where can I get an example blockfile that stops most ads?\r
-</h3>\r
-<p>\r
-The sample blockfile we provide blocks almost nothing,\r
-and we do not publish blockfiles that stop almost all banner ads.\r
-But others have; you can find them by\r
-<a href="http://www.altavista.com/cgi-bin/query?pg=q&what=web&fmt=.&q=%2Bjunkbuster+%2Burl%3Ablocklist">asking Altavista.</a>\r
-You can add any part of the new file to your old one\r
-(probably called\r
-<big><kbd>sblock.ini</kbd></big>\r
-if you haven't changed the default name in the latest version)\r
-or your just replace it completely.\r
-You\r
-<a href="ijbfaq.html#cover">probably</a>\r
-don't need to restart the proxy.\r
-<p>\r
-<a name="pub">If you develop an interesting blocklist and publish it on the Web,</a>\r
-you might want to include the word ``junkbuster'' in it\r
-and use the word ``blocklist'' in the file name given in the\r
-<small>URL</small>\r
-so that others can find it with the query given in the previous sentence.\r
-</p>\r
-\r
-<h3><a name="zap" href="/cgi-bin/gp?pg=ijbfaq&pr=zap"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-If I see an ad I wish I hadn't, how do I stop it?\r
-</h3>\r
-<p>\r
-If your\r
-<small>ISP</small>\r
-is running the\r
-Internet Junkbuster,\r
-they should have a policy on whether they accept suggestions from\r
-their customers on what to block. Consult their web page.\r
-<p>\r
-<a name="cover">If you are running</a>\r
-the\r
-Internet Junkbuster\r
-yourself, you have complete control over what gets through.\r
-Just add a pattern to cover the offending \r
-<small>URL</small>\r
-to your blockfile.\r
-Version 1.3 and later automatically rereads the blockfile when it changes,\r
-but if you're running an earlier version you'll\r
-have to\r
-<a href="ijbfaq.html#shutdown">stop it</a>\r
-and restart it.\r
-<p>\r
-<a name="target">To choose a pattern you'll first need to find the</a>\r
-<small>URL</small>\r
-of the ad you want cover.\r
-<p>\r
-<a name="pinpoint">Some people use the</a>\r
-<a href="ijbman.html#debug">debug</a>\r
-<big><kbd>1</kbd></big>\r
-option to display each \r
-<small>URL</small>\r
-in a window as the request is sent to the server.\r
-It's then usually an easy task to pick the offending \r
-<small>URL</small>\r
-from the list of recent candidates.\r
-<p>\r
-<a name="source">Alternatively,</a>\r
-you can use\r
-<b><font face="arial, helvetica">\r
-View Document Info</font></b>\r
-(or\r
-<b><font face="arial, helvetica">\r
-View Document Source</font></b>\r
-if your browser doesn't have that).\r
-The\r
-<b><font face="arial, helvetica">\r
-Info</font></b>\r
-feature has the advantage of showing you the full\r
-<small>URL</small>\r
-including the host name,\r
-which may not be specified in the source:\r
-there you might see something like\r
-<big><kbd>SRC="/ads/click_here_or_die.gif"</kbd></big>\r
-indicating only the\r
-<i><dfn>path</dfn></i>.\r
-(The host name is assumed to be the same as the one the page came from.)\r
-<p>\r
-<a name="offsite">But ads often</a>\r
-come from a different site, in which case you\r
-might see something like\r
-<big><kbd>SRC="grabem.n.trackem.com/Ad/Infinitum/SpaceID=1666"</kbd></big>\r
-or longer.\r
-<a name="warehouse">If the company looks like a pure ad warehouse</a>\r
-(as in the last case),\r
-you may want to place just its domain name in the blockfile,\r
-which blocks all \r
-<small>URL</small>s\r
-from that site.\r
-<p>\r
-<a name="wanted">If the ad comes from a server</a>\r
-that you really want some content from,\r
-you can include enough of the path\r
-to avoid zapping stuff you might want.\r
-In the first example above,\r
-<big><kbd>/ads/</kbd></big>\r
-would seem to be enough.\r
-If you don't include the domain name,\r
-the pattern applies to all sites,\r
-so you don't want such patterns\r
-to be too general:\r
-for example\r
-<big><kbd>/ad</kbd></big>\r
-would block\r
-<big><kbd>/admin/salaries/</kbd></big>\r
-on your company's internal site.\r
-<p>\r
-<a name="image">To speed the blocking of images, some</a>\r
-<small>UNIX <a href="legal.html#not_our_trademark">&#174;</a></small>\r
-users create a\r
-shell script called\r
-<big><kbd>Image:</kbd></big>\r
-containing a line such as\r
-<big><kbd>echo $1 | sed s/http:..// &gt;&gt; $HOME/lib/blockfile</kbd></big>\r
-that adds its argument to the user's blockfile.\r
-Once an offending image has been be found using\r
-<b><font face="arial, helvetica">\r
-View Document Info</font></b>\r
-it's easy to cut-and-paste the line (or part of it) into a shell window.\r
-The same script can be linked to a file called\r
-<big><kbd>Frame:</kbd></big>\r
-to dealing with framed documents,\r
-and\r
-<big><kbd>junkbuster:</kbd></big>\r
-to accept the output of the\r
-<a href="ijbman.html#debug">debug</a>\r
-option.\r
-<p>\r
-<a name="partial">When compiled without the</a>\r
-<i><dfn>regular expressions</dfn></i>\r
-option, the\r
-Internet Junkbuster\r
-uses only very simple (and fast) matching methods.\r
-The pattern\r
-<big><kbd>/banners</kbd></big>\r
-will not stop\r
-<big><kbd>/images/banners/huge.gif</kbd></big>\r
-getting through: you would have to include the pattern\r
-<big><kbd>/images/banners</kbd></big>\r
-or something that matches in full from the left.\r
-<a name="regex">So you can get what you want here,</a>\r
-the matcher understands\r
-<small>POSIX</small>\r
-regular expressions:\r
-you can use\r
-<big><kbd>/*.*/banners</kbd></big>\r
-to block\r
-and any\r
-<small>URL</small>\r
-containing\r
-<big><kbd>/banners</kbd></big>\r
-(even in the middle of the path).\r
-<a name="posix">(In Versions 1.1 through 1.4</a>\r
-they were an option at compile time;\r
-from Version 2.0 they have become the default.)\r
-Regular expressions give you\r
-<a href="http://theory.uwinnipeg.ca/localfiles/infofiles/gcc/rx_toc.html">many more features</a>\r
-than this,\r
-but if you're not already familiar with them you probably won't \r
-need to know anything beyond the\r
-<big><kbd>/*.*/</kbd></big>\r
-idiom.\r
-If you do, a\r
-<big><kbd>man egrep</kbd></big>\r
-is probably a good starting point).\r
-<p>\r
-<a name="slash">Don't forget the</a>\r
-<big><kbd>/</kbd></big>\r
-(slash)\r
-at the beginning of the path.\r
-If you leave it out the line will be interpreted as a domain name,\r
-so\r
-<big><kbd>ad</kbd></big>\r
-would block all sites from Andorra\r
-(since\r
-<big><kbd>.ad</kbd></big>\r
-is the two-letter\r
-<a href="reference.html#country">country code</a>\r
-for that principality).\r
-<p>\r
-<a name="detail">For a detailed technical description</a>\r
-of how pattern matching is done,\r
-see the\r
-<a href="ijbman.html#o_b">manual.</a>\r
-</p>\r
-\r
-<h3><a name="despite" href="/cgi-bin/gp?pg=ijbfaq&pr=despite"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How come this ad is still getting through anyway?\r
-</h3>\r
-<p>\r
-If the ad had been displayed before you included its\r
-<small>URL</small>\r
-in the blockfile,\r
-it will probably be held in cache for some time,\r
-so it will be displayed without the need for any request to the server.\r
-Using the\r
-<a href="ijbman.html#debug">debug</a>\r
-<big><kbd>1</kbd></big>\r
-option to show each\r
-<small>URL</small>\r
-as it is fetched is a good way to see exactly what is happening.\r
-<p>\r
-<a name="otherwise">If new items seem to be getting through,</a>\r
-check that you are\r
-<a href="ijbfaq.html#show">really running</a>\r
-the proxy with the right blockfile in the options.\r
-Check the blockfile for\r
-<a href="ijbfaq.html#exceptions">exceptions.</a>\r
-<p>\r
-<a name="java">Some sites may have different ways of inserting ads,</a>\r
-such as via\r
-<a href="cookies.html#java">Java.</a>\r
-If you have ideas on how to block new kinds\r
-of junk not currently covered, please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=java">tell us.</a>\r
-</p>\r
-\r
-<h3><a name="exceptions" href="/cgi-bin/gp?pg=ijbfaq&pr=exceptions"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How do I stop it blocking a URL that I actually want?\r
-</h3>\r
-<p>\r
-You can change the patterns so they don't cover it,\r
-or use a simple feature in Version 1.1 and later: a line beginning with a\r
-<big><kbd>~</kbd></big>\r
-character means that a\r
-<small>URL</small>\r
-blocked by previous patterns that matches the rest of\r
-the line is let through.\r
-For example,\r
-the pattern\r
-<big><kbd>/ad</kbd></big>\r
-would block\r
-<big><kbd>/addasite.html</kbd></big>\r
-but not if followed by\r
-<big><kbd>~/addasite</kbd></big>\r
-in the blockfile.\r
-Or suppose you want to see everything that comes from\r
-a site you like, even if it looks like an ad: simply put\r
-<big><kbd>~aSiteYouLike.com</kbd></big>\r
-at the\r
-<em>end</em>\r
-of the blockfile.\r
-(Order is important, because the last matching line wins.)\r
-<p>\r
-<a name="agreed">As well as unblocking</a>\r
-pages that were unintentionally blocked,\r
-this feature is useful for unblocking ads from a specific source.\r
-This might be because you are interested in those particular ones,\r
-or if you have an explicit agreement to accept certain ads,\r
-such as those from a free web-based email provider.\r
-</p>\r
-\r
-<h3><a name="children" href="/cgi-bin/gp?pg=ijbfaq&pr=children"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Can I block sites I don't want my children to see?\r
-</h3>\r
-<p>\r
-Yes, but remember that\r
-<a name="savvy">children who are technically sophisticated enough</a>\r
-to use the browsers' proxy configuration options\r
-could of course bypass any proxy.\r
-This kind of technology can be used as a gentle barrier to remind\r
-or guide the child,\r
-but nobody should expect it to replace the parent's role\r
-in setting and enforcing standards of online behavior for their children.\r
-<p>\r
-<a name="recommend">Some</a>\r
-<small>ISP</small>s\r
-are starting to provide specialized proxies to protect children.\r
-There are two basic approaches: the ``black list'' and the ``white list''\r
-approach.\r
-<a name="negative">The black list approach allows the child</a>\r
-to go anywhere not explicitly prohibited; the white list permits visits\r
-only to sites explicitly designated as acceptable.\r
-<p>\r
-<a name="positive">It's very easy for</a>\r
-anyone to\r
-compile a white list from a page of ``recommended\r
-kids sites'' and to configure an\r
-Internet Junkbuster\r
-to allow access to those sites only.\r
-If you compile with the\r
-<a href="ijbfaq.html#regex">regex</a>\r
-option,\r
-you can place a\r
-<big><kbd>*</kbd></big>\r
-(asterisk) as the first line of the blockfile (which blocks everything),\r
-and then list\r
-<a href="ijbfaq.html#exceptions">exceptions</a>\r
-after that.\r
-Be careful to make the exception sufficiently broad:\r
-for example, using\r
-<big><kbd>~www.uexpress.com/ups/comics/ch/</kbd></big>\r
-as the exception for\r
-<a href="http://www.uexpress.com/ups/comics/ch/"><cite>Calvin and Hobbes</cite></a>\r
-would block some of the graphic elements on the page;\r
-you would probably want a wider exception such as\r
-<big><kbd>~www.uexpress.com/ups/</kbd></big>\r
-to permit them.\r
-<p>\r
-<a name="trust">Version 2.0 has an experimental feature</a>\r
-to permit only sites mentioned in a nominated\r
-<a href="ijbman.html#trustfile">trusted site.</a>\r
-This allows organizations to build lists of sites for kids to browse,\r
-and the software automatically restricts access to those on the list.\r
-<p>\r
-<a name="scan">Many filtering</a>\r
-<a href="links.html#blocking">products</a>\r
-actually scan for keywords in\r
-the text of pages they retrieve\r
-before presenting it,\r
-but\r
-the\r
-Internet Junkbuster\r
-does not do this.\r
-Building a perfectly reliable black list system is hard,\r
-because it's very difficult to state\r
-in advance\r
-exactly\r
-what is obscene or unsuitable.\r
-For more info see our\r
-<a href="links.html#parents">links</a>\r
-page.\r
-</p>\r
-\r
-<h3><a name="message" href="/cgi-bin/gp?pg=ijbfaq&pr=message"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What do I see when a page or graphic is blocked by the proxy?\r
-</h3>\r
-<p>\r
-You usually see a broken image icon,\r
-but it depends on several factors beyond the proxy's control.\r
-If asked for a\r
-<small>URL</small>\r
-matching its blockfile, the proxy returns an\r
-<small>HTML</small>\r
-page containing a message identifying itself\r
-(currently the two words ``Internet Junkbuster'')\r
-with a status 202 (Accepted) instead of the usual 200 (OK).\r
-(Versions 1.X returned an error 404: Forbidden, which caused\r
-strange behavior in some cases.)\r
-Status 202 is described in the\r
-<small>HTTP</small>\r
-<a href="http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code202">RFC</a>\r
-as indicating that the request has been accepted but not completed,\r
-and that it might complete successfully in the future\r
-(in our case, if the blockfile were changed).\r
-<p>\r
-<a name="depends">The broken image icon is most common</a>\r
-because the browser is usually expecting a graphic.\r
-But if it was expecting text, or if the page happens to be using certain\r
-<small>HTML</small>\r
-extensions\r
-such as\r
-<big><kbd>layer</kbd></big>\r
-and your browser is a late model from Microsoft,\r
-you may see the words ``Internet Junkbuster'' displayed as a hot link.\r
-<p>\r
-<a name="click">Clicking on the link takes you to an explanation of</a>\r
-the pattern in the blockfile that caused the block,\r
-so that you can edit the blockfile and go back and reload if you really\r
-want to see what was blocked. The explanatory link is generated by\r
-the proxy and is automatically intercepted based on its ending in\r
-<big><kbd>ij-blocked-url</kbd></big>;\r
-even though the site is specified as\r
-<big><kbd>http://internet.junkbuster.com</kbd></big>\r
-no request should actually made to that site.\r
-If one is, it means that the proxy was been removed after it\r
-generated the link.\r
-<p>\r
-<a name="layer">To summarize:</a>\r
-the identifying link to the blocking explanation\r
-is usually turned into a broken image icon,\r
-but it may be displayed on a page alone,\r
-or they may may be restricted to the particular frame, layer or graphic area\r
-specified in the page containing them.\r
-The proxy has no way of knowing the context in which a\r
-<small>URL</small>\r
-will be used and cannot control how the blocking message will be rendered.\r
-</p>\r
-\r
-<h3><a name="broken" href="/cgi-bin/gp?pg=ijbfaq&pr=broken"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Why not replace blocked banners with something invisible?\r
-</h3>\r
-<p>\r
-<a name="infringe">Many users have suggested to us</a>\r
-that blocked banners should be replaced by a something like a\r
-1x1 transparent\r
-<small>GIF</small>\r
-to make the page would look as if there was nothing ever there.\r
-Apart from making it harder to catch unintended blocking,\r
-this might also displease the owners of the page,\r
-who could argue that such a change constitutes a copyright infringement.\r
-We think that merely failing to allow an included graphic to be accessed\r
-would probably not be considered an infringement:\r
-after all this is what happens when a browser\r
-is configured not to load images automatically.\r
-However, we are\r
-<a href="over.html#notlaw">not</a>\r
-lawyers,\r
-so anyone in doubt should take appropriate advice.\r
-<p>\r
-<a name="done">In a context where the copyright issue is resolved</a>\r
-satisfactorily,\r
-a proxy could simply return a status 301 or 302 and\r
-specify a replacement\r
-<small>URL</small>\r
-in a\r
-<big><kbd>Location</kbd></big>\r
-and/or\r
-<big><kbd>URI</kbd></big>\r
-header.\r
-An alternative would be to use inline code to return a\r
-1 x 1 clear\r
-<small>GIF</small>.\r
-We do not publish sample code for this,\r
-and we have no way of stopping\r
-<a href="ijbdist.html#others">others</a>\r
-who have.\r
-</p>\r
-\r
-<h3><a name="size" href="/cgi-bin/gp?pg=ijbfaq&pr=size"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Why not block banners based on the dimensions of the image?\r
-</h3>\r
-<p>\r
-Many users have pointed out that most banner ads come in standard sizes,\r
-so why not block all\r
-<small>GIF</small>s\r
-of those sizes?\r
-This would theoretically be without fetching the object \r
-because the dimensions are usually given in the\r
-<big><kbd>IMG</kbd></big>\r
-tag,\r
-but it would require substantial changes in the code,\r
-and we doubt whether it would be much more effective than a good block list.\r
-</p>\r
-\r
-<h3><a name="embedded" href="/cgi-bin/gp?pg=ijbfaq&pr=embedded"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What about non-graphic advertising within the pages I want?\r
-</h3>\r
-<p>\r
-The\r
-Internet Junkbuster\r
-deliberately\r
-does not provide a way of automatically editing the contents of a page,\r
-to remove textual advertising or\r
-to repair the holes left by blocked banners.\r
-Other packages such as\r
-<a href="links.html#webfilter">WebFilter</a>\r
-do.\r
-<p>\r
-<a name="base">For the same reason,</a>\r
-it has no way of stopping a new browser\r
-window being created, because this is done through the\r
-<big><kbd>target</kbd></big>\r
-attribute in the\r
-<big><kbd>&lt;a&gt;</kbd></big>\r
-and\r
-<big><kbd>&lt;base&gt;</kbd></big>\r
-elements,\r
-not through headers.\r
-Nor do we plan to add a feature to\r
-<a href="http://simmons.starkville.ms.us/tips/081097/">paralyze animated</a>\r
-<small>GIF</small>s.\r
-</p>\r
-\r
-<h3><a name="push" href="/cgi-bin/gp?pg=ijbfaq&pr=push"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Does it block ads on the broadcasting ``push'' systems? How about pop-up ads?\r
-</h3>\r
-<p>\r
-We haven't tried it but we expect it would probably\r
-work on image ads on push channels.\r
-See also\r
-<a href="links.html#adchoice">adchoice</a>.\r
-<p>\r
-<a name="pop">Disabling</a>\r
-<a href="cookies.html#java">Javascript</a>\r
-stops some pop-up ads.\r
-One problem is that some advertisers throw open a new\r
-browser window to frame the ad. The ad is easily blocked,\r
-but the empty window remains. You can kill it easily, but this is a chore.\r
-We don't see how to stop them other than editing the\r
-<small>HTML</small>\r
-from the parent window, which we\r
-<a href="ijbfaq.html#broken">don't</a>\r
-like to do.\r
-<p>\r
-<a name="TBTD">The</a>\r
-<a href="http://www.tbtf.com/archive/10-06-97.html">TBTF</a>\r
-newsletter warned subscribers to push information that\r
-<a name="LOGTARGET">in IE4,</a>\r
-<a href="http://www.microsoft.com/standards/cdf.htm#Logging">LOGTARGET</a>\r
-allows\r
-servers to determine the\r
-<small>URL</small>s\r
-viewed at their site even if accessed from cache or through a proxy.\r
-If you use this browser see our instructions on\r
-<a href="cookies.html#counting">how to disable</a>\r
-this.\r
-<p>\r
-<a name="pushy">If you find you have experience using the proxy with push,</a>\r
-or have any other advice about it, please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=pushy">tell us.</a>\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<br>\r
-<center>\r
-<h2><a name="cookies"><font face="arial, helvetica">\r
-Cookies\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>For background information on cookies see our\r
-<a href="cookies.html">page describing their dangers.</a>\r
-\r
-<h3><a name="breakthrough" href="/cgi-bin/gp?pg=ijbfaq&pr=breakthrough"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Might some cookies still get through? How can I stop them?\r
-</h3>\r
-<p>\r
-Yes, you should expect the occasional cookie to make it through to your browser.\r
-We know of at least three ways this can happen;\r
-please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=breakthrough">tell us</a>\r
-if you find any others.\r
-One way is in secure documents, which are explained\r
-<a href="ijbfaq.html#secure">below.</a>\r
-<p>\r
-<a name="EQUIV">A</a>\r
-<a href="links.html#JavaScript">few</a>\r
-sites set cookies using a line such as\r
-<big><kbd>&lt;META HTTP-EQUIV="Set-Cookie" CONTENT="flavor=chocolate"&gt;</kbd></big>\r
-in the\r
-<big><kbd>HEAD</kbd></big>\r
-section of an\r
-<small>HTML</small>\r
-document.\r
-<a name="javascript">Cookies can also be</a>\r
-<!-- IEM: http://cgi.netscape.com/eng/mozilla/Gold/handbook/javascript/ref_a-c.html#cookie_property -->\r
-set and read\r
-in\r
-JavaScript.\r
-To see if this is happening in a document,\r
-view its source, look in the\r
-<big><kbd>head</kbd></big>\r
-for a section tagged\r
-<big><kbd>script language="JavaScript"</kbd></big>.\r
-If it contains a reference to\r
-<big><kbd>document.cookie</kbd></big>,\r
-the page can manipulate your cookie file without sending any cookie headers.\r
-The\r
-Internet Junkbuster\r
-does not tamper with these methods.\r
-Fortunately they are rarely used at the moment.\r
-If a cookie gets set, it should be stopped\r
-by the proxy on its way back to the server when a page is requested,\r
-but it can still be read in Javascript.\r
-bu\r
-<p>\r
-<a name="alert">To prevent cookies breaking through,</a>\r
-<strong>always</strong>\r
-keep\r
-<a href="cookies.html#disable">cookie alerts</a>\r
-turned on in your browser,\r
-and\r
-<a href="cookies.html#java">disable</a>\r
-Java and Javascript.\r
-Making the files\r
-<a href="cookies.html#only">hard to write</a>\r
-may also help.\r
-</p>\r
-\r
-<h3><a name="method" href="/cgi-bin/gp?pg=ijbfaq&pr=method"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Exactly how do cookies get created and stored anyway?\r
-</h3>\r
-<p>\r
-When a web site's server sends you a page it also sends\r
-certain ``header information'' which your browser records but does not display.\r
-One of these is a\r
-<big><kbd>Set-Cookie</kbd></big>\r
-header, which specifies the cookie information that the server wants your browser to record.\r
-Similarly, when your browser requests a page it also sends headers, specifying\r
-information such as the graphics formats it understands.\r
-If a cookie has previously been set by a site that matches the\r
-<small>URL</small>\r
-it is about to request,\r
-your browser adds a\r
-<big><kbd>Cookie</kbd></big>\r
-header quoting the previous information.\r
-<p>\r
-<a name="privacy">For more background information on how cookies</a>\r
-can damage your privacy, see our\r
-<a href="cookies.html">page on cookies.</a>\r
-For highly detailed technical information see the\r
-<a href="links.html#kristol">RFC.</a>\r
-The\r
-Internet Junkbuster\r
-will show you all headers you use the\r
-<a href="ijbman.html#debug">debug</a>\r
-<big><kbd>8</kbd></big>\r
-option,\r
-or you can get a sample from our\r
-<a href="ijbfaq.html#headers">demonstration page.</a>\r
-</p>\r
-\r
-<h3><a name="break" href="/cgi-bin/gp?pg=ijbfaq&pr=break"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-If cookies can't get through, will some things stop working for me?\r
-</h3>\r
-<p>\r
-Possibly.\r
-Some personalized services including certain\r
-<!-- IEM: http://my.yahoo.com -->\r
-chat\r
-rooms\r
-require cookies.\r
-<a name="registration">Newspapers that require</a>\r
-<!-- IEM: http://www.nytimes.com/subscribe/sub-bin/new_sub.cgi#agree -->\r
-registration\r
-or\r
-<!-- IEM: http://interactive5.wsj.com/regUser.html -->\r
-subscription\r
-will not automatically recognize you if you don't send them the cookie they\r
-assigned you. And there are a very small number of sites that do\r
-strange things with cookies; they don't work for anyone that blocks\r
-cookies by any means.\r
-Some sites such as\r
-<a href="links.html#withhold">Microsoft</a>\r
-explain that their content is so wonderfully compelling that\r
-they will withhold it from you unless you submit to their\r
-inserting cookies.\r
-<p>\r
-<a name="want">If you want such sites to be given your cookies,</a>\r
-you can use the\r
-<a href="ijbman.html#cookiefile">cookiefile</a>\r
-option provided you are running\r
-<a href="ijbfaq.html#crumble">Version 1.2 or later</a>\r
-yourself.\r
-Simply include the domain name of those sites in the\r
-<i>cookiefile</i>\r
-specified by this option.\r
-If it still doesn't work,\r
-the problem may be in\r
-<a href="ijbfaq.html#breakage">other headers.</a>\r
-<p>\r
-<a name="one">It's possible to let cookies out but not in,</a>\r
-which is enough to keep some sites happy, but not all of them:\r
-one newspaper site seems to go into an endless frenzy\r
-if deprived of fresh cookies.\r
-A cookiefile containing\r
-a single line consisting of the two characters\r
-<big><kbd>&gt;*</kbd></big>\r
-(greater-than and star) permits server-bound cookies only.\r
-The\r
-<big><kbd>*</kbd></big>\r
-is a\r
-<a href="ijbman.html#wildcard">wildcard</a>\r
-that matches all domains.\r
-<p>\r
-<a name="else">If someone else is running the</a>\r
-Internet Junkbuster\r
-for you and has a version\r
-that\r
-<!-- IAM: ijbfaq.html#registration -->\r
-passes server-bound cookies through,\r
-you can try editing your browser's cookie\r
-file to contain just the ones you want,\r
-and restart your browser.\r
-<a name="window">To subscribe to a new service like this</a>\r
-after you have started using the\r
-Internet Junkbuster,\r
-you can try the following:\r
-tell your browser to\r
-<a href="ijbfaq.html#discontinue">stop using</a>\r
-the\r
-Internet Junkbuster,\r
-fill out and submit your subscription details\r
-(allowing that web site to set a cookie),\r
-then\r
-reconfigure your browser to use the\r
-Internet Junkbuster\r
-again\r
-(and stop more cookies being sent).\r
-This also requires the\r
-<a href="ijbman.html#cookiefile">cookiefile</a>\r
-option,\r
-and its success depends on the Web site\r
-not wanting to change your cookies at every session.\r
-For this reason it does not work at some major newspaper sites, for example.\r
-<a name="buyers">But you may prefer to</a>\r
-look at whether other sites provide the same\r
-or better services without demanding the opportunity\r
-to track your behavior.\r
-The web is a buyer's market where most prices are zero:\r
-very few people pay\r
-for content with money, so why should you pay with your privacy?\r
-</p>\r
-\r
-<h3><a name="crumble" href="/cgi-bin/gp?pg=ijbfaq&pr=crumble"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Can I control cookies on a per-site basis?\r
-</h3>\r
-<p>\r
-<a name="discard">Yes, since version 1.2 the</a>\r
-Internet Junkbuster\r
-has included advanced cookie management facilities.\r
-Unless you specify otherwise,\r
-cookies are discarded (``crumbled'') by the\r
-Internet Junkbuster\r
-whether they came from the server or the browser.\r
-In Version 1.2 and later you can\r
-use the\r
-<a href="ijbman.html#cookiefile">cookiefile</a>\r
-option\r
-to specify when cookies are to be passed through intact.\r
-It uses the same syntax and\r
-<a href="ijbman.html#o_b">matching</a>\r
-algorithm as the blockfile.\r
-<p>\r
-<a name="cook">If the</a>\r
-<small>URL</small>\r
-matches a pattern in the\r
-<i><dfn>cookiefile</dfn></i>\r
-then cookies are let through in both the browser's request for the\r
-<small>URL</small>\r
-and in the server's response.\r
-<a name="directional">One-way permissions can be</a>\r
-specified by starting the line with the\r
-<big><kbd>&gt;</kbd></big>\r
-or\r
-<big><kbd>&lt;</kbd></big>\r
-character.\r
-For example, a cookiefile consisting of the four lines\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>org</kbd></big>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>&gt;send-user-cookies.org</kbd></big>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>&lt;accept-server-cookies.org</kbd></big>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>~block-all-cookies.org</kbd></big>\r
-<br>\r
-allows cookies to and from\r
-<big><kbd>.org</kbd></big>\r
-domains only, with the following exceptions:\r
-<br><ol  type="1">\r
-<li>\r
-<a name="fed">Cookies sent from servers in the domain</a>\r
-<big><kbd>send-user-cookies.org</kbd></big>\r
-are blocked on their way to the client,\r
-but cookies sent by the browser to that domain are still be fed to them.\r
-<li>\r
-<a name="take">The cookies of</a>\r
-<big><kbd>accept-server-cookies.org</kbd></big>\r
-check in to the proxy and are passed through to the browser,\r
-but when they come back to the proxy they never check out.\r
-<li>\r
-<a name="deny">All cookies to and from</a>\r
-<big><kbd>block-all-cookies.org</kbd></big>\r
-are blocked.\r
-</ol>\r
-<p>\r
-<a name="paths">If</a>\r
-the\r
-<b><kbd>junkbuster</kbd></b>\r
-was compiled with the regular expressions option\r
-they may be used in paths.\r
-Any logging to a\r
-<a href="ijbfaq.html#jar">``cookie jar''</a>\r
-is separate and not affected.\r
-<p>\r
-<a name="breadth">It's important to give hosts you want to be able</a>\r
-to set cookies sufficient breadth. For example,\r
-instead of\r
-<big><kbd>www.yahoo.com</kbd></big>\r
-use\r
-<big><kbd>yahoo.com</kbd></big>\r
-because the company uses many different hosts ending in that domain.\r
-</p>\r
-\r
-<h3><a name="wafers" href="/cgi-bin/gp?pg=ijbfaq&pr=wafers"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Can I make up my own fake cookies (wafers) to feed to servers?\r
-</h3>\r
-<p>\r
-Yes,\r
-using the\r
-<a href="ijbman.html#wafer">wafer</a>\r
-option.\r
-We coined the term\r
-<i><dfn>wafer</dfn></i>\r
-to describe cookies chosen by a user,\r
-not the Web server.\r
-Servers may not find wafers as tasty as the cookies\r
-they make themselves.\r
-But users may enjoy controlling servers' diets for various reasons,\r
-such as the following.\r
-<br><ul  type="1">\r
-<li>\r
-<a name="retaliate">Users who consider cookies to</a>\r
-be an unwelcome intrusion and a waste\r
-of their disk space can respond in kind.\r
-By writing ``signature wafers'' they can\r
-express their feelings about cookies,\r
-in a place that the people\r
-in charge of them are most likely to notice.\r
-<li>\r
-<a name="notice">Sites running a proxy</a>\r
-that logs cookies to a file\r
-(such as the\r
-Internet Junkbuster\r
-does with the\r
-<a href="ijbman.html#jarfile">jarfile</a>\r
-option on)\r
-may want to notify\r
-servers that their cookies are being intercepted,\r
-deleted or copied.\r
-One possible reason for doing this is the uncertain copyright status\r
-of cookie strings.\r
-<a href="over.html#notlaw">Nothing</a>\r
-here should be taken as legal advice: we are simply raising a question\r
-for any interested parties to consider,\r
-and make no representation that such measures are necessary or sufficient.\r
-Concerned proxy sites might decide to send a wafer\r
-(named ``NOTICE'' for example)\r
-containing text along the lines of the following.\r
-<blockquote>\r
-<p>\r
-<a name="licenses_on_cookies_refused">TO WHOM IT MAY CONCERN</a>\r
-<i>\r
-<br>\r
-<br>\r
-Do not send me any copyrighted information other than the\r
-document that I am requesting or any of its necessary components.\r
-<br>\r
-<br>\r
-In particular do not send me any cookies that\r
-are subject to a claim of copyright by anybody.\r
-Take notice that I refuse to be bound by any license condition\r
-(copyright or otherwise) applying to any cookie.\r
-</i>\r
-</blockquote>\r
-Any company that tries to argue in court that the proxy site\r
-was breaching their copyright in the cookies would\r
-be met with the defense that the proxy site gave that company\r
-the opportunity to protect its copyright by simply\r
-not sending cookies after receiving the notice. \r
-<p>\r
-<a name="pointer">Cookies can be as long as four thousand characters,</a>\r
-so there's plenty of space for lawyerly verbosity,\r
-but white space, commas, and semi-colons are\r
-<a href="ijbman.html#o_w">prohibited.</a>\r
-Spaces can be turned into underscores.\r
-Alternatively,\r
-a\r
-<small>URL</small>\r
-could be sent as the cookie value,\r
-pointing to a document containing a notice,\r
-perhaps with a suggestive value such as\r
-<br>\r
-<big><kbd>http://www.junkbusters.com/ht/en/ijbfaq.html#licenses_on_cookies_refused</kbd></big>\r
-<br>\r
-But including the notice directly would probably be preferable\r
-because the addressee does not have to look it up.\r
-<p>\r
-<a name="vanilla">The</a>\r
-Internet Junkbuster 2.0\r
-currently sends a full notice as a\r
-``vanilla wafer''\r
-if cookies are being logged to a cookie jar\r
-and no other wafers have been specified.\r
-It can be suppressed with the\r
-<a href="ijbman.html#suppress-vanilla-wafer">suppress-vanilla-wafer</a>\r
-option,\r
-which might be used in situations where there is an established understanding\r
-between the proxy and all who serve it.\r
-</ul>\r
-<p>\r
-<a name="gimme">Junkbusters provides a</a>\r
-<small>CGI</small>\r
-script that lets you\r
-<a href="ijbfaq.html#headers">see</a>\r
-your wafers as they appear to servers.\r
-<p>\r
-<a name="malfunction">Wafers confuse a few fragile servers.</a>\r
-If this troubles you, don't use this option.\r
-<p>\r
-<a name="regardless">Any wafers specified are sent to</a>\r
-all sites regardless of the cookiefile.\r
-<a name="compliant">They are appended after any genuine cookies,</a>\r
-to maintain compliance with\r
-<a href="links.html#kristol">RFC 2109</a>\r
-in the event that a path was specified for a cookie.\r
-The\r
-<small>RFC</small>'s provisions regarding the\r
-<big><kbd>$</kbd></big>\r
-character\r
-(such as the\r
-<big><kbd>Version</kbd></big>\r
-attribute)\r
-are transparent\r
-to the proxy; it simply quotes what was recited by the browser.\r
-<p>\r
-<a name="personalize">If you want to send wafers only to specific sites,</a>\r
-you could try putting them your browser's cookie file in a format\r
-conforming to the Netscape\r
-<a href="links.html#netscape">specification</a>,\r
-and then specify in the proxy's cookiefile that cookies are to be\r
-<a href="ijbfaq.html#directional">sent to</a>\r
-but not accepted from those sites, so they can't overwrite the file.\r
-This may work with Netscape but not all other browsers.\r
-</p>\r
-\r
-<h3><a name="jar" href="/cgi-bin/gp?pg=ijbfaq&pr=jar"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Why would anyone want to save their cookies in a ``cookie jar?''\r
-</h3>\r
-<p>\r
-We provided this capability just in case anyone wants it.\r
-There are a few possible reasons.\r
-<br><ul  type="1">\r
-<li>\r
-<a name="pay">It's conceivable that</a>\r
-marketing companies might one day\r
-<a href="new.html#hagel">buy</a>\r
-history files and cookie jars from consumers\r
-in the same way that they currently pay them to fill out survey forms.\r
-With this information they could\r
-gather psychographic information,\r
-see which competitors' sites the consumer has visited,\r
-and discover what advertising is being targeted at them.\r
-<li>\r
-<a name="choose">Some consumers might</a>\r
-employ semi-automated means of sorting through\r
-their cookie jars, selecting which ones to place in their cookies\r
-file for use by their browsers.\r
-Their decisions could be based on payments offered,\r
-privacy rating systems such as\r
-<a href="links.html#truste">TRUSTe</a>\r
-proposes,\r
-or their own opinion of the company.\r
-It could be done manually or with software.\r
-<li>\r
-<a name="share">Users may even start ``sharing'' cookies among themselves,</a>\r
-sending back cookies that servers generated for other visitors.\r
-Servers that aren't expecting this possibility\r
-will be misled about their visitors' identities.\r
-Cookies could be shared among users on a single machine,\r
-or across continents via\r
-<small>FTP</small>\r
-and anonymous remailers.\r
-<a name="disinformation">Privacy activists may promote</a>\r
-cookie disinformation campaigns\r
-as a way to defend the public against abuse.\r
-If a significant percentage of people send disinformative cookies,\r
-user tracking via cookies may become less reliable and less used.\r
-</ul>\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<br>\r
-<center>\r
-<h2><a name="anonymity"><font face="arial, helvetica">\r
-Anonymity\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>For details\r
-on how your identity can be revealed while you surf,\r
-see our page on\r
-<a href="http://www.junkbusters.com/cgi-bin/privacy">privacy.</a>\r
-Once you start using\r
-the\r
-Internet Junkbuster\r
-you should find that much of the information\r
-previously indicated on that page will no longer be provided.\r
-If the\r
-<big><kbd>REMOTE HOST</kbd></big>\r
-indicating your IP address is too close for comfort,\r
-see our suggestions\r
-<a href="ijbfaq.html#conceal">below</a>\r
-on how to\r
-conceal\r
-your IP address.\r
-We also recommend that you\r
-<a href="cookies.html">disable JavaScript</a>\r
-and\r
-<a href="links.html#java">Java.</a>\r
-\r
-<h3><a name="disclose" href="/cgi-bin/gp?pg=ijbfaq&pr=disclose"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-If I use the Internet Junkbuster, will my anonymity be guaranteed?\r
-</h3>\r
-<p>\r
-No. Your chances of remaining anonymous are improved,\r
-but unless you are an expert on Internet security\r
-it would be safest to assume that everything you do on the Web\r
-can be attributed to you personally.\r
-<p>\r
-<a name="happen">The</a>\r
-Internet Junkbuster\r
-removes various information about you,\r
-but it's still possible that web sites can find out who you are.\r
-Here's one way this can happen.\r
-<p>\r
-<a name="ftp">A few browsers</a>\r
-<a href="http://www.junkbusters.com/cgi-bin/privacy">disclose the user's email address</a>\r
-in certain situations, such as when transferring a file by\r
-<small>FTP</small>.\r
-The\r
-Internet Junkbuster 2.0\r
-does not filter the\r
-<small>FTP</small>\r
-stream.\r
-If you need this feature, or are concerned about the mail handler\r
-of your browser disclosing your email address,\r
-you might consider\r
-products such as\r
-<a href="links.html#nsclean">NSClean</a>.\r
-<p>\r
-<a name="binaries">Browsers downloaded as binaries</a>\r
-could use non-standard headers to give out any information\r
-they can have access to: see the manufacturer's license agreement.\r
-It's impossible to anticipate and prevent every breach of privacy that\r
-might occur.\r
-The professionally paranoid prefer browsers available as source code,\r
-because anticipating their behavior is easier.\r
-</p>\r
-\r
-<h3><a name="should" href="/cgi-bin/gp?pg=ijbfaq&pr=should"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Why should I trust my ISP or Junkbusters with my browsing data?\r
-</h3>\r
-<p>\r
-You shouldn't have to trust us, and you certainly don't have to.\r
-We do not run the proxy as a service,\r
-where we could observe your online behavior.\r
-We provide source code so that everyone can see that the proxy isn't\r
-doing anything sneaky.\r
-<p>\r
-<a name="awful">You are already trusting your</a>\r
-<small>ISP</small>\r
-not to look at an awful lot of information on what you do.\r
-They probably post a\r
-<a href="links.html#policy">privacy policy</a>\r
-on their site to reassure you.\r
-If they run a proxy for you, using it could actually\r
-make it slightly easier for them to monitor you,\r
-but we doubt that any sane\r
-<small>ISP</small>\r
-would try this,\r
-because if it were discovered customers would desert them.\r
-</p>\r
-\r
-<h3><a name="header" href="/cgi-bin/gp?pg=ijbfaq&pr=header"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What private information from server-bound headers is removed?\r
-</h3>\r
-<p>\r
-The\r
-Internet Junkbuster\r
-pounces on the following\r
-<small>HTTP</small>\r
-headers in requests to servers,\r
-unless instructed otherwise in the options.\r
-<br><ul  type="1">\r
-<li>\r
-<a name="from">The</a>\r
-<big><kbd>FROM</kbd></big>\r
-header,\r
-which a few browsers use to tell your email address to servers,\r
-is dropped\r
-unless the\r
-<a href="ijbman.html#from">from</a>\r
-option is set.\r
-<li>\r
-<a name="agent">The</a>\r
-<big><kbd>USER_AGENT</kbd></big>\r
-<a name="infer">header</a>\r
-is changed to indicate that the browser is\r
-currently Mozilla (Netscape) 3.01 Gold\r
-with an unremarkable Macintosh configuration.\r
-Misidentification helps resist certain\r
-<a href="ijbfaq.html#misidentify">attacks.</a>\r
-If your browser and hardware happen to be accurately identified,\r
-you might want to change the default.\r
-(Earlier versions of the\r
-Internet Junkbuster\r
-indicated different details;\r
-by altering them periodically we aim to hinder anyone trying to\r
-<a href="ijbfaq.html#detect">infer</a>\r
-whether our proxy is present.)\r
-<a name="lying">If you don't like the idea</a>\r
-of incorrectly identifying your computer as a Mac,\r
-set it accordingly.\r
-<!-- Aside: or read Kundera's Unbearable Lightness of Being, 5:5, ``It is a tragicomic fact..'' (p187?) -->\r
-<li>\r
-<a name="referer">The</a>\r
-<big><kbd>REFERER</kbd></big>\r
-header\r
-(which indicates where the\r
-<small>URL</small>\r
-currently being requested was found)\r
-is dropped.\r
-A single static referer to replace all\r
-real referers may be specified using the \r
-<a href="ijbman.html#referer">referer</a>\r
-option.\r
-Where no referer is provided by the browser, none is added;\r
-the\r
-<a href="ijbman.html#add-header">add-header</a>\r
-option with arguments such as\r
-<big><kbd>-x 'Referer: http://me.me.me'</kbd></big>\r
-can be used to send a bogus referer with every request.\r
-</ul>\r
-In \r
-Version <a href="ijbdist.html#c4">1.4</a>\r
-and later you can use the\r
-<a href="ijbman.html#o_r">-r @</a>\r
-option to selectively disclose\r
-<big><kbd>REFERER</kbd></big>\r
-and\r
-<big><kbd>USER_AGENT</kbd></big>\r
-to only those sites you nominate.\r
-<p>\r
-<a name="UA">Some browsers</a>\r
-send Referer and User-Agent information under different non-standard headers.\r
-The\r
-Internet Junkbuster 2.0\r
-stops\r
-<big><kbd>UA</kbd></big>\r
-headers,\r
-but others may get through.\r
-This information is also available via JavaScript,\r
-so\r
-<a href="cookies.html">disable disable</a>\r
-it.\r
-<a name="indexers">Some search engines</a>\r
-<a href="cookies.html#queries">encode the query you typed</a>\r
-in the\r
-<small>URL</small>\r
-that goes to advertisers to target a banner ad at you,\r
-so you will need to block the ad as well as the referer header,\r
-unless you want them (and anyone they might\r
-<a href="cookies.html#set">buy data</a>\r
-from)\r
-to know\r
-<a href="links.html#search">everything you ever search for.</a>\r
-<p>\r
-<a name="JavaScript">If you have JavaScript enabled (the default on</a>\r
-most browsers) servers can use it to obtain Referer and User Agent,\r
-as well as your plug-ins.\r
-We recommend\r
-<a href="cookies.html#java">disabling</a>\r
-JavaScript and Java.\r
-<p>\r
-<a name="response">Currently no</a>\r
-<small>HTTP</small>\r
-response headers (browser bound)\r
-are removed,\r
-not even the\r
-<big><kbd>Forwarded:</kbd></big>\r
-or\r
-<big><kbd>X-Forwarded-For:</kbd></big>\r
-headers.\r
-Nor are any added,\r
-<a href="ijbman.html#o_y">unless requested.</a>\r
-We are considering a more flexible header management system for\r
-a future version.\r
-</p>\r
-\r
-<h3><a name="breakage" href="/cgi-bin/gp?pg=ijbfaq&pr=breakage"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Might some things break because header information is changed?\r
-</h3>\r
-<p>\r
-Possibly.  If used with a browser less advanced than Netscape 3.0 or IE-3,\r
-indicating an advanced browser\r
-may encourage pages containing extensions that confuse your browser.\r
-If this becomes a problem\r
-upgrade your browser or\r
-use the\r
-<a href="ijbman.html#user-agent">user-agent</a>\r
-option to indicate an\r
-<a href="ijbfaq.html#low">older browser.</a>\r
-In \r
-Version <a href="ijbdist.html#c4">1.4</a>\r
-and later you can selectively reveal your real browser\r
-to only those sites you nominate.\r
-<p>\r
-<a name="Russian">Because different browsers</a>\r
-use different encodings of Russian characters,\r
-certain web servers convert pages on-the-fly according to the User Agent\r
-header. Giving a User Agent with the wrong operating system or\r
-browser manufacturer causes some Russian sites to be garbled;\r
-Russian surfers should\r
-<a href="ijbman.html#o_r">change it</a>\r
-to something closer.\r
-<p>\r
-<a name="counters">Some</a>\r
-<a href="http://www.yahoo.com/Computers_and_Internet/Internet/World_Wide_Web/Programming/Access_Counts/">page access counters</a>\r
-work by looking at the referer;\r
-they may fail or break when deprived.\r
-<p>\r
-<a name="wired">Some sites depend on getting a referer header,</a>\r
-such as\r
-<big><kbd>uclick.com</kbd></big>,\r
-which serves comic strips\r
-for many newspaper sites,\r
-including\r
-<a href="http://www.uclick.com/?feature=db"><cite>Doonsbury</cite></a>\r
-for the\r
-<a href="http://www.washingtonpost.com/wp-srv/style/longterm/comics/comics.htm"><cite>Washington Post.</cite></a>\r
-(If you click on that last link, you can then get to a page containing\r
-the strip via the\r
-same\r
-<small>URL</small>\r
-we've linked to under\r
-<cite>Doonsbury</cite>,\r
-but if you click on the\r
-<cite>Doonsbury</cite>\r
-link directly, it gives you an error message suggesting that you\r
-use a browser that supports referers.)\r
-In \r
-Version <a href="ijbdist.html#c4">1.4</a>\r
-and later you can use the\r
-<a href="ijbman.html#o_r">-r @</a>\r
-option\r
-and place a line like\r
-<big><kbd>&gt;uclick.com</kbd></big>\r
-in your cookiefile.\r
-<a href="http://www.wired.com/news/">Wired News</a>\r
-used to use referer to decide whether to add a navigation column to\r
-the page, but they have changed that.\r
-<p>\r
-<a name="Intellicast">The weather maps of</a>\r
-<a href="links.html#Intellicast">Intellicast</a>\r
-have been blocked by their server when no referer or cookie is provided.\r
-You can use the same countermeasure with a line such as\r
-<big><kbd>&gt;208.194.150.32</kbd></big>\r
-(or simply get your weather information\r
-<a href="ijbfaq.html#buyers">elsewhere</a>).\r
-<p>\r
-<a name="decide">Some software vendors, including</a>\r
-<a href="http://www.intuit.com/quicken_store/">Intuit</a>\r
-use\r
-<big><kbd>USER_AGENT</kbd></big>\r
-to decide which versions of their products to display to you.\r
-With the\r
-<a href="ijbfaq.html#agent">default</a>\r
-you get Mac versions.\r
-<p>\r
-<a name="resort">As a last resort if a site you need doesn't seem to be working,</a>\r
-the\r
-<a href="ijbfaq.html#set">proxy configuration</a>\r
-of many browsers allow you to specify\r
-<b><font face="arial, helvetica">\r
-No Proxy For</font></b>\r
-any hostname you want.\r
-<p>\r
-<a name="What">We had reports that on some versions of Netscape the</a>\r
-<a href="http://home.netscape.com/home/whats-new.html">What's New</a>\r
-feature did not work with the proxy,\r
-but we think we fixed this in Version 2.0.1.\r
-</p>\r
-\r
-<h3><a name="misidentify" href="/cgi-bin/gp?pg=ijbfaq&pr=misidentify"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How is misidentifying my browser good for security and privacy?\r
-</h3>\r
-<p>\r
-Almost\r
-<a href="new.html#Browser">every</a>\r
-major release of both leading browsers has contained\r
-bugs that allow malicious servers to compromise your privacy and security.\r
-Known bugs are quickly fixed, but millions of copies of the affected\r
-software remain out there, and yours is probably one of them.\r
-The\r
-<a href="ijbfaq.html#agent">header</a>\r
-that normally identifies your browser tells such servers exactly which attacks\r
-to use against you.\r
-By misidentifying your browser you reduce the likelihood that they\r
-will be able to mount a successful attack.\r
-</p>\r
-\r
-<h3><a name="conceal" href="/cgi-bin/gp?pg=ijbfaq&pr=conceal"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Does the Internet Junkbuster conceal my IP address?\r
-</h3>\r
-<p>\r
-Web sites get the IP address of any proxy or browser they serve pages to.\r
-If you run the proxy on your own computer the IP address disclosed\r
-is the same as your browser would, unless you use the\r
-<a href="ijbman.html#forwardfile">forwardfile</a>\r
-option is used to chain to another proxy,\r
-in which case servers only get the last IP address in the chain.\r
-Chaining slightly slows browsing of course, but it improves anonymity.\r
-<p>\r
-<a name="anonymizing">One public proxy that you can</a>\r
-forward to is\r
-<a href="new.html#LPWA">lpwa.com</a>\r
-port 8000.\r
-Read about its privacy-enhancing\r
-features and the authentication procedures first,\r
-and note that it blocks\r
-<a href="ijbfaq.html#wired">referer</a>\r
-in almost all cases,\r
-as well as some\r
-<a href="http://lpwa.com:8000/system.html#principles:header">other headers.</a>\r
-</p>\r
-\r
-<h3><a name="authorize" href="/cgi-bin/gp?pg=ijbfaq&pr=authorize"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-How can I set the proxy to remember my LPWA password?\r
-</h3>\r
-<p>\r
-After you log in to\r
-<a href="http://lpwa.com">LPWA</a>\r
-it tells your browser to send a\r
-<big><kbd>Proxy-authorization</kbd></big>\r
-header with each request.\r
-Whenever you shut down the browser and start again with a new browser,\r
-you need to log in again.\r
-If you are the only person using the\r
-Internet Junkbuster\r
-proxy, you can avoid repeated logins to\r
-<a href="http://lpwa.com">LPWA</a>\r
-by telling the\r
-Internet Junkbuster\r
-to send the information by placing a line such as\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>add-header Proxy-authorization: Basic ZHVtbXk=.</kbd></big>\r
-<br>\r
-in the configuration file.\r
-The exact example above\r
-<em>does not work</em>\r
-because the code\r
-<big><kbd>ZHVtbXk=.</kbd></big>\r
-is a bogus one that\r
-<a href="http://lpwa.com">LPWA</a>\r
-would never generate;\r
-follow the procedure below to generate a valid one.\r
-<br><ol  type="1">\r
-<li>\r
-<a name="eight">Restart your</a>\r
-Internet Junkbuster\r
-with\r
-<big><kbd>debug 8</kbd></big>\r
-so you can see the\r
-<a href="ijbman.html#o_d">headers.</a>\r
-<li>\r
-<a name="login">Log in to</a>\r
-<a href="http://lpwa.com">LPWA</a>\r
-and go to any other site.\r
-<li>\r
-<a name="observe">Find the</a>\r
-<big><kbd>Proxy-authorization</kbd></big>\r
-header from the debug output and paste it\r
-after the word\r
-<a href="ijbman.html#add-header">add-header</a>\r
-into the config file.\r
-Also change the debug value back again.\r
-<li>\r
-<a name="return">Shut down your browser, start it up again, and</a>\r
-restart the proxy. Test that it works.\r
-</ol>\r
-This trick is convenient for sole users, but is not suitable when\r
-more than one person uses the proxy, because they will all get the\r
-same\r
-<a href="http://lpwa.com">LPWA</a>\r
-identity.\r
-</p>\r
-\r
-<h3><a name="ident" href="/cgi-bin/gp?pg=ijbfaq&pr=ident"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Does the Internet Junkbuster thwart identification by identd?\r
-</h3>\r
-<p>\r
-We think so,\r
-provided you are not the user running the\r
-proxy.\r
-If your computer (or your\r
-<small>ISP</small>'s)\r
-is running the\r
-<a href="links.html#identd"><kbd>identd</kbd></a>\r
-demon,\r
-servers can ask it for the identity of the\r
-user making the request at time you request a page from them.\r
-But if you're going through a proxy,\r
-they will identify the user name associated with the proxy, not you.\r
-A visit to\r
-<a href="http://ident.junkbusters.com">http://ident.junkbusters.com</a>\r
-lets you see what's happening.\r
-This test is (quite rightly) blocked by many\r
-<a href="ijbfaq.html#firewall">firewalls;</a>\r
-just interrupt the transfer if you get an abnormal wait after clicking.\r
-Running other applications\r
-may also expose you via\r
-<a href="links.html#identd"><kbd>identd</kbd></a>;\r
-the proxy of course doesn't help then.\r
-</p>\r
-\r
-<h3><a name="detect" href="/cgi-bin/gp?pg=ijbfaq&pr=detect"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Can web sites tell that I'm using the Internet Junkbuster?\r
-</h3>\r
-<p>\r
-With the default options the proxy doesn't announce itself.\r
-Obvious indications such as\r
-<a href="links.html#alive">Keep-Alive</a>\r
-headers are\r
-<a href="ijbman.html#o_x">deleted,</a>\r
-but sites might notice that you can cancel cookies faster than\r
-any human could possibly click on a mouse.\r
-(If you want to provide a\r
-plausible explanation for this,\r
-change the User Agent header to a\r
-<a href="ijbfaq.html#lynx">cookie-free</a>\r
-or\r
-<a href="cookies.html#communicator">cookie-crunching</a>\r
-browser).\r
-<p>\r
-<a name="figure">But when certain options</a>\r
-are used they could figure out something's going on,\r
-even if they're not pushing cookies.\r
-If you use blocking\r
-they can tell from their logs that the graphics in their pages\r
-are not being requested selectively.\r
-The\r
-<a href="ijbman.html#add-forwarded-header">add-forwarded-header</a>\r
-option explicitly announces to the server that a proxy is present,\r
-and\r
-sending them\r
-<a href="ijbfaq.html#wafers">wafers</a>\r
-is of course a dead giveaway.\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<br>\r
-<center>\r
-<h2><a name="security"><font face="arial, helvetica">\r
-Security\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>\r
-<h3><a name="encrypt" href="/cgi-bin/gp?pg=ijbfaq&pr=encrypt"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-What happens with Secure Documents (SSL, https:)?\r
-</h3>\r
-<p>\r
-If you enter a\r
-``Secure Document Area,''\r
-cookies and other header information\r
-such as User Agent and Referer\r
-are sent encrypted,\r
-so they cannot be filtered.\r
-We recommend getting your browser to alert you when this happens.\r
-(On Netscape:\r
-<b><font face="arial, helvetica">\r
-Options</font></b>;\r
-<b><font face="arial, helvetica">\r
-Security</font></b>;\r
-<b><font face="arial, helvetica">\r
-General</font></b>;\r
-<b><font face="arial, helvetica">\r
-Show an alert before entering a secure document space</font></b>.) \r
-We also recommend adding the line\r
-<big><kbd>:443</kbd></big>\r
-to the blockfile to stop all but sites specified in an exception\r
-after that line from using SSL.\r
-<p>\r
-<a name="passage">It may be possible to filter encrypted cookies</a>\r
-by combining the blocking proxy with a cryptographic proxy along\r
-the lines of\r
-<a href="http://stronghold.ukweb.com/safepassage/">SafePassage</a>,\r
-but we have not tried this.\r
-</p>\r
-\r
-<h3><a name="ssl" href="/cgi-bin/gp?pg=ijbfaq&pr=ssl"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Will using this as my Security Proxy compromise security?\r
-</h3>\r
-<p>\r
-We're not security experts, but we don't think so.\r
-The whole point of\r
-<small>SSL</small>\r
-is that the\r
-contents of messages are\r
-<!-- IEM: http://addy.com/dc/html/what_is_ssl_.html -->\r
-encrypted\r
-by the time\r
-they leave the browser and the server.\r
-Eavesdroppers (including proxies) can see where your messages are going\r
-whether you are running a proxy or not,\r
-but they only get to see the contents after they have been encrypted.\r
-</p>\r
-\r
-<h3><a name="restrict" href="/cgi-bin/gp?pg=ijbfaq&pr=restrict"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Can I restrict use of the proxy to a set of nominated IP addresses?\r
-</h3>\r
-<p>\r
-Yes, we added an\r
-<a href="ijbman.html#aclfile">access control</a>\r
-file in Version 2.0.\r
-But before you use it please consider why you want to do it.\r
-If the reason is security,\r
-it probably means you need a firewall.\r
-<p>\r
-<a name="selective">The</a>\r
-<a href="ijbman.html#listen-address">listen-address</a>\r
-option provides a way of binding the proxy to a single IP address/port.\r
-The right way to do this is to choose a port inside your firewall, and\r
-deny access to it to those outside the firewall.\r
-The\r
-Internet Junkbuster\r
-is not a firewall proxy;\r
-it should not be expected to solve security problems.\r
-<p>\r
-<a name="firewall">For background information on firewalls,</a>\r
-see\r
-<a href="http://www.yahoo.com/Computers_and_Internet/Security_and_Encryption/Firewalls/">Yahoo</a>\r
-or a\r
-<a href="http://www.netscapeworld.com/ned-02-1998/ned-02-firewall.html">magazine article</a>\r
-or these well-known books:\r
-<a href="http://www.amazon.com/exec/obidos/ISBN=0201633574/junkbusterscomA/"><cite>Firewalls and Internet Security: Repelling the Wily Hacker</cite></a>\r
-by\r
-<person>William R. Cheswick</person>\r
-and\r
-<person>Steven M. Bellovin</person>\r
-or\r
-<a href="http://www.amazon.com/exec/obidos/ISBN=1565921240/junkbusterscomA/"><cite>Building Internet Firewalls</cite></a>\r
-by\r
-<person>D. Brent Chapman</person>\r
-and\r
-<person>Elizabeth D. Zwicky</person>.\r
-There's\r
-<!-- IEM: http://www.wmd.de/wmd/staff/pauck/misc/fwtk_on_linux.html -->\r
-free Linux software\r
-available,\r
-and a large number of\r
-<a href="http://www.yahoo.com/Business_and_Economy/Companies/Computers/Software/System_Utilities/Security/Firewalls/">commercial</a>\r
-products and services.\r
-For an excellent security overview, primer, and compendium reference, see\r
-<a href="http://www.amazon.com/exec/obidos/ISBN=1565921488/junkbusterscomA/"><cite>Practical Unix and Internet Security</cite></a>\r
-by\r
-<person>Simson Garfinkel</person>\r
-and\r
-<person>Gene Spafford</person>.\r
-</p>\r
-\r
-<h3><a name="others" href="/cgi-bin/gp?pg=ijbfaq&pr=others"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Are there any security risks for ISPs or others who offer the proxy?\r
-</h3>\r
-<p>\r
-Yes.\r
-As with any service offered over the Internet,\r
-hackers can try to misuse it.\r
-A well-run\r
-<small>ISP</small>\r
-will have professionals who are experienced at assessing and containing\r
-these risks.\r
-<p>\r
-<a name="outside">It's possible to set up your machine so</a>\r
-that other people can have access to your proxy,\r
-but if you lack expertise in computer security\r
-you probably shouldn't have your computer configured to offer\r
-this or any other service to the outside world.\r
-<p>\r
-<a name="attack">Hackers can attempt to gain access</a>\r
-to the machine by various attacks,\r
-which we have tried to guard against but don't guarantee to thwart.\r
-They can also use the ``anonymizing'' quality of proxies\r
-to try to cover their tracks while hacking other computers.\r
-For this reason we recommend preventing it being used\r
-as an anonymous\r
-<big><kbd>telnet</kbd></big>\r
-by putting the pattern\r
-<big><kbd>:23</kbd></big>\r
-in the blockfile (it's included as standard equipment).\r
-(Actually the current implementation incidentally blocks telnet due to the\r
-way headers are handled, but it's best not to rely on this.)\r
-If you wish to block all ports except the default\r
-<small>HTTP</small>\r
-port 80,\r
-you can put the lines\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>:</kbd></big>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>~:80</kbd></big>\r
-<br>\r
-at the beginning of the blockfile, but be aware that some servers\r
-run on non-default ports (e.g. 8080). You might also want to add the line\r
-<big><kbd>~:443</kbd></big>\r
-to allow\r
-<small>SSL</small>.\r
-<p>\r
-<a name="root">On</a>\r
-<small>UNIX <a href="legal.html#not_our_trademark">&#174;</a></small>\r
-systems it is neither necessary nor desirable for the proxy to run as root.\r
-<p>\r
-<a name="patched">Versions 2.0.1 and below may be vulnerable to remote</a>\r
-exploitation of a memory buffer bug; for security reasons all users\r
-are encouraged to\r
-<a href="ijbdist.html#upgrade">upgrade.</a>\r
-<p>\r
-<a name="holes">If you find any security holes in the code</a>\r
-please\r
-<a href="/cgi-bin/gp?pg=ijbfaq&pr=holes">tell us,</a>\r
-along with any suggestions you may have for fixing it.\r
-However, we do not claim that we will be able to do so.\r
-<p>\r
-<a name="useful">We distribute this code in the hope that people</a>\r
-will find it useful, but we provide\r
-<a href="ijbfaq.html#free">no warranty</a>\r
-for it,\r
-and we are not responsible for anyone's use or misuse of it.\r
-<p>\r
-<a name="updates">You may also want to check back periodically for updated versions of the code.</a>\r
-We do not\r
-maintain a mailing list.\r
-To get quick updates, bookmark our\r
-<a href="ijbdist.html#versions">Distribution Information</a>\r
-page.\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<font face="arial, helvetica">\r
-<a rel="begin" href="index.html">Home</a> <font color="#ff0000">\r
-<b> &#183; </b></font>\r
-<a rel="next" href="ijbman.html">Next</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="lopt.html">Site Map</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="legal.html">Legal</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkdata.html">Privacy</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="cookies.html">Cookies</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="ijb.html">Banner Ads</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="telemarketing.html">Telemarketing</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkmail.html">Mail</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkemail.html">Spam</a>\r
-\r
-</font><form action="/cgi-bin/search" method="GET">\r
-<input type="text" name="q" size=60 maxlength=120 value="">\r
-<input type="submit" value="Search"></form>\r
-<small>\r
-<small>\r
-<p>\r
-<a href="legal.html#copy">Copyright</a> &#169; 1996-8 Junkbusters\r
-<a href="legal.html#marks">&#174;</a> Corporation.\r
-Copying and distribution permitted under\r
-the <a href="gpl.html"><small>GNU</small></a>\r
-General Public License.\r
-</small>\r
-<tt>\r
-1998/10/31\r
-http://www.junkbusters.com/ht/en/ijbfaq.html\r
-</tt>\r
-<address><kbd>webmaster&#64;junkbusters.com</kbd></address>\r
-</small>\r
-</body>\r
-</html>\r
diff --git a/doc/ijbman.html b/doc/ijbman.html
deleted file mode 100644 (file)
index 710cddb..0000000
+++ /dev/null
@@ -1,920 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">\r
-<html>\r
-<head>\r
-<!-- Copyright 1996-8 Junkbusters Corporation -->\r
-<!-- This work comes with NO WARRANTY -->\r
-<!-- It may be redistributed and modified under the GNU GPL-->\r
-<!-- See the body of http://www.junkbusters.com/ht/en/gpl.html for details-->\r
-<!-- Junkbusters is a registered trade mark of Junkbusters Corporation -->\r
-<!-- Generated 1998/10/31 03:58:25 UTC -->\r
-<meta name="Generator" content="Junkbusters Ebira $Revision: 1.1 $ $Date: 2001/04/16 21:10:38 $">\r
-<!-- Document  ID: $Revision: 1.1 $ $Date: 2001/04/16 21:10:38 $ -->\r
-<title>\r
-Internet Junkbuster Technical Information\r
-</title>\r
-<base href="http://www.junkbusters.com/ht/en/ijbman.html">\r
-<meta name="description" content="The manual page for the Internet Junkbuster, free software to removes banner ads, cookies, and other stuff you don't want from your web browser.">\r
-<meta name="keywords" content="stop, junk, busters, junkbusters, junkbuster, mail, email, e-mail, direct, spam, spamoff, declare, telemarketing, telemarketers, privacy, sharing, names, renting, direct, marketing, database, databases, junk mail, lists, environment, conservation, recycling, catalogs, consumer, sending, opt out ">\r
-<link rel="next" href="cookies.html">\r
-<link rel="previous" href="ijbfaq.html">\r
-<link rel="contents" href="toc.html">\r
-</head>\r
-<body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink="#787878">\r
-<center>\r
-<h1><a name="top_of_page">Internet J<small>UNK<i><font color=red>BUSTER</font></i></small> Technical Information\r
-</a></h1>\r
-</center>\r
-<font face="arial, helvetica">\r
-<p align="center">\r
-<a href="#description">Options</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#show">Checking Options</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#install">Installation</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="#copyright">Copyright</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="ijbfaq.html#top_of_page">(FAQ)</a>\r
-</p>\r
-</font><br>\r
-<center>\r
-<h2><a name="man"><font face="arial, helvetica">\r
-Manual Page\r
-</font></a>\r
-</h2>\r
-</center>\r
-<br>A copy of this page\r
-in standard\r
-<big><kbd>man</kbd></big>\r
-macro format\r
-is included in the\r
-<a href="ijbfaq.html#tar">tar archive</a>.\r
-\r
-<h3><a name="name" href="/cgi-bin/gp?pg=ijbman&pr=name"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Name\r
-</h3>\r
-<p>\r
-<b><kbd>junkbuster</kbd></b>\r
-- The\r
-Internet Junkbuster\r
-Proxy\r
-<a href="legal.html#marks"><small><sup>TM</sup></small></a>\r
-</p>\r
-\r
-<h3><a name="synopsis" href="/cgi-bin/gp?pg=ijbman&pr=synopsis"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Synopsis\r
-</h3>\r
-<p>\r
-<b><kbd>junkbuster</kbd></b>\r
-<i>configfile</i>\r
-(Version 2.0 onwards)\r
-<br>\r
-<b><kbd>junkbstr.exe</kbd></b>\r
-<i>configfile</i>\r
-(Windows)\r
-<br>\r
-<b><kbd>junkbuster</kbd></b>\r
-<a href="#o_a">[-a]</a>\r
-<a href="#o_y">[-y]</a>\r
-<a href="#o_s">[-s]</a>\r
-<a href="#o_c">[-c]</a>\r
-<a href="#o_v">[-v]</a>\r
-<br>\r
-<a href="#o_u">[-u user_agent]</a>\r
-<a href="#o_r">[-r referer]</a>\r
-<a href="#o_t">[-t from]</a>\r
-<br>\r
-<a href="#o_b">[-b blockfile]</a>\r
-<a href="#o_j">[-j jarfile]</a>\r
-<a href="#o_l">[-l logfile]</a>\r
-<br>\r
-<a href="#o_w">[-w NAME=VALUE]</a>\r
-<a href="#o_x">[-x Header_text]</a>\r
-<br>\r
-<a href="#o_h">[-h [bind_host_address][:bind_port]]</a>\r
-<br>\r
-<a href="#o_f">[-f forward_host[:port]]</a>\r
-<a href="#o_d">[-d N]</a>\r
-<br>\r
-<a href="#o_g">[-g gw_protocol[:[gw_host][:gw_port]]]</a>\r
-<br>\r
-(Version 1.4 and earlier)\r
-</p>\r
-\r
-<h3><a name="description" href="/cgi-bin/gp?pg=ijbman&pr=description"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Description\r
-</h3>\r
-<p>\r
-<b><kbd>junkbuster</kbd></b>\r
-is an instrumentable proxy that filters the \r
-<small>HTTP</small>\r
-stream between\r
-web servers and browsers.\r
-Its main purpose is to enhance privacy.\r
-<p>\r
-<a name="dual">Versions before 2.0 used command-line options;</a>\r
-Versions from 2.0 onward use a configuration file.\r
-The following descriptions of the options first give the older\r
-command-line usage, then the new configfile line.\r
-<p>\r
-<a name="won">In Versions 2.0.1 upwards on Windows,</a>\r
-a start-up message is printed and the configuration is read from the file\r
-<big><kbd>junkbstr.ini</kbd></big>\r
-if it exists and no argument was given.\r
-<p>\r
-<a name="reread">All files except the configfile</a>\r
-are checked for changes before each page is fetched,\r
-so they may edited without restarting the proxy.\r
-<h4>Options\r
-</h4>\r
-<dl><p><dt><i><a name="o_b">-b blockfile</a></i><br><a name="blockfile"><tt>blockfile</tt>&#160;&#160;<i>blockfile</i></a><dd>\r
-<a href="ijbfaq.html#blocking">Block</a>\r
-requests to\r
-<small>URL</small>s\r
-matching any pattern given in the lines of the\r
-<i>blockfile</i>.\r
-The\r
-<b><kbd>junkbuster</kbd></b>\r
-instead returns status 202, indicating that the request has been accepted\r
-(though not completed),\r
-and a\r
-<a href="ijbfaq.html#show">message identifying itself</a>\r
-(though the browser may\r
-display only a broken image icon).\r
-(Versions before 2.0 returned an error 403 (Forbidden).)\r
-The syntax of a pattern is\r
-<big><kbd>[domain][:port][/path]</kbd></big>\r
-(the\r
-<big><kbd>http://</kbd></big>\r
-or\r
-<big><kbd>https://</kbd></big>\r
-protocol part is omitted).\r
-To decide if a pattern matches a target, the domains are compared first,\r
-then the paths. \r
-<p>\r
-<a name="compare">To compare the domains,</a>\r
-the pattern domain and the target\r
-domain specified in the\r
-<small>URL</small>\r
-are each broken into their components.\r
-(Components are separated by the\r
-<big><kbd>.</kbd></big>\r
-(period) character.)\r
-Next each of the target components\r
-is compared with the corresponding pattern component: last with last,\r
-next-to-last with next-to-last, and so on.\r
-(This is called\r
-<i><dfn>right-anchored</dfn></i>\r
-matching.)\r
-If all of the pattern components find their match in the target,\r
-then the domains are considered a match.\r
-Case is irrelevant when comparing domain components.\r
-<p>\r
-<a name="substring">A successfully</a>\r
-matching pattern can be an anchored substring of a target, but\r
-not vice versa.\r
-Thus if a pattern doesn't specify a domain,\r
-it matches all domains.\r
-<a name="wildcard">Furthermore, when comparing two components,</a>\r
-the components must either match in their entirety or up to a wildcard\r
-<big><kbd>* </kbd></big>\r
-(star character) in the pattern.  The wildcard feature\r
-implements only a "prefix" match capability ("abc*" vs. "abcdefg"),\r
-not suffix matching ("*efg" vs. "abcdefg") or\r
-infix matching ("abc*efg" vs. "abcdefg").\r
-The feature is restricted to the domain component;\r
-it is unrelated to the optional\r
-regular expression\r
-feature in the path\r
-<a href="ijbman.html#regex">(described below).</a>\r
-<p>\r
-<a name="numeric">If a numeric port</a>\r
-is specified in the pattern domain, then the target port must\r
-match as well.  The default port in a target is port 80.\r
-<p>\r
-<a name="onward">If the domain and port match,</a>\r
-then the target\r
-<small>URL</small>\r
-path is checked for\r
-a match against the path in the pattern.\r
-Paths are compared with a simple case-sensitive\r
-left-anchored substring comparison.\r
-Once again, the pattern can be an\r
-anchored substring of the target, but not vice versa.\r
-A path of\r
-<big><kbd>/</kbd></big>\r
-(slash) would match all paths.  Wildcards are not considered in\r
-path comparisons.\r
-<p>\r
-<a name="example">For example, the target</a>\r
-<small>URL</small>\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>the.yellow-brick-road.com/TinMan/has_no_brain</kbd></big>\r
-<br>\r
-would be matched (and blocked) by the following patterns\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>yellow-brick-road.com</kbd></big>\r
-<br>\r
-and\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>Yellow*.COM</kbd></big>\r
-<br>\r
-and\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>/TinM</kbd></big>\r
-<br>\r
-but not\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>follow.the.yellow-brick-road.com</kbd></big>\r
-<br>\r
-or\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>/tinman</kbd></big>\r
-<br>\r
-<p>\r
-<a name="comments">Comments in a blockfile start with a</a>\r
-<big><kbd>#</kbd></big>\r
-(hash) character and end at a new line.\r
-Blank lines are also ignored.\r
-<p>\r
-<a name="except">Lines beginning with a</a>\r
-<big><kbd>~</kbd></big>\r
-(tilde) character are taken to be\r
-<a href="ijbfaq.html#exceptions">exceptions:</a>\r
-a\r
-<small>URL</small>\r
-blocked by previous patterns that matches the rest of\r
-the line is let through. (The last match wins.)\r
-<p>\r
-<a name="regex">Patterns</a>\r
-may contain\r
-<small>POSIX</small>\r
-<a href="ijbfaq.html#regex">regular expressions</a>\r
-provided the\r
-<b><kbd>junkbuster</kbd></b>\r
-was compiled with this option\r
-(the default in Version 2.0 on).\r
-The idiom\r
-<big><kbd>/*.*/ad</kbd></big>\r
-can then be used\r
-to match any\r
-<small>URL</small>\r
-containing\r
-<big><kbd>/ad</kbd></big>\r
-(such as\r
-<big><kbd>http://nomatterwhere.com/images/advert/g3487.gif</kbd></big>\r
-for example).\r
-These expressions\r
-<a href="ijbman.html#substring">don't work</a>\r
-in the domain part.\r
-<p>\r
-<a name="rereads">In version 1.3 and later</a>\r
-the blockfile and cookiefile are checked for changes before each request.\r
-<p><dt><i><a name="o_w">-w NAME=VALUE</a></i><br><a name="wafer"><tt>wafer</tt>&#160;&#160;<i>NAME=VALUE</i></a><dd>\r
-Specifies a pair to be sent as a cookie with every request\r
-<a href="ijbfaq.html#wafers">to the server.</a>\r
-(Such boring cookies are called\r
-<i>wafers</i>.)\r
-This option may be called more than once to generate multiple wafers.\r
-The original\r
-Netscape specification\r
-prohibited\r
-semi-colons, commas and white space;\r
-these characters will be\r
-<small>URL</small>-encoded\r
-if used in wafers.\r
-<!-- Aside: genuine cookies are not encoded -->\r
-<!-- Aside: we could use quoted string as specified in the new RFC -->\r
-The Path and Domain attributes are not currently supported.\r
-<p><dt><i><a name="o_c">-c cookiefile</a></i><br><a name="cookiefile"><tt>cookiefile</tt>&#160;&#160;<i>cookiefile</i></a><dd>\r
-Enforce the cookie management policy specified in the\r
-<i>cookiefile.</i>\r
-<a name="java">If this option is not used all cookies are silently crunched,</a>\r
-so that users who never want cookies aren't bothered by browsers\r
-asking whether each cookie should be accepted.\r
-However, cookies can\r
-<a href="ijbfaq.html#breakthrough">still get through</a>\r
-via\r
-<a href="links.html#javascript">JavaScript</a>\r
-and\r
-<small>SSL</small>,\r
-so alerts should be left on.\r
-<p>\r
-<a name="dropping">In Version 1.2 and later</a>\r
-this option must be followed by a\r
-<a href="ijbfaq.html#crumble">filename</a>\r
-containing instructions on which sites are allowed to\r
-receive and set cookies.\r
-<a name="drop">By default cookies are dropped in both the browser's request</a>\r
-and the server's response, unless the\r
-<small>URL</small>\r
-requested matches an entry in the\r
-<i>cookiefile</i>.\r
-The matching algorithm is the same as for the blockfile.\r
-A leading\r
-<big><kbd>&gt;</kbd></big>\r
-character allows\r
-<a href="ijbfaq.html#directional">server-bound</a>\r
-cookies only;\r
-a\r
-<big><kbd>&lt;</kbd></big>\r
-allows only browser-bound cookies;\r
-a\r
-<big><kbd>~</kbd></big>\r
-character stops cookies in\r
-<a href="ijbfaq.html#crumble">both directions.</a>\r
-Thus a cookiefile containing a single line with the two characters\r
-<big><kbd>&gt;*</kbd></big>\r
-will pass on all cookies to servers but not give any new ones to the browser.\r
-<p><dt><i><a name="o_j">-j jarfile</a></i><br><a name="jarfile"><tt>jarfile</tt>&#160;&#160;<i>jarfile</i></a><dd>\r
-All Set-cookie attempts by the server are\r
-<a href="ijbfaq.html#jar">logged</a>\r
-to\r
-<i>jarfile</i>.\r
-If no wafer is specified,\r
-one containing a\r
-<a href="ijbfaq.html#notice">canned notice</a>\r
-(the \r
-<i>vanilla wafer</i>)\r
-is added as an alert to the server\r
-unless the\r
-<a href="ijbman.html#suppress-vanilla-wafer">suppress-vanilla-wafer</a>\r
-<!-- Aside: (no vanilla~wafer) -->\r
-option is invoked.\r
-<p><dt><i><a name="o_v">-v</a></i><br><a name="suppress-vanilla-wafer"><tt>suppress-vanilla-wafer</tt></a><dd>\r
-Suppress the vanilla wafer.\r
-<p><dt><i><a name="o_t">-t from</a></i><br><a name="from"><tt>from</tt>&#160;&#160;<i>from</i></a><dd>\r
-If the browser\r
-<a href="ijbfaq.html#from">discloses an email address</a>\r
-in the\r
-<big><kbd>FROM</kbd></big>\r
-header (most don't),\r
-replace it with\r
-<i>from.</i>\r
-If\r
-<i>from</i>\r
-is set to\r
-<b>.</b>\r
-(the period character)\r
-the\r
-<big><kbd>FROM</kbd></big>\r
-is passed to the server unchanged.\r
-The default is to delete the\r
-<big><kbd>FROM</kbd></big>\r
-header.\r
-<p><dt><i><a name="o_r">-r referer</a></i><br><a name="referer"><tt>referer</tt>&#160;&#160;<i>referer</i></a><dd>\r
-Whenever the browser discloses the\r
-<small>URL</small>\r
-that\r
-<a href="ijbfaq.html#referer">led to</a>\r
-the current request,\r
-replace it with\r
-<i>referer.</i>\r
-If\r
-<i>referer</i>\r
-is set to\r
-<b>.</b>\r
-(period)\r
-the \r
-<small>URL</small>\r
-is passed to the server unchanged.\r
-In \r
-Version <a href="ijbdist.html#c4">1.4</a>\r
-and later, if referer is set to \r
-<b>@</b>\r
-(at) the\r
-<small>URL</small>\r
-is sent in cases where the cookiefile\r
-specifies that a cookie would be sent.\r
-(No way to send bogus referers selectively is provided.)\r
-The default is to delete Referer.\r
-<p>\r
-<a name="referrer">Version 2.0 also accepts the spelling</a>\r
-<big><kbd>referrer</kbd></big>,\r
-which most dictionaries consider correct.\r
-<p><dt><i><a name="o_u">-u user-agent</a></i><br><a name="user-agent"><tt>user-agent</tt>&#160;&#160;<i>user-agent</i></a><dd>\r
-Information disclosed by the browser\r
-<a href="ijbfaq.html#agent">about itself</a>\r
-is replaced with the value\r
-<i>user-agent.</i>\r
-If\r
-<i>user-agent</i>\r
-is set to\r
-<b>.</b>\r
-(period)\r
-the\r
-<big><kbd>User-Agent</kbd></big>\r
-header is passed to the server unchanged,\r
-along with any\r
-<big><kbd>UA</kbd></big>\r
-headers produced by\r
-<small>MS-IE</small>\r
-(which would otherwise be deleted).\r
-In \r
-Version <a href="ijbdist.html#c4">1.4</a>\r
-and later, if\r
-<i>user-agent</i>\r
-is set to\r
-<b>@</b>\r
-(at) these headers are sent unchanged in cases where the cookiefile\r
-specifies that a cookie would be sent,\r
-otherwise only default\r
-<big><kbd>User-Agent</kbd></big>\r
-header is sent.\r
-That default\r
-is Mozilla/3.0 (Netscape)\r
-with an unremarkable\r
-<a href="ijbfaq.html#infer">Macintosh</a>\r
-configuration.\r
-If used with a browser less advanced than Mozilla/3.0 or IE-3, the default\r
-may encourage pages containing extensions that confuse the browser.\r
-<!-- Aside: Some servers use extensions to everyone anyway.  But in that case it's probably ignoring cookies anyway.  Some servers attempt to send cookies only to browsers identifying themselves as Mozilla. -->\r
-<p><dt><i><a name="o_h">-h [host][:port]</a></i><br><a name="listen-address"><tt>listen-address</tt>&#160;&#160;<i>[host][:port]</i></a><dd>\r
-If\r
-<i>host</i>\r
-is specified,\r
-bind the\r
-<b><kbd>junkbuster</kbd></b>\r
-to that\r
-<small>IP</small>\r
-address.\r
-If a\r
-<i>port</i>\r
-is specified, use it.\r
-The default\r
-port\r
-is 8000;\r
-the default host is\r
-<big><kbd>localhost</kbd></big>.\r
-Before Version 2.0.2,\r
-the default was to bind to all \r
-<small>IP</small>\r
-addresses\r
-(<big><kbd>INADDR_ANY</kbd></big>);\r
-but this has been restricted to\r
-<big><kbd>localhost</kbd></big>\r
-to avoid unintended security breaches.\r
-(To open the proxy to all, use the line\r
-<br>\r
-&#160;&#160;&#160;<big><kbd>listen-address :8000</kbd></big>\r
-<br>\r
-in the configuration file.)\r
-<p><dt><i><a name="o_f">-f forward_host[:port]</a></i><br><a name="forwardfile"><tt>forwardfile</tt>&#160;&#160;<i>forwardfile</i></a><dd>\r
-Version 1.X required all\r
-<small>HTTP</small>\r
-requests from the client to be forwarded to the same destination.\r
-Version 2.0 takes its routing specification from a\r
-<i>forwardfile</i>,\r
-allowing selection of the proxy (a.k.a. forwarding host) and gateway\r
-according to the\r
-<small>URL</small>.\r
-Here is a typical line.\r
-<br>\r
-<pre>\r
-*         lpwa.com:8000      .      .\r
-</pre>\r
-<p>\r
-<a name="lines">Each line contains four fields:</a>\r
-<big><kbd>target</kbd></big>,\r
-<big><kbd>forward_to</kbd></big>,\r
-<big><kbd>via_gateway_type</kbd></big>\r
-and\r
-<big><kbd>gateway</kbd></big>.\r
-As usual, the\r
-<a href="ijbman.html#compare">last</a>\r
-<big><kbd>target</kbd></big>\r
-domain that matches the requested\r
-<small>URL</small>\r
-wins,\r
-and the\r
-<big><kbd>*</kbd></big>\r
-character alone matches any domain.\r
-The target domain need not be a fully qualified\r
-hostname; it can be a general domain such as\r
-<big><kbd>com</kbd></big>\r
-or\r
-<big><kbd>co.uk</kbd></big>\r
-or even just a port number.\r
-<a name="nose">For example, because</a>\r
-<a href="http://lpwa.com">LPWA</a>\r
-does not handle\r
-<a href="ijbfaq.html#encrypt">SSL</a>,\r
-the line above will typically be followed by a line such as\r
-<br>\r
-<pre>\r
-:443  .      .      .\r
-</pre>\r
-to allow SSL transactions to proceed directly.\r
-The cautious would also\r
-add an entry in their blockfile to stop transactions\r
-to port 443 for all but specified trusted sites.\r
-<p>\r
-<a name="forward">If the winning</a>\r
-<big><kbd>forward_to</kbd></big>\r
-field is\r
-<big><kbd>.</kbd></big>\r
-(the dot character) the proxy connects \r
-directly to the server given in the\r
-<small>URL</small>,\r
-otherwise it forwards to the host and port number specified.\r
-The default port is 8000.\r
-The\r
-<big><kbd>via_gateway_type</kbd></big>\r
-and\r
-<big><kbd>gateway</kbd></big>\r
-fields also use a dot to indicate no gateway protocol.\r
-The gateway protocols are explained\r
-<a href="ijbman.html#o_g">below</a>.\r
-<p>\r
-<a name="old">The example line above in a forwardfile alone</a>\r
-would send everything through port 8000 at\r
-<big><kbd>lpwa.com</kbd></big>\r
-with no gateway protocol,\r
-and is equivalent to the old\r
-<big><kbd>-f lpwa.com:8000</kbd></big>\r
-with no\r
-<big><kbd>-g</kbd></big>\r
-option.\r
-For more information see the example file provided with the distribution.\r
-<p>\r
-<a name="loop">Configure with care: no loop detection is performed.</a>\r
-When setting up chains of proxies that might loop back, try adding\r
-<a href="ijbman.html#squid">Squid.</a>\r
-<p><dt><i><a name="o_g">-g gw_protocol[:[gw_host][:gw_port]]</a></i><dd>\r
-Use\r
-<i>gw_protocol</i>\r
-as the gateway protocol.\r
-This option was introduced in Version 1.4,\r
-but was folded into the\r
-<a href="ijbman.html#forwardfile">forwardfile</a>\r
-option in Version 2.0.\r
-The default is to use no gateway protocol;\r
-this may be explicitly specified as\r
-<big><kbd>direct</kbd></big>\r
-on the command line\r
-or the dot character in the forwardfile.\r
-The\r
-<big><kbd>SOCKS4</kbd></big>\r
-protocol may be specified as\r
-<big><kbd>socks</kbd></big>\r
-or\r
-<big><kbd>socks4</kbd></big>.\r
-The\r
-<big><kbd>SOCKS4A</kbd></big>\r
-protocol is specified as\r
-<big><kbd>socks4a</kbd></big>.\r
-The\r
-<big><kbd>SOCKS5</kbd></big>\r
-protocol is not currently supported.\r
-The default\r
-<small>SOCKS</small>\r
-<i>gw_port</i>\r
-is 1080.\r
-<p>\r
-<a name="configure">The user's browser should</a>\r
-<em>not</em>\r
-be\r
-<a href="ijbfaq.html#socks">configured</a>\r
-to use\r
-<big><kbd>SOCKS</kbd></big>;\r
-the proxy conducts the negotiations, not the browser.\r
-<p>\r
-<a name="identify">The user identification capabilities of</a>\r
-<big><kbd>SOCKS4</kbd></big>\r
-are deliberately not used;\r
-the user is always identified to the\r
-<big><kbd>SOCKS</kbd></big>\r
-server as\r
-<big><kbd>userid=anonymous</kbd></big>.\r
-If the server's policy is to reject requests from\r
-<big><kbd>anonymous</kbd></big>,\r
-the proxy will not work.\r
-Use a\r
-<a href="ijbman.html#o_d">debug</a>\r
-value of 3\r
-to see the status returned by the server.\r
-<p><dt><i><a name="o_d">-d N</a></i><br><a name="debug"><tt>debug</tt>&#160;&#160;<i>N</i></a><dd>\r
-Set debug mode.\r
-The most common value is 1,\r
-to\r
-<a href="ijbfaq.html#pinpoint">pinpoint</a>\r
-offensive\r
-<small>URL</small>s,\r
-so they can be added to the blockfile.\r
-The value of\r
-<b>N</b>\r
-is a bitwise\r
-logical-<small>OR</small>\r
-of the following values:\r
-<br>\r
-1 =  URLs (show each URL requested by the browser);<br>\r
-2 =  Connections (show each connection to or from the proxy);<br>\r
-4 =  I/O (log I/O errors);<br>\r
-8 =  Headers (as each header is scanned, show the header and what is done to it);<br>\r
-16 =  Log everything (including debugging traces and the contents of the pages).<br>\r
-<a name="or">Multiple</a>\r
-<big><kbd>debug</kbd></big>\r
-lines are permitted; they are logical OR-ed together.\r
-<p>\r
-<a name="single">Because most browsers send several requests in parallel</a>\r
-the debugging output may appear intermingled, so the\r
-<a href="ijbman.html#single-threaded">single-threaded</a>\r
-option is recommended when using\r
-<a href="ijbman.html#debug">debug</a>\r
-with\r
-<b>N</b>\r
-greater than 1.\r
-<!-- Aside: Yes, it's clumsy, but it's easy to parse. -->\r
-<p><dt><i><a name="o_y">-y</a></i><br><a name="add-forwarded-header"><tt>add-forwarded-header</tt></a><dd>\r
-Add \r
-<big><kbd>X-Forwarded-For</kbd></big>\r
-headers to the server-bound \r
-<small>HTTP</small>\r
-stream\r
-indicating the client \r
-<small>IP</small>\r
-address\r
-<a href="ijbfaq.html#detect">to the server,</a>\r
-in the new style of\r
-<a href="ijbman.html#squid">Squid 1.1.4.</a>\r
-If you want the traditional\r
-<big><kbd>HTTP_FORWARDED</kbd></big>\r
-response header, add it manually with the\r
-<a href="ijbman.html#o_x">-x</a>\r
-option.\r
-<!-- Aside: Not a default, since the end-client usually doesn't wish to be identified, but may be helpful in debugging chains. -->\r
-<p><dt><i><a name="o_x">-x HeaderText</a></i><br><a name="add-header"><tt>add-header</tt>&#160;&#160;<i>HeaderText</i></a><dd>\r
-Add the\r
-<i>HeaderText</i>\r
-verbatim to requests to the server.\r
-Typical uses include\r
-adding old-style forwarding notices such as\r
-<big><kbd>Forwarded: by http://pro-privacy-isp.net</kbd></big>\r
-and reinstating the\r
-<big><kbd>Proxy-Connection: Keep-Alive</kbd></big>\r
-header\r
-(which the\r
-<b><kbd>junkbuster</kbd></b>\r
-deletes so as\r
-<a href="ijbfaq.html#detect">not</a>\r
-to reveal its existence).\r
-No checking is done for correctness or plausibility,\r
-so it can be used to throw any old trash into the server-bound \r
-<small>HTTP</small>\r
-stream.\r
-Please don't litter.\r
-<!-- Aside: this represents "more than enough rope" -->\r
-<p><dt><i><a name="o_s">-s</a></i><br><a name="single-threaded"><tt>single-threaded</tt></a><dd>\r
-Doesn't\r
-<big><kbd>fork()</kbd></big>\r
-a separate process\r
-(or create a separate thread)\r
-to handle each connection.\r
-Useful when debugging to keep the process single threaded.\r
-<p><dt><i><a name="o_l">-l logfile</a></i><br><a name="logfile"><tt>logfile</tt>&#160;&#160;<i>logfile</i></a><dd>\r
-Write all debugging data into\r
-<i>logfile.</i>\r
-The default\r
-<i>logfile</i>\r
-is the standard output.\r
-<p><dt><br><a name="aclfile"><tt>aclfile</tt>&#160;&#160;<i>aclfile</i></a><dd>\r
-Unless this option is used, the proxy talks to anyone who can connect to it,\r
-and everyone who can has equal permissions on where they can go.\r
-An access file allows restrictions to be placed on these two policies,\r
-by distinguishing some\r
-<i><dfn>source</dfn></i>\r
-<small>IP</small>\r
-addresses and/or\r
-some\r
-<i><dfn>destination</dfn></i>\r
-addresses.\r
-(If a\r
-<a href="ijbman.html#forwardfile">forwarder or a gateway</a>\r
-is being used, its address is considered the destination address,\r
-not the ultimate\r
-<small>IP</small>\r
-address of the\r
-<small>URL</small>\r
-requested.)\r
-<p>\r
-<a name="permit">Each line of the access file begins with</a>\r
-either the word\r
-<big><kbd>permit</kbd></big>\r
-or\r
-<big><kbd>deny</kbd></big>\r
-followed by source and (optionally) destination addresses \r
-to be matched against those of the\r
-<small>HTTP</small>\r
-request.\r
-The last matching line specifies the result: if it was a\r
-<big><kbd>deny</kbd></big>\r
-line or if no line matched,\r
-the request will be refused.\r
-<p>\r
-<a name="various">A source or destination</a>\r
-can be specified as a single numeric\r
-<small>IP</small>\r
-address,\r
-or with a hostname, provided that the host's name\r
-can be resolved to a numeric address: this cannot be used to block all\r
-<big><kbd>.mil </kbd></big>\r
-domains for example,\r
-because there is no single address associated with that domain name.\r
-Either form may be followed by a slash and an integer\r
-<big><kbd>N</kbd></big>,\r
-specifying a subnet mask of\r
-<big><kbd>N</kbd></big>\r
-bits.\r
-For example,\r
-<big><kbd>permit 207.153.200.72/24</kbd></big>\r
-matches the entire Class-C subnet from\r
-207.153.200.0\r
-through 207.153.200.255.\r
-(A netmask of 255.255.255.0 corresponds to 24 bits of\r
-ones in the netmask, as with\r
-<big><kbd>*_MASKLEN=24</kbd></big>.)\r
-A value of 16 would be used for a Class-B subnet.\r
-A value of zero for\r
-<big><kbd>N</kbd></big>\r
-in the subnet mask length will cause any address to match;\r
-this can be used to express a default rule.\r
-For more information see the example file provided with the distribution.\r
-<p>\r
-<a name="false">If you like these access controls</a>\r
-you should probably have\r
-<a href="ijbfaq.html#firewall">firewall</a>;\r
-they are not intended to replace one.\r
-<p><dt><br><a name="trustfile"><tt>trustfile</tt>&#160;&#160;<i>trustfile</i></a><dd>\r
-This feature is experimental, has not been fully documented and is\r
-very subject to change.\r
-The goal is for parents to be able to choose a page or site whose\r
-links they regard suitable for their\r
-<a href="ijbfaq.html#children">young children</a>\r
-and for the proxy to allow access only to sites mentioned there.\r
-To do this the proxy examines the\r
-<a href="ijbman.html#o_r">referer</a>\r
-variable on each page request to check they resulted from\r
-a click on the ``trusted referer'' site: if so the referred site\r
-is added to a list of trusted sites, so that the child can\r
-then move around that site.\r
-There are several uncertainties in this scheme that experience may be\r
-able to iron out; check back in the months ahead.\r
-<p><dt><br><a name="trust_info_url"><tt>trust_info_url</tt>&#160;&#160;<i>trust_info_url</i></a><dd>\r
-When access is denied due to lack of a trusted referer, this\r
-<small>URL</small>\r
-is displayed with a message pointing the user to it for further information.\r
-<p><dt><br><a name="hide-console"><tt>hide-console</tt></a><dd>\r
-In the Windows version only, instructs the program\r
-to disconnect from and hide the command console after starting.\r
-<p><dt><i><a name="o_a">-a</a></i><dd>\r
-(Obsolete) Accept the server's\r
-<big><kbd>Set-cookie</kbd></big>\r
-headers, passing them through to the browser.\r
-<a name="obsolete">This option was removed in Version 1.2</a>\r
-and replaced by an improvement to the\r
-<a href="ijbman.html#o_c">-c</a>\r
-option.\r
-</dl>\r
-</p>\r
-\r
-<h3><a name="install" href="/cgi-bin/gp?pg=ijbman&pr=install"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Installation and Use\r
-</h3>\r
-<p>\r
-Browsers must be told where to find the\r
-<b><kbd>junkbuster</kbd></b>\r
-(e.g.\r
-<big><kbd>localhost</kbd></big>\r
-port 8000).\r
-To set the \r
-<small>HTTP</small>\r
-proxy in Netscape 3.0,\r
-go through:\r
-<b><font face="arial, helvetica">\r
-Options</font></b>;\r
-<b><font face="arial, helvetica">\r
-Network Preferences</font></b>;\r
-<b><font face="arial, helvetica">\r
-Proxies</font></b>;\r
-<b><font face="arial, helvetica">\r
-Manual Proxy Configuration</font></b>;\r
-<b><font face="arial, helvetica">\r
-View</font></b>.\r
-See the\r
-<a href="ijbfaq.html"><small>FAQ</small></a>\r
-for other browsers.\r
-The\r
-<a href="ijbfaq.html#security">Security Proxy</a>\r
-should also be set to the same values,\r
-otherwise\r
-<big><kbd>shttp:</kbd></big>\r
-<small>URL</small>s\r
-won't work.\r
-<p>\r
-<a name="limitations">Note the limitations</a>\r
-explained in the\r
-<a href="ijbfaq.html"><small>FAQ</small></a>.\r
-</p>\r
-\r
-<h3><a name="show" href="/cgi-bin/gp?pg=ijbman&pr=show"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Checking Options\r
-</h3>\r
-<p>\r
-To allow users to\r
-<a href="ijbfaq.html#show">check</a>\r
-that a\r
-<b><kbd>junkbuster</kbd></b>\r
-is running and how it is configured,\r
-it intercepts requests for any\r
-<small>URL</small>\r
-ending in\r
-<big><kbd>/show-proxy-args</kbd></big>\r
-and blocks it,\r
-returning instead returns information on its\r
-version number and\r
-current configuration\r
-including the contents of its blockfile.\r
-To get an explicit warning that no\r
-<b><kbd>junkbuster</kbd></b>\r
-intervened if the proxy was not configured,\r
-it's best to point it to a\r
-<small>URL</small>\r
-that does this, such as\r
-<a href="http://internet.junkbuster.com/cgi-bin/show-proxy-args">http://internet.junkbuster.com/cgi-bin/show-proxy-args</a>\r
-on Junkbusters's website.\r
-</p>\r
-\r
-<h3><a name="also" href="/cgi-bin/gp?pg=ijbman&pr=also"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-See Also\r
-</h3>\r
-<p>\r
-<a href="ijbfaq.html">http://www.junkbusters.com/ht/en/ijbfaq.html</a>\r
-<br>\r
-<a href="cookies.html">http://www.junkbusters.com/ht/en/cookies.html</a>\r
-<br>\r
-<a href="http://internet.junkbuster.com/cgi-bin/show-proxy-args">http://internet.junkbuster.com/cgi-bin/show-proxy-args</a>\r
-<br>\r
-<a name ="kristol" href="http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html">http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html</a>\r
-<br>\r
-<a name ="squid" href="http://squid.nlanr.net/Squid/">http://squid.nlanr.net/Squid/</a>\r
-<br>\r
-<a href="http://www-math.uni-paderborn.de/~axel/">http://www-math.uni-paderborn.de/~axel/</a>\r
-</p>\r
-\r
-<h3><a name="copyright" href="/cgi-bin/gp?pg=ijbman&pr=copyright"><img border=0 width=14 height=14 src="/images/fb.gif" alt="&lt;Feedback&gt"></a>&#160;\r
-Copyright and GPL\r
-</h3>\r
-<p>\r
-Written and copyright by the Anonymous Coders and Junkbusters Corporation\r
-and made available under the\r
-<a href="gpl.html">GNU General Public License (GPL).</a>\r
-This software comes with\r
-<a href="gpl.html#nowarr">NO WARRANTY.</a>\r
-Internet Junkbuster\r
-Proxy\r
-is a\r
-<a href="legal.html#marks">trademark</a>\r
-of Junkbusters Corporation.\r
-</p>\r
-<p align="center"><a href="#top_of_page"><img border=0 width=250 height=15 src="/images/top.gif" alt="--- Back to Top of Page ---"></a></p>\r
-<font face="arial, helvetica">\r
-<a rel="begin" href="index.html">Home</a> <font color="#ff0000">\r
-<b> &#183; </b></font>\r
-<a rel="next" href="cookies.html">Next</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="lopt.html">Site Map</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="legal.html">Legal</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkdata.html">Privacy</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="cookies.html">Cookies</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="ijb.html">Banner Ads</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="telemarketing.html">Telemarketing</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkmail.html">Mail</a>\r
-<font color="#ff0000">\r
-<b> &#183; </b></font><a href="junkemail.html">Spam</a>\r
-\r
-</font><form action="/cgi-bin/search" method="GET">\r
-<input type="text" name="q" size=60 maxlength=120 value="">\r
-<input type="submit" value="Search"></form>\r
-<small>\r
-<small>\r
-<p>\r
-<a href="legal.html#copy">Copyright</a> &#169; 1996-8 Junkbusters\r
-<a href="legal.html#marks">&#174;</a> Corporation.\r
-Copying and distribution permitted under\r
-the <a href="gpl.html"><small>GNU</small></a>\r
-General Public License.\r
-</small>\r
-<tt>\r
-1998/10/31\r
-http://www.junkbusters.com/ht/en/ijbman.html\r
-</tt>\r
-<address><kbd>webmaster&#64;junkbusters.com</kbd></address>\r
-</small>\r
-</body>\r
-</html>\r
diff --git a/doc/obsolete/fb.gif b/doc/obsolete/fb.gif
new file mode 100755 (executable)
index 0000000..4305992
Binary files /dev/null and b/doc/obsolete/fb.gif differ
diff --git a/doc/obsolete/ijbfaq.html b/doc/obsolete/ijbfaq.html
new file mode 100644 (file)
index 0000000..3d52247
--- /dev/null
@@ -0,0 +1,1999 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
+<!-- $Id: ijbfaq.html,v 1.2 2001/05/17 22:56:17 jongfoster Exp $\r
+\r
+     See copyright details at end of file\r
+\r
+     After changing this file, please run it through "HTML Tidy"\r
+     (from http://www.w3.org/People/Raggett/tidy/)\r
+     It should have no warnings or errors.\r
+-->\r
+\r
+<html>\r
+  <head>\r
+    <title>Internet Junkbuster Frequently Asked Questions</title>\r
+    <meta name="description" content=\r
+    "An extensive FAQ on the Internet Junkbuster, free software to removes banner ads, cookies, and other stuff you don't want from your web browser.">\r
+    <meta name="keywords" content=\r
+    "stop, junk, busters, junkbusters, junkbuster, mail, email, e-mail, direct, spam, privacy, sharing, names, renting, direct, marketing, database, databases, junk mail, lists, consumer, sending, opt out, privacy, advertising, direct, marketing, targeting, through, click, trails, http_referer, cookie, cutter, iff, internet fast forward, Cookie Management Tool">\r
+<style type="text/css">\r
+<!--\r
+h2           { text-align: Center; font-family: arial, helvetica, sans-serif }\r
+p.sans       { font-family: arial, helvetica, sans-serif }\r
+b.dot        { color: #FF0000 }\r
+b.eg         { font-family: arial, helvetica, sans-serif }\r
+-->\r
+</style>\r
+  </head>\r
+\r
+  <body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink=\r
+  "#787878">\r
+    <p class="sans"><a href="http://ijbswa.sourceforge.net">\r
+    Website</a> <b class="dot">&middot;</b> <a href="ijbman.html">\r
+    Manual</a> <b class="dot">&middot;</b> <b>FAQ</b> <b class=\r
+    "dot">&middot;</b> <a href="gpl.html">GPL</a></p>\r
+\r
+    <h1 align="center"><a name="top_of_page"></a>Internet\r
+    J<small>UNK<i style="color: #FF0000">BUSTER</i></small>\r
+    Frequently Asked Questions</h1>\r
+\r
+    <p align="center" class="sans"><a href="#browser">Configuring\r
+    Browsers</a> <b class="dot">&middot;</b> <a href="#defaulted">\r
+    IE 5.0</a> <b class="dot">&middot;</b> <a href="#local">\r
+    Installation</a> <b class="dot">&middot;</b> <a href=\r
+    "#companies">For Companies</a> <b class="dot">&middot;</b> <a\r
+    href="#blocking">Blocking Ads</a> <b class="dot">&middot;</b>\r
+    <a href="#cookies">Cookies</a> <b class="dot">&middot;</b> <a\r
+    href="#hotmail">Hotmail</a> <b class="dot">&middot;</b> <a\r
+    href="#children">Children</a> <b class="dot">&middot;</b> <a\r
+    href="#chain">Forwarding/Chaining</a> <b class="dot">\r
+    &middot;</b> <a href="#conceal">IP</a> <b class="dot">\r
+    &middot;</b> <a href="#anonymity">Anonymity</a> <b class="dot">\r
+    &middot;</b> <a href="#security">Security</a></p>\r
+\r
+    <h1>This document is out of date</h1>\r
+\r
+    <p><b>Development of JunkBuster is ongoing and this document is\r
+    no longer current. However, it may provide some assistance. If\r
+    you have problems, please use the <a href=\r
+    "http://groups.yahoo.com/group/junkbuster-users/">Yahoo Groups\r
+    mailing list</a> (which includes an archive of mail), the\r
+    SourceForge.net <a href=\r
+    "http://sourceforge.net/projects/ijbswa/">project page</a>, or\r
+    see the project's <a href="http://ijbswa.sourceforge.net/">home\r
+    page</a>. Please also bear in mind that versions 2.9.x of\r
+    JunkBuster are development releases, and are not production\r
+    quality.</b></p>\r
+\r
+    <h2><a name="top"></a>The Top Ten Questions</h2>\r
+\r
+    <h3><a name="what"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What is the Internet Junkbuster\r
+    Proxy and what does it do for me?</h3>\r
+\r
+    <p>The Internet Junkbuster Proxy <small><sup>TM</sup></small>\r
+    is free privacy-enhancing software that can be run on your PC\r
+    or by your ISP or company. It blocks requests for URLs\r
+    (typically banner ads) that match its blockfile. It also\r
+    deletes unauthorized cookies and other unwanted identifying\r
+    header information that is exchanged between web servers and\r
+    browsers. These headers are not normally accessible to users\r
+    (even though they may contain information that's important to\r
+    your privacy), but with the Internet Junkbuster you can see\r
+    almost <a href="ijbman.html#o_d">anything you want</a> and\r
+    control everything you're likely to need. Many people publish\r
+    their blockfiles to help others get started.</p>\r
+\r
+    <h3><a name="free"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Is there a license fee / warranty\r
+    / registration form / expiration?</h3>\r
+\r
+    <p>No, none of these. It's completely free of charge.\r
+    Junkbusters offers you the software to copy, use, modify and\r
+    distribute as you wish, forever, at no charge under the GNU\r
+    General Public License.</p>\r
+\r
+    <p><a name="warranty"></a>It comes with no warranty of any\r
+    kind.</p>\r
+\r
+    <p><a name="register"></a>You don't have to register, in fact\r
+    we don't even provide a way to do so: the practice of\r
+    registering software is usually just an excuse to send you\r
+    solicitations and sell your name and information about your\r
+    behavior. You are welcome to obtain and use our software as\r
+    anonymously you wish. (Your IP address will naturally be\r
+    disclosed when you download it; use anonymizing software if you\r
+    want to conceal this. We never want to be given any information\r
+    that you consider private or confidential.)</p>\r
+\r
+    <p><a name="why"></a>We are often asked why we give away a\r
+    product that many would happily pay for. The answer is that we\r
+    are determined to carry out our mission: to free the world from\r
+    junk communications.</p>\r
+\r
+    <h3><a name="windows"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Does it run on Windows? On a Mac?\r
+    On the AOL browser?</h3>\r
+\r
+    <p>For the latest information on availability, see the\r
+    Distribution Information page. We don't think it will ever run\r
+    on Windows 3.1. But you don't need to have it running on your\r
+    computer if you get your ISP or Systems Administrator at work\r
+    to run it.</p>\r
+\r
+    <h3><a name="isp"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How can I get my ISP to run the\r
+    Internet Junkbuster?</h3>\r
+\r
+    <p>Try their sales or support department (depending on whether\r
+    you are already a customer). <a name="unaware"></a>You might\r
+    send them email including the following URL:<br>\r
+     &nbsp;&nbsp;&nbsp; <code>\r
+    http://www.junkbusters.com/ht/en/ijbfaq.html#isps</code><br>\r
+     <a name="switch"></a>You could mention that many other ISPs\r
+    provide it, and that you regard it as an important part of your\r
+    decision on where to buy Internet service.</p>\r
+\r
+    <h3><a name="who"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Who chooses the options that\r
+    control what is blocked?</h3>\r
+\r
+    <p>Whoever starts the Internet Junkbuster chooses the options\r
+    and the blockfile. If your ISP runs it for you, they have to\r
+    make these decision (though some may give you a choice of\r
+    proxies, and a way to suggest new URLs to block). If you run it\r
+    on your computer, you get to choose.</p>\r
+\r
+    <h3><a name="self"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How do I download and run the\r
+    program on my computer?</h3>\r
+\r
+    <p>It depends on your platform. If you are using Windows 95 or\r
+    NT, see our separate page on installing under Windows. If you\r
+    have a C compiler and are using almost any flavor of UNIX &reg;\r
+    you download it, compile it, start it running, and then\r
+    configure your browser. Several precompiled packages are also\r
+    available through links in our distribution page, which lists\r
+    all available platforms.</p>\r
+\r
+    <p><a name="port"></a>If you are using a platform for which we\r
+    have no current availability, you are welcome to port the code.\r
+    If you do this and you would like us to consider publishing\r
+    your ported version, please tell us.</p>\r
+\r
+    <h3><a name="show"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How can I tell which blockfile\r
+    and options are being used?</h3>\r
+\r
+    <p>Just point your browser to\r
+    http://internet.junkbuster.com/cgi-bin/show-proxy-args or to\r
+    any URL ending in <code>show-proxy-args</code> (even if it\r
+    doesn't exist). It needn't exist because the Internet\r
+    Junkbuster intercepts the request, blocks it, and returns in\r
+    its place information about itself. Using the URL above is\r
+    useful for checking that your browser really is going through\r
+    an Internet Junkbuster, because the <code>junkbuster.com</code>\r
+    server returns a warning if the request actually gets to it.\r
+    Some people set the home page of their browser to such a URL to\r
+    be sure that it is configured to use the proxy.</p>\r
+\r
+    <p><a name="headers"></a>If you wish to check the header\r
+    information your proxy is actually sending, a visit to\r
+    http://internet.junkbuster.com/cgi-bin/show_http_headers will\r
+    give you the more relevant ones first. You might also like to\r
+    turn the proxy off and compare the difference. (Don't forget to\r
+    turn it back on again.)</p>\r
+\r
+    <h3><a name="responding"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; My browser started giving me\r
+    ``server not responding'' messages</h3>\r
+\r
+    <p>Once your browser is told to use a proxy such as the\r
+    Internet Junkbuster, it thinks of it as its server for\r
+    everything, so this message means it can't talk to the proxy.\r
+    The Internet Junkbuster may not be running, or you may have\r
+    specified its proxy address incorrectly. Check that the details\r
+    you entered are correct. If you have <code>telnet</code> you\r
+    can try connecting to the appropriate port to see if the\r
+    Internet Junkbuster is running. If your ISP is running the\r
+    Internet Junkbuster, you may want to check with them. If you\r
+    are running it yourself under UNIX &reg;, try looking at a\r
+    <code>ps ax</code> to see if it is running. The <a href=\r
+    "ijbman.html#o_h">port</a> specified in its options should be\r
+    the same one as your browser has configured.</p>\r
+\r
+    <h3><a name="idea"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; I've got this great idea for a\r
+    new feature. Who do I tell?</h3>\r
+\r
+    <p>We'd be very interested to hear it, but please bear a few\r
+    things in mind.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="considered"></a>Please check this FAQ to see if\r
+      we've already considered the idea, such as automatic\r
+      detection of banner ads and replacing ads with something else\r
+      such as a transparent GIF.</li>\r
+\r
+      <li><a name="confidential"></a>Don't tell us anything you\r
+      want to keep confidential or retain some right over.</li>\r
+\r
+      <li><a name="wish"></a>We currently have a long wish list of\r
+      things that we may or may not do in the near future,\r
+      including a version for your favorite computer and a plug-in\r
+      version.</li>\r
+\r
+      <li><a name="go4it"></a>If you don't want to wait you're\r
+      welcome to improve on our code, publish your version on the\r
+      Web, and tell us where to find it. Projects that are\r
+      especially welcome include a port to the Mac and extensions\r
+      for HTTP 1.1. (Meanwhile, be sure your browser is configured\r
+      not to use HTTP 1.1.)</li>\r
+    </ol>\r
+\r
+    <h3><a name="other"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; My question isn't listed here.\r
+    Who do I ask for support?</h3>\r
+\r
+    <p><a name="harder"></a>If you find using our free product\r
+    harder than you're used to for consumer software, there are\r
+    many commercial alternatives that you could consider.</p>\r
+\r
+    <p><a name="RTM"></a>The answer to detailed technical questions\r
+    may be answered in <a href="ijbman.html">manual page</a>, or in\r
+    the source code. Also double-check this page for an answer:\r
+    using the ``find'' feature on your browser for likely keywords\r
+    may help. Our site also has a search feature.</p>\r
+\r
+    <p><a name="Use"></a>Many people post requests for help and\r
+    responses on Usenet.</p>\r
+\r
+    <p><a name="them"></a>If your ISP is providing the Internet\r
+    Junkbuster for you, and your question is about how to use it,\r
+    check their web page before asking them.</p>\r
+\r
+    <p><a name="us"></a>Even though we don't offer the kind of\r
+    support you might expect if you paid a lot of money for a\r
+    software product, you can still ask us. But before you do,\r
+    please consider whether you could ask someone closer to you.\r
+    And please be patient if we're slow to reply: we never charge\r
+    consumers for our services, so we have to subsidize consumers\r
+    with revenue from companies, and our resources are limited.</p>\r
+\r
+    <p><a name="quote"></a>If your company or organization would be\r
+    interested in a maintenance contract with phone and email\r
+    support, hard copy documentation and source code and\r
+    pre-compiled binaries on tape or disk, please ask us for a\r
+    quote.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <h2><a name="browser"></a>Configuring your browser to talk to\r
+    the Internet Junkbuster</h2>\r
+\r
+    <h3><a name="address"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What is the proxy address of the\r
+    Internet Junkbuster?</h3>\r
+\r
+    <p><a name="localhost"></a>If you set up the Internet\r
+    Junkbuster to run on the computer you browse from (rather than\r
+    your ISP's server or some networked computer at work), the\r
+    proxy will be on <code>localhost</code> (which is the special\r
+    name used by every computer on the Internet to refer to itself)\r
+    and the port will be <code>8000</code> (unless you have told\r
+    the Internet Junkbuster to run on a different port with the <a\r
+    href="ijbman.html#listen-address">listen-address</a> option).\r
+    So you when configuring your browser's proxy settings you\r
+    typically enter the word <code>localhost</code> in the two\r
+    boxes next to <b class="eg">HTTP</b> and <b class="eg">\r
+    Secure</b>, and the number <code>8000</code> in the two boxes\r
+    labeled to the right of those boxes. <a name="Gopher"></a>The\r
+    Internet Junkbuster does not currently handle other protocols\r
+    such as Gopher, FTP, or WAIS, so leave those setting unchanged.\r
+    Nor does it handle ICQ or Instant Messenger services.</p>\r
+\r
+    <p><a name="remote"></a>If your ISP or company is running the\r
+    Internet Junkbuster for you, they will tell you the address to\r
+    use. It will be the name of the computer it's running on (or\r
+    possibly its numeric IP address), plus a port number. Port 8000\r
+    is the default, so assume this number if it is not specified.\r
+    Sometimes a colon is used to glue them together, as in <code>\r
+    junkbuster.fictitious-pro-privacy-isp.net:8000</code> but with\r
+    most browsers you do not type the colon, you enter the address\r
+    and port number in separate boxes.</p>\r
+\r
+    <h3><a name="set"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How do I tell the browser where\r
+    to find the Internet Junkbuster?</h3>\r
+\r
+    <p>All current browsers can be told the address of a proxy to\r
+    use. You enter the same information in two fields in your\r
+    browser's proxy configuration screen (see list below): one for\r
+    HTTP, and one for the Secure Protocol (assuming your browser\r
+    supports SSL). If you find some information already entered for\r
+    your proxy, see the next question. Here are the menus you go\r
+    through to get to the proxy configuration settings. (We also\r
+    recommend that you disable Java, which is a separate\r
+    operation.) <strong>Make notes on the changes you make so you\r
+    know how to undo them!</strong> You will need to know what you\r
+    did in case you wish to discontinue using the proxy.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="netscape"></a>For Netscape 2.01, 2.02 and 3.0\r
+      [Graphic Illustration]: <b class="eg">Options</b>; <b class=\r
+      "eg">Network Preferences</b>; <b class="eg">Proxies</b>; <b\r
+      class="eg">Manual Proxy Configuration View ;</b> enter proxy\r
+      address details under <b class="eg">HTTP</b> and <b class=\r
+      "eg">Security Proxy</b>; click on <b class="eg">OK</b>; click\r
+      on the next <b class="eg">OK</b>. [Return to Windows\r
+      Installation Procedure]<br>\r
+       With Netscape 2.0, follow with <b class="eg">Options</b>, <b\r
+      class="eg">Save Options</b>.<br>\r
+       <a name="Netscape4.02"></a>With Netscape 4.X series, you\r
+      first have to go through <b class="eg">Edit/Preferences</b>.\r
+      [Graphic Illustration] Then in the frame on the left, click\r
+      on triangle pointing to the right towards the word <b class=\r
+      "eg">Advanced</b>; it will switch to a triangle pointing\r
+      down; and the words <b class="eg">Cache</b>, <b class="eg">\r
+      Proxies</b> and <b class="eg">Disk Space</b> appear. Click on\r
+      <b class="eg">Proxies</b> and the frame on the right will\r
+      display a banner saying <b class="eg">Proxies Configure\r
+      proxies to access the Internet</b>. Click the radio button\r
+      labeled <b class="eg">Manual proxy configuration</b> then\r
+      click the button labeled <b class="eg">View</b>; enter proxy\r
+      address details under <b class="eg">HTTP</b> and <b class=\r
+      "eg">Security Proxy</b>; click on <b class="eg">OK</b>; click\r
+      on the next <b class="eg">OK</b>. [Return to Windows\r
+      Installation Procedure]</li>\r
+\r
+      <li><a name="explorer3"></a>For Internet Explorer 3.0\r
+      [Graphic Illustration]: <b class="eg">View</b>; <b class=\r
+      "eg">Options</b>; <b class="eg">Connections</b>; tick <b\r
+      class="eg">Connect through proxy server</b> box; <b class=\r
+      "eg">Settings</b>; enter proxy address details <b class="eg">\r
+      HTTP</b> Box, with port number in the second box; same with\r
+      <b class="eg">Secure</b>; click on <b class="eg">OK</b>.\r
+      [Return to Windows Installation Procedure]</li>\r
+\r
+      <li><a name="explorer2"></a>For Internet Explorer 2.0: <b\r
+      class="eg">View</b>; <b class="eg">Options</b>; <b class=\r
+      "eg">Proxy</b>; enter proxy address details click on <b\r
+      class="eg">OK</b>. [Return to Windows Installation\r
+      Procedure]</li>\r
+\r
+      <li><a name="nt"></a>On NT for MS-IE: <b class="eg">Control\r
+      Panel</b>; <b class="eg">Internet</b>; <b class="eg">\r
+      Advanced</b>; <b class="eg">Proxy</b>.</li>\r
+\r
+      <li><a name="if"></a>For MS-IE 4.0: similar to 3.0: <b class=\r
+      "eg">View</b>; <b class="eg">Internet Options</b>; <b class=\r
+      "eg">Connection</b>; tick <b class="eg">Access Internet using\r
+      a proxy server</b> box; from there we have had reports of\r
+      different versions, either click on <b class="eg">\r
+      Advanced</b> or <b class="eg">Settings</b>; enter proxy\r
+      address details <b class="eg">HTTP</b> Box, with port number\r
+      in the second box; same with <b class="eg">Secure</b>; click\r
+      on <b class="eg">OK</b>. Note that 4.0 has <b class="eg">\r
+      Advanced</b> settings to allow HTTP 1.1 through proxies;\r
+      these must be disabled because the proxy does not currently\r
+      understand HTTP 1.1. Please tell us if you see any other\r
+      differences. [Return to Windows Installation Procedure]</li>\r
+\r
+      <li><a name="IE5"></a>For MS-IE 5.0: similar to 4.0: <b\r
+      class="eg">Tools|Internet Options</b> from the menu bar; <b\r
+      class="eg">Connections</b>. Select either dial-up connection\r
+      or LAN (depending on how you connect to the Internet); press\r
+      <b class="eg">Settings</b>; and check the <b class="eg">Use\r
+      Proxy Server</b> box; enter proxy address details in the <b\r
+      class="eg">HTTP</b> Box, with port number in the second box;\r
+      same with <b class="eg">Secure</b>; click on <b class="eg">\r
+      OK</b> buttons to get out. <em>Note:</em> <a name=\r
+      "defaulted"></a>You must also uncheck the HTTP 1.1 checkboxes\r
+      at the end of the <b class="eg">Advanced</b> options. This\r
+      seems to have been made the default in IE 5.0. [Return to\r
+      Windows Installation Procedure]</li>\r
+\r
+      <li><a name="level5"></a>For Netscape's level 5 browser, we\r
+      have no information. If you do, please tell us.</li>\r
+\r
+      <li><a name="mosaic"></a>For NCSA Mosaic for Windows: <b\r
+      class="eg">Options</b>, <b class="eg">Preferences</b>, <b\r
+      class="eg">Proxy</b>; enter proxy address details under <b\r
+      class="eg">HTTP</b>.</li>\r
+\r
+      <li><a name="Opera"></a>For Opera: <b class="eg">\r
+      Preferences</b>, <b class="eg">Proxy servers</b>; check the\r
+      box next to HTTP; enter the server and port number in the box\r
+      on the other side; click on <b class="eg">OK</b>.</li>\r
+\r
+      <li><a name="lynx"></a>For Lynx, Mosaic/X, <a href=\r
+      "http://monty.cnri.reston.va.us/grail-0.3/">Grail,</a> and\r
+      W3O Arena, you can specify the proxy via environment\r
+      variables before starting the application. This will probably\r
+      be done with something like either<br>\r
+       &nbsp;&nbsp;&nbsp;<code>setenv http_proxy\r
+      http://localhost:8000/</code><br>\r
+       or<br>\r
+       &nbsp;&nbsp;&nbsp; <code>\r
+      http_proxy=http://junkbuster.fictitious-pro-privacy-isp.net:8000/\r
+      export http_proxy</code><br>\r
+       depending on your shell and where the Internet Junkbuster\r
+      lives.</li>\r
+    </ol>\r
+\r
+    <p>If your browser is not listed here, or if you notice an\r
+    error, please tell us the correct procedure.</p>\r
+\r
+    <h3><a name="already"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What should I do if I find\r
+    another proxy is already configured?</h3>\r
+\r
+    <p>Some ISPs and companies require all Web traffic to go\r
+    through their proxy. In this case you would find your proxy\r
+    configuration with values already set, possibly under <a name=\r
+    "Automatic"></a>Automatic Proxy Configuration (in the case of\r
+    Netscape and MS-IE 3.0 and above). It's probably a firewall\r
+    proxy between your company and the outside world, <a name=\r
+    "cache"></a>or a caching proxy if you're using an ISP.</p>\r
+\r
+    <p><a name="f"></a>What needs to be done in this case is to use\r
+    the <a href="ijbman.html#forwardfile">forwardfile</a> option to\r
+    tell the Internet Junkbuster the address of the other proxy.\r
+    Specify a different (unused) port number with the <a href=\r
+    "ijbman.html#listen-address">listen-address</a> option, and\r
+    configure your browser to use that port. If you haven't done\r
+    this kind of thing before, it's probably best to consult your\r
+    systems administrator or ISP about it; check their web page\r
+    first.</p>\r
+\r
+    <h3><a name="discontinue"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; What if I want to stop using\r
+    the Internet Junkbuster?</h3>\r
+\r
+    <p>Just go through the same procedure you used to start your\r
+    browser using the Internet Junkbuster, but remove the details\r
+    you put in (or if there was something there before, restore\r
+    it). You may need to use <b class="eg">Save Options</b> to make\r
+    this change permanent. On Netscape 3.0 you can go through <b\r
+    class="eg">Options</b>; <b class="eg">Network Preferences</b>;\r
+    <b class="eg">Proxies</b> and click on <b class="eg">No\r
+    Proxy</b> to turn it off, and later click on <b class="eg">\r
+    Manual Proxy Configuration</b> if you want to start using it\r
+    again. (No need to enter the again details under <b class="eg">\r
+    View</b> as you did the first time; they should remain there\r
+    unchanged.)</p>\r
+\r
+    <p><a name="shut"></a>This stops your browser talking to the\r
+    proxy; shutting down the proxy is a different matter.</p>\r
+\r
+    <h3><a name="dial"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Automatic dialing isn't working\r
+    any more. How do I fix it?</h3>\r
+\r
+    <p>Some browsers (such as MSIE-4) can be configured to dial\r
+    your ISP automatically when you click on a link, but this\r
+    feature (called "automatically connect" or "autoconnect") gets\r
+    disabled if you specify a proxy running on your own computer\r
+    (with address <code>localhost</code> or <code>127.0.0.1</code>)\r
+    because these addresses don't require dialing. The Internet\r
+    Junkbuster knows nothing about dialing, so it doesn't work. To\r
+    make automatic dialing work, make up a name such as <code>\r
+    junkbuster.ijb</code> and use that name in the proxy settings\r
+    instead of <code>localhost</code>, and then add the line <code>\r
+    127.0.0.1 junkbuster.ijb</code> to the file <code>\r
+    c:\windows\hosts</code> (if there already is a line beginning\r
+    with <code>127.0.0.1</code> just add <code>\r
+    junkbuster.ijb</code> at the end of it.)</p>\r
+\r
+    <p><a name="also"></a>This should also work Netscape\r
+    Communicator 4 on machines where IE-4 has been installed.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <h2><a name="local"></a>Setting up the Internet Junkbuster on\r
+    your local computer</h2>\r
+\r
+    <p>The next two sections assume you wish to compile the code\r
+    with your own C compiler. <a name="install"></a>If you just\r
+    want to use the <code>.exe</code> file provided for Windows,\r
+    see the Windows Installation page.</p>\r
+\r
+    <h3><a name="u"></a><img border="0" src="fb.gif" alt="*" width=\r
+    "14" height="14">&nbsp; How do I compile the code under\r
+    Unix?</h3>\r
+\r
+    <p>If you are running Redhat Linux you may prefer to use the\r
+    rpm instead of the following procedure.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="download"></a>First download the tar file\r
+      (~286k) <a name="tar"></a>and uncompress and extract the\r
+      files from it with this command<br>\r
+       &nbsp;&nbsp;&nbsp;<code>uncompress -c ijb20.tar.Z | tar xf\r
+      -</code></li>\r
+\r
+      <li><a name="sun"></a>If your operating system is from Sun or\r
+      HP examine the <code>Makefile</code> and make any changes\r
+      indicated inside.</li>\r
+\r
+      <li><a name="make"></a>Run<br>\r
+      <br>\r
+       &nbsp;&nbsp;&nbsp;<code>make</code></li>\r
+\r
+      <li>\r
+        <a name="defaults"></a>Copy the sample configuration file\r
+        (<code>junkbstr.ini</code>, previously called <code>\r
+        sconfig.txt</code> and other names in earlier releases) to\r
+        some convenient place such as <code>\r
+        /usr/local/lib/junkbuster/configfile</code> or whatever you\r
+        choose. The sample file has all the options commented out.\r
+        You can remove the <code>#</code> character on any that you\r
+        want, but it may be better to leave this until to later.\r
+        Run it asynchronously:<br>\r
+        <br>\r
+         &nbsp;&nbsp;&nbsp;<code>junkbuster configfile &amp;</code>\r
+        \r
+\r
+        <p>If you are running a version earlier than 2.0 you can\r
+        start it with <code>junkbuster &amp;</code></p>\r
+      </li>\r
+\r
+      <li><a name="config"></a>Configure your browser (described\r
+      above).</li>\r
+\r
+      <li><a name="test"></a>Verify that the Internet Junkbuster is\r
+      working (described above).</li>\r
+\r
+      <li><a name="restart"></a>Decide on the options you really\r
+      want, <code>kill</code> the process and start it again. The\r
+      most popular option is <a href="ijbman.html#blockfile">\r
+      blockfile</a> to block ads. <a name="comprehensive"></a>A\r
+      sample blockfile is provided as an illustration, but it\r
+      doesn't really stop many ads. More comprehensive ones are\r
+      available elsewhere.</li>\r
+\r
+      <li><a name="rc"></a>You'll probably want to add an entry to\r
+      <code>/etc/rc.d/rc.local</code> or equivalent to start it at\r
+      boot time. (Any output you specify should be redirected to a\r
+      file. And don't forget the &amp; at the end to run it\r
+      asynchronously or your system will seize up after the next\r
+      reboot.)</li>\r
+    </ol>\r
+\r
+    <h3><a name="win"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How do I compile the code under\r
+    Windows?</h3>\r
+\r
+    <p>A <code>.exe</code> file (binary) is supplied with the\r
+    source code, but if you prefer to compile it yourself here is\r
+    the likely procedure. Most of these steps are repeated in our\r
+    checklist for installation under Windows.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="zip"></a>First click here to download the zip\r
+      file called <code>ijb20.zip</code> (~208k), then uncompress\r
+      and unpack the zip archive using a tool like WinZip.</li>\r
+\r
+      <li><a name="change"></a>Now the distribution (source and\r
+      sample files) will be in a folder called <code>ijb20</code>.\r
+      Go into that folder and then edit the Makefile for your\r
+      system, removing the comment character (<code>#</code>) in\r
+      the lines related to Win32. Then type:<br>\r
+       &nbsp;&nbsp;&nbsp;<code>nmake</code><br>\r
+       This should create an executable called <code>\r
+      junkbstr.exe</code>. <a name="compilers"></a>For information\r
+      on issues with various compilers, see the Distribution\r
+      Information page.</li>\r
+\r
+      <li>\r
+        <a name="attempt"></a>Run the executable with the\r
+        command:<br>\r
+         &nbsp;&nbsp;&nbsp;<code>junkbstr</code><br>\r
+         <a name="terminal"></a>(Click on the icon with that name\r
+        that looks like a terminal, not like a notepad.) The\r
+        program will produce a message indicating that it has\r
+        started and is ready to serve. \r
+\r
+        <p><a name="ini"></a>(Version 2.0.1 and above uses the file\r
+        <code>junkbstr.ini</code> as the config file if it exists\r
+        and no argument was given. If you have an earlier version\r
+        or if you want it to use a different config file, simply\r
+        specify that file as the argument.)</p>\r
+      </li>\r
+\r
+      <li><a name="configures"></a>Configure your browser\r
+      (described above).</li>\r
+\r
+      <li><a name="work"></a>Check the proxy is working (described\r
+      below).</li>\r
+\r
+      <li>\r
+        <a name="shortcut"></a>To have the proxy start itself\r
+        automatically when you login to Win95, drop the\r
+        ``shortcut'' to the <code>junkbstr</code> executable into\r
+        the StartUp folder:<br>\r
+         &nbsp;&nbsp;&nbsp;<code>C:\Windows\Start\r
+        Menu\Programs\StartUp</code><br>\r
+         You might want to change the shortcut's <code>\r
+        Properties-&gt;Shortcut</code> to <code>Run:\r
+        Minimized</code>. If you specify the <a href=\r
+        "ijbman.html#hide-console">hide-console</a> option then the\r
+        DOS window will vanish after it starts. \r
+\r
+        <p><a name="NT"></a>WinNT users can put it into their own\r
+        StartUp folders or the Administrator can put it into the\r
+        system's global StartUp folder. For details on how to make\r
+        this a service under NT see our Windows page.</p>\r
+      </li>\r
+    </ol>\r
+\r
+    <h3><a name="check"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How do I check that the proxy is\r
+    working?</h3>\r
+\r
+    <p>Pick a page from somewhere (such as your bookmarks, or just\r
+    one that your browser was pointing to) and <b class="eg">\r
+    Reload</b> it. If you get a message along the lines of ``server\r
+    not responding, using cached copy instead,'' see the advice\r
+    above. If the page reloads OK, check that your browser is\r
+    actually talking to the proxy by going to\r
+    http://internet.junkbuster.com/cgi-bin/show-proxy-args or any\r
+    URL ending in <code>show-proxy-args</code> (as described below,\r
+    the proxy should intercept the request.) When you see\r
+    ``Internet Junkbuster Proxy Status,'' you'll know it's\r
+    working.</p>\r
+\r
+    <h3><a name="chain"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How and why would I have this\r
+    proxy chained with other proxies?</h3>\r
+\r
+    <p>You may need the <a href="ijbman.html#forwardfile">\r
+    forwarding</a> feature to ``daisy chain'' the Internet\r
+    Junkbuster to another proxy, perhaps an anonymizing proxy to\r
+    conceal your IP address, or a caching proxy from your ISP, or a\r
+    firewall proxy between your company and the outside world.\r
+    Version 2.0 and above can be even configured to forward <a\r
+    href="ijbman.html#forwardfile">selectively</a> according to the\r
+    URL requested: for example, connecting directly to trusted\r
+    hosts, but going through an anonymizing or firewall proxy for\r
+    all other hosts.</p>\r
+\r
+    <p><a name="administrator"></a>Network administrators might use\r
+    it to provide transparent access to multiple networks without\r
+    modifying browser configurations. <a name="direct"></a>Most\r
+    browsers also provide a way of specifying hosts that the\r
+    browser connects to directly, bypassing the proxy. Some provide\r
+    a method for Automatic Proxy Configuration. A well written\r
+    Internet Junkbuster configuration can be much more flexible and\r
+    powerful.</p>\r
+\r
+    <p><a name="example"></a>An ISP's caching proxy would typically\r
+    be called something like <code>cache.your-isp.net:8080</code>\r
+    (as described on you ISP's web page); you would put this\r
+    information in your <a href="ijbman.html#forwardfile">\r
+    forwardfile</a> as described in our manual. Your browser would\r
+    be configured to the Internet Junkbuster for HTTP and Security\r
+    Proxies as before, but you probably want to tell it to use the\r
+    caching proxy for FTP and other protocols. <a name="nonlocal">\r
+    </a>If your ISP is running the Internet Junkbuster for you,\r
+    they have probably already decided whether to chain with a\r
+    caching proxy.</p>\r
+\r
+    <h3><a name="socks"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How does the Internet Junkbuster\r
+    work with SOCKS gateways?</h3>\r
+\r
+    <p>There is support for some gateways in Version 1.4 and above.\r
+    The gateway protocol used to be specified on the command line;\r
+    it is now specified in the same file as <a href=\r
+    "ijbman.html#forwardfile">forwarding.</a> Note that the\r
+    browser's proxy configuration must <em>not</em> specify a\r
+    <code>SOCKS</code> host; it should specify the proxy as\r
+    described above.</p>\r
+\r
+    <h3><a name="plain"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How do I configure it to be just\r
+    a plain old proxy?</h3>\r
+\r
+    <p>To get the proxy to do as little as possible (which means\r
+    not deleting any sensitive headers), place in your\r
+    configuration file the following three lines (each ending in a\r
+    space then a period) to stop it changing sensitive headers:<br>\r
+     &nbsp;&nbsp;&nbsp;<code>referer .</code><br>\r
+     &nbsp;&nbsp;&nbsp;<code>from .</code><br>\r
+     &nbsp;&nbsp;&nbsp;<code>user-agent .</code><br>\r
+     &nbsp;&nbsp;&nbsp;<code>cookiefile mycookiefile</code><br>\r
+     The fourth line is also needed to specify a <a href=\r
+    "ijbman.html#o_c">cookiefile</a> that might be called <code>\r
+    mycookiefile</code> containing a single line with a <code>\r
+    *</code> character, to allow all cookies through.</p>\r
+\r
+    <h3><a name="shutdown"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How do I shut down the proxy (to\r
+    restart it)?</h3>\r
+\r
+    <p>It depends on your platform.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="X"></a>Under Windows, you can click on the "X"\r
+      button at the top right of the DOS window (and answer <b\r
+      class="eg">Yes</b> when Windows warns you it cannot shut down\r
+      the program automatically), or use <b class="eg">\r
+      Ctrl-Break</b> or the old three-fingered salute of <b class=\r
+      "eg">Ctrl-Alt-Delete</b> and select <b class="eg">End\r
+      Task</b>.</li>\r
+\r
+      <li><a name="ps"></a>Under UNIX &reg; you'll need to <code>\r
+      kill</code> the <b><code>junkbuster</code></b> process. <a\r
+      name="pid"></a>If you don't know the process number to give\r
+      to <code>kill</code>, try this:<br>\r
+       &nbsp;&nbsp;&nbsp;<code>ps ax | grep junkbuster</code></li>\r
+    </ol>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <h2><a name="companies"></a> Information for companies</h2>\r
+\r
+    <h3><a name="think"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What do advertising companies\r
+    think of this kind of technology?</h3>\r
+\r
+    <p>We've seen only a few public comments from the advertising\r
+    industry on this, other than SEC filings. First, the president\r
+    of the Internet Advertising Bureau told CNET that he wasn't\r
+    worried by banner blockers. Second, after the Federal Trade\r
+    Commission's workshop where we gave a live demonstration of our\r
+    proxy before many eminent representatives of the industry, the\r
+    Direct Marketing Association made the following statement in\r
+    the closing paragraphs of their summary comments to the\r
+    Commission.</p>\r
+\r
+    <blockquote>\r
+      Clever shareware developers have come up with products that\r
+      can obliterate cookies and advertisements for those consumers\r
+      who have these concerns. The Internet is a market that is so\r
+      democratic and flexible that it is easy for companies and\r
+      software developers to respond to a perceived market need.\r
+    </blockquote>\r
+\r
+    <p>Their attitude seems to be that they would prefer that\r
+    people use technical solutions to protect their privacy than\r
+    have protections imposed by legislation or government\r
+    regulations. So, do you perceive a market need? Then here are\r
+    some ways to flex your democratic muscles.</p>\r
+\r
+    <h3><a name="nobrainer"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; Should we provide the\r
+    Internet Junkbuster for our employees?</h3>\r
+\r
+    <p>That depends. Try this quick three-point test.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="waste"></a>Do you want to spend your\r
+      communications budget on bandwidth that wastes your\r
+      employees' time by forcing them to wait for a lot of annoying\r
+      distractions while they're trying to do their jobs?</li>\r
+\r
+      <li><a name="surveillance"></a>Do you want current and\r
+      potential vendors to know quantitative details about the\r
+      software and hardware platforms that you have?</li>\r
+\r
+      <li><a name="intelligence"></a>Do you want your competitors\r
+      to be able to track exactly which of your employees are\r
+      checking out their web sites?</li>\r
+    </ol>\r
+\r
+    <p>If the answer to all three questions is yes, then you\r
+    probably don't have any need for this kind of product.</p>\r
+\r
+    <h3><a name="commercial"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; Can our company get\r
+    commercial support for the software?</h3>\r
+\r
+    <p>Yes, ask us for a quote on a maintenance contract with your\r
+    choice of phone and email support, hard copy documentation,\r
+    source code and pre-compiled binaries on tape or disk, and\r
+    email alerting of upgrades and issues. We also offer consulting\r
+    services to help set up ``stealth browsing'' capabilities to\r
+    help reduce the footprints left while doing competitive\r
+    analysis and other Web work where confidentiality is\r
+    critical.</p>\r
+\r
+    <h3><a name="isps"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; I run an ISP. What issues should\r
+    I consider before offering it?</h3>\r
+\r
+    <p>Many ISPs who offer the proxy to their customers have told\r
+    us that most of their customers are delighted with it (although\r
+    one reported that a customer complaint that without banner ads,\r
+    surfing was like reading a novel: we recommend making it\r
+    optional). Many ISPs like it because it reduces bandwidth\r
+    requirements. To help get you started, here's a checklist we've\r
+    developed from working with a few ISPs. You may think of more,\r
+    and we'd be interested if you're willing to share them with\r
+    us.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="pending"></a>If you get more than one request\r
+      for the Internet Junkbuster you may want to tell your\r
+      customers on your News page that you already know about it\r
+      and are assessing it.</li>\r
+\r
+      <li><a name="try"></a>Try the software and verify that it\r
+      performs satisfactorily.</li>\r
+\r
+      <li><a name="value"></a>Determine whether your customers\r
+      perceive the service as valuable (and therefore worth the\r
+      time to set up). We've had reports of many delighted\r
+      customers.</li>\r
+\r
+      <li><a name="secure"></a>Assess the level of security\r
+      associated with the software. If access is to be restricted\r
+      (to just dial-in ports, for example) how is this to be\r
+      done?</li>\r
+\r
+      <li><a name="costs"></a>Consider whether to expect any\r
+      additional load on computing resources required, and any\r
+      change in use of bandwidth due to the blocking of large\r
+      GIFs.</li>\r
+\r
+      <li><a name="opt"></a>Choose the <a href="ijbman.html">\r
+      options</a> you wish to provide.</li>\r
+\r
+      <li>\r
+        <a name="multiple"></a>Decide whether you want to offer a\r
+        choice of configurations, such some of these four. \r
+\r
+        <ol type="A">\r
+          <li><a name="banner"></a>Banners Blocked, Wafer with\r
+          No-Cookie-Copyright notice</li>\r
+\r
+          <li><a name="low"></a>Cookies not stopped (<a href=\r
+          "ijbman.html#cookiefile">cookiefile</a> with just a\r
+          <code>*</code> in it), User Agent specified as Lynx</li>\r
+\r
+          <li><a name="oneway"></a>Cookies from browser allowed,\r
+          permitting registered services</li>\r
+\r
+          <li><a name="kid"></a>A proxy for kids.</li>\r
+        </ol>\r
+        <a name="caching"></a>If you run a caching proxy, decide\r
+        whether the Internet Junkbuster will chain with it by\r
+        default, and whether to offer an alternate with no caching.\r
+        (Some ISPs don't, because they want to give customers an\r
+        incentive to use caching and save bandwidth.)\r
+      </li>\r
+\r
+      <li><a name="naming"></a>Decide on a naming scheme for your\r
+      proxies. If you're running only one proxy on one machine, the\r
+      simplest way is to just use port 8000 on your main machine,\r
+      such as <code>our-isp.net.</code> But it would probably be\r
+      safer to put an entry in your name server and call it\r
+      something like <code>junkbuster.our-isp.net.</code> If\r
+      running several proxies, you could either use different ports\r
+      on the same machine, or if you have the opportunity to\r
+      distribute the load over a few machines you could use\r
+      different hostname aliases such as <code>\r
+      banner.junkbuster.our-isp.net</code>, <code>\r
+      lynx.junkbuster.our-isp.net</code> and <code>\r
+      oneway.junkbuster.our-isp.net</code> (corresponding to the\r
+      examples in the previous point). You may want to set up\r
+      Automatic Proxy Configuration.</li>\r
+\r
+      <li>\r
+        <a name="document"></a>Prepare a page explaining the\r
+        Internet Junkbuster to your customers. <a name="does"></a>\r
+        Here's are some examples from Australia, Germany, Florida,\r
+        New York/New Jersey/Pennsylvania, North Carolina, Texas,\r
+        and Utah. <a name="reuse"></a>You are welcome to copy and\r
+        modify material from Junkbusters according to the GPL. You\r
+        might want to set up a process to check this page\r
+        periodically and update it when it changes. (A few links\r
+        can probably serve as well as lot of copying however.) A\r
+        typical page would probably specify the following. \r
+\r
+        <ol type="1">\r
+          <li><a name="abstract"></a>A brief explanation stating\r
+          what the Internet Junkbuster does, with a link to this\r
+          page.</li>\r
+\r
+          <li><a name="addresses"></a>The addresses of the proxy or\r
+          proxies, with their port number(s).</li>\r
+\r
+          <li><a name="options"></a>The options used, and how to\r
+          view the contents of the blockfile (which you can place\r
+          on your web pages, preferably in a file called <code>\r
+          blocklist.html</code> or <code>\r
+          blocklist.txt</code>).</li>\r
+\r
+          <li><a name="additions"></a>An indication of whether\r
+          suggestions for the blocklist are considered, and if so,\r
+          how to submit them: to a particular email address, via\r
+          web-based form, etc.</li>\r
+\r
+          <li><a name="configuration"></a>Instructions on how to\r
+          configure a browser. You may want to include details for\r
+          only the two major browsers and leave the others to a\r
+          link.</li>\r
+\r
+          <li><a name="service"></a>Procedures on how to report\r
+          problems, give feedback etc.</li>\r
+        </ol>\r
+      </li>\r
+\r
+      <li><a name="beta"></a>Invite a small number of\r
+      technologically sophisticated customers to beta-test the\r
+      service.</li>\r
+\r
+      <li><a name="announce"></a>Announce general availability on\r
+      your ``News'' page. Tell us if you would like to be included\r
+      on a list of ISPs offering the Internet Junkbuster.</li>\r
+    </ol>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <h2><a name="blocking"></a> Blocking</h2>\r
+\r
+    <h3><a name="readymade"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; Where can I get an example\r
+    blockfile that stops most ads?</h3>\r
+\r
+    <p>The sample blockfile we provide blocks almost nothing, and\r
+    we do not publish blockfiles that stop almost all banner ads.\r
+    But others have; you can find them by asking Google. You can\r
+    add any part of the new file to your old one (probably called\r
+    <code>sblock.ini</code> if you haven't changed the default name\r
+    in the latest version) or your just replace it completely. You\r
+    probably don't need to restart the proxy.</p>\r
+\r
+    <p><a name="pub"></a>If you develop an interesting blocklist\r
+    and publish it on the Web, you might want to include the word\r
+    ``junkbuster'' in it and use the word ``blocklist'' in the file\r
+    name given in the URL so that others can find it with the query\r
+    given in the previous sentence.</p>\r
+\r
+    <h3><a name="zap"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; If I see an ad I wish I hadn't,\r
+    how do I stop it?</h3>\r
+\r
+    <p>If your ISP is running the Internet Junkbuster, they should\r
+    have a policy on whether they accept suggestions from their\r
+    customers on what to block. Consult their web page.</p>\r
+\r
+    <p><a name="cover"></a>If you are running the Internet\r
+    Junkbuster yourself, you have complete control over what gets\r
+    through. Just add a pattern to cover the offending URL to your\r
+    blockfile. Version 1.3 and later automatically rereads the\r
+    blockfile when it changes, but if you're running an earlier\r
+    version you'll have to stop it and restart it.</p>\r
+\r
+    <p><a name="target"></a>To choose a pattern you'll first need\r
+    to find the URL of the ad you want cover.</p>\r
+\r
+    <p><a name="pinpoint"></a>Some people use the <a href=\r
+    "ijbman.html#debug">debug</a> <code>1</code> option to display\r
+    each URL in a window as the request is sent to the server. It's\r
+    then usually an easy task to pick the offending URL from the\r
+    list of recent candidates.</p>\r
+\r
+    <p><a name="source"></a>Alternatively, you can use <b class=\r
+    "eg">View Document Info</b> (or <b class="eg">View Document\r
+    Source</b> if your browser doesn't have that). The <b class=\r
+    "eg">Info</b> feature has the advantage of showing you the full\r
+    URL including the host name, which may not be specified in the\r
+    source: there you might see something like <code>\r
+    SRC="/ads/click_here_or_die.gif"</code> indicating only the <i>\r
+    <dfn>path</dfn></i>. (The host name is assumed to be the same\r
+    as the one the page came from.)</p>\r
+\r
+    <p><a name="offsite"></a>But ads often come from a different\r
+    site, in which case you might see something like <code>\r
+    SRC="grabem.n.trackem.com/Ad/Infinitum/SpaceID=1666"</code> or\r
+    longer. <a name="warehouse"></a>If the company looks like a\r
+    pure ad warehouse (as in the last case), you may want to place\r
+    just its domain name in the blockfile, which blocks all URLs\r
+    from that site.</p>\r
+\r
+    <p><a name="wanted"></a>If the ad comes from a server that you\r
+    really want some content from, you can include enough of the\r
+    path to avoid zapping stuff you might want. In the first\r
+    example above, <code>/ads/</code> would seem to be enough. If\r
+    you don't include the domain name, the pattern applies to all\r
+    sites, so you don't want such patterns to be too general: for\r
+    example <code>/ad</code> would block <code>\r
+    /admin/salaries/</code> on your company's internal site.</p>\r
+\r
+    <p><a name="image"></a>To speed the blocking of images, some\r
+    UNIX &reg; users create a shell script called <code>\r
+    Image:</code> containing a line such as <code>echo $1 | sed\r
+    s/http:..// &gt;&gt; $HOME/lib/blockfile</code> that adds its\r
+    argument to the user's blockfile. Once an offending image has\r
+    been be found using <b class="eg">View Document Info</b> it's\r
+    easy to cut-and-paste the line (or part of it) into a shell\r
+    window. The same script can be linked to a file called <code>\r
+    Frame:</code> to dealing with framed documents, and <code>\r
+    junkbuster:</code> to accept the output of the <a href=\r
+    "ijbman.html#debug">debug</a> option.</p>\r
+\r
+    <p><a name="partial"></a>When compiled without the <i><dfn>\r
+    regular expressions</dfn></i> option, the Internet Junkbuster\r
+    uses only very simple (and fast) matching methods. The pattern\r
+    <code>/banners</code> will not stop <code>\r
+    /images/banners/huge.gif</code> getting through: you would have\r
+    to include the pattern <code>/images/banners</code> or\r
+    something that matches in full from the left. <a name="regex">\r
+    </a>So you can get what you want here, the matcher understands\r
+    POSIX regular expressions: you can use <code>\r
+    /*.*/banners</code> to block and any URL containing <code>\r
+    /banners</code> (even in the middle of the path). <a name=\r
+    "posix"></a>(In Versions 1.1 through 1.4 they were an option at\r
+    compile time; from Version 2.0 they have become the default.)\r
+    Regular expressions give you many more features than this, but\r
+    if you're not already familiar with them you probably won't\r
+    need to know anything beyond the <code>/*.*/</code> idiom. If\r
+    you do, a <code>man egrep</code> is probably a good starting\r
+    point).</p>\r
+\r
+    <p><a name="slash"></a>Don't forget the <code>/</code> (slash)\r
+    at the beginning of the path. If you leave it out the line will\r
+    be interpreted as a domain name, so <code>ad</code> would block\r
+    all sites from Andorra (since <code>.ad</code> is the\r
+    two-letter country code for that principality).</p>\r
+\r
+    <p><a name="detail"></a>For a detailed technical description of\r
+    how pattern matching is done, see the <a href=\r
+    "ijbman.html#o_b">manual.</a></p>\r
+\r
+    <h3><a name="despite"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; How come this ad is still getting\r
+    through anyway?</h3>\r
+\r
+    <p>If the ad had been displayed before you included its URL in\r
+    the blockfile, it will probably be held in cache for some time,\r
+    so it will be displayed without the need for any request to the\r
+    server. Using the <a href="ijbman.html#debug">debug</a> <code>\r
+    1</code> option to show each URL as it is fetched is a good way\r
+    to see exactly what is happening.</p>\r
+\r
+    <p><a name="otherwise"></a>If new items seem to be getting\r
+    through, check that you are really running the proxy with the\r
+    right blockfile in the options. Check the blockfile for\r
+    exceptions.</p>\r
+\r
+    <p><a name="java"></a>Some sites may have different ways of\r
+    inserting ads, such as via Java. If you have ideas on how to\r
+    block new kinds of junk not currently covered, please tell\r
+    us.</p>\r
+\r
+    <h3><a name="exceptions"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; How do I stop it blocking a\r
+    URL that I actually want?</h3>\r
+\r
+    <p>You can change the patterns so they don't cover it, or use a\r
+    simple feature in Version 1.1 and later: a line beginning with\r
+    a <code>~</code> character means that a URL blocked by previous\r
+    patterns that matches the rest of the line is let through. For\r
+    example, the pattern <code>/ad</code> would block <code>\r
+    /addasite.html</code> but not if followed by <code>\r
+    ~/addasite</code> in the blockfile. Or suppose you want to see\r
+    everything that comes from a site you like, even if it looks\r
+    like an ad: simply put <code>~aSiteYouLike.com</code> at the\r
+    <em>end</em> of the blockfile. (Order is important, because the\r
+    last matching line wins.)</p>\r
+\r
+    <p><a name="agreed"></a>As well as unblocking pages that were\r
+    unintentionally blocked, this feature is useful for unblocking\r
+    ads from a specific source. This might be because you are\r
+    interested in those particular ones, or if you have an explicit\r
+    agreement to accept certain ads, such as those from a free\r
+    web-based email provider.</p>\r
+\r
+    <p><a name="blocked"></a>If you want to find out exactly which\r
+    pattern in the blockfile a given URL matched, just click on the\r
+    words ``Internet Junkbuster'' which are displayed alone on a\r
+    page when your browser requests a blocked URL. The proxy\r
+    displays a message that pinpoints the pattern for you.</p>\r
+\r
+    <h3><a name="children"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Can I block sites I don't want my\r
+    children to see?</h3>\r
+\r
+    <p>Yes, but remember that <a name="savvy"></a>children who are\r
+    technically sophisticated enough to use the browsers' proxy\r
+    configuration options could of course bypass any proxy. This\r
+    kind of technology can be used as a gentle barrier to remind or\r
+    guide the child, but nobody should expect it to replace the\r
+    parent's role in setting and enforcing standards of online\r
+    behavior for their children.</p>\r
+\r
+    <p><a name="recommend"></a>Some ISPs are starting to provide\r
+    specialized proxies to protect children. There are two basic\r
+    approaches: the ``black list'' and the ``white list'' approach.\r
+    <a name="negative"></a>The black list approach allows the child\r
+    to go anywhere not explicitly prohibited; the white list\r
+    permits visits only to sites explicitly designated as\r
+    acceptable.</p>\r
+\r
+    <p><a name="positive"></a>It's very easy for anyone to compile\r
+    a white list from a page of ``recommended kids sites'' and to\r
+    configure an Internet Junkbuster to allow access to those sites\r
+    only. (If you publish such a list on the web, please tell us\r
+    its URL). Assuming your version isn't an old one without regex,\r
+    you can place a <code>*</code> (asterisk) as the first line of\r
+    the blockfile (which blocks everything), and then list\r
+    exceptions after that. Be careful to make the exception\r
+    sufficiently broad: for example, using <code>\r
+    ~www.uexpress.com/ups/comics/ch/</code> as the exception for\r
+    <cite>Calvin and Hobbes</cite> would block some of the graphic\r
+    elements on the page; you would probably want a wider exception\r
+    such as <code>~www.uexpress.com/ups/</code> to permit them.</p>\r
+\r
+    <p><a name="trust"></a>Version 2.0 has an experimental feature\r
+    to permit only sites mentioned in a nominated <a href=\r
+    "ijbman.html#trustfile">trusted site.</a> This allows\r
+    organizations to build lists of sites for kids to browse, and\r
+    the software automatically restricts access to those on the\r
+    list.</p>\r
+\r
+    <p><a name="scan"></a>Many filtering products actually scan for\r
+    keywords in the text of pages they retrieve before presenting\r
+    it, but the Internet Junkbuster does not do this. Building a\r
+    perfectly reliable black list system is hard, because it's very\r
+    difficult to state in advance exactly what is obscene or\r
+    unsuitable. For more info see our links page.</p>\r
+\r
+    <h3><a name="message"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What do I see when a page or\r
+    graphic is blocked by the proxy?</h3>\r
+\r
+    <p>You usually see a broken image icon, but it depends on\r
+    several factors beyond the proxy's control. If asked for a URL\r
+    matching its blockfile, the proxy returns an HTML page\r
+    containing a message identifying itself (currently the two\r
+    words ``Internet Junkbuster'') with a status 202 (Accepted)\r
+    instead of the usual 200 (OK). (Versions 1.X returned an error\r
+    404: Forbidden, which caused strange behavior in some cases.)\r
+    Status 202 is described in the HTTP RFC as indicating that the\r
+    request has been accepted but not completed, and that it might\r
+    complete successfully in the future (in our case, if the\r
+    blockfile were changed).</p>\r
+\r
+    <p><a name="depends"></a>The broken image icon is most common\r
+    because the browser is usually expecting a graphic. But if it\r
+    was expecting text, or if the page happens to be using certain\r
+    HTML extensions such as <code>layer</code> and your browser is\r
+    a late model from Microsoft, you may see the words ``Internet\r
+    Junkbuster'' displayed as a hot link.</p>\r
+\r
+    <p><a name="click"></a>Clicking on the link takes you to an\r
+    explanation of the pattern in the blockfile that caused the\r
+    block, so that you can edit the blockfile and go back and\r
+    reload if you really want to see what was blocked. The\r
+    explanatory link is generated by the proxy and is automatically\r
+    intercepted based on its ending in <code>ij-blocked-url</code>;\r
+    even though the site is specified as <code>\r
+    http://internet.junkbuster.com</code> no request should\r
+    actually made to that site. If one is, it means that the proxy\r
+    was been removed after it generated the link.</p>\r
+\r
+    <p><a name="layer"></a>To summarize: the identifying link to\r
+    the blocking explanation is usually turned into a broken image\r
+    icon, but it may be displayed on a page alone, or they may may\r
+    be restricted to the particular frame, layer or graphic area\r
+    specified in the page containing them. The proxy has no way of\r
+    knowing the context in which a URL will be used and cannot\r
+    control how the blocking message will be rendered.</p>\r
+\r
+    <h3><a name="broken"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Why not replace blocked banners\r
+    with something invisible?</h3>\r
+\r
+    <p><a name="infringe"></a>Many users have suggested to us that\r
+    blocked banners should be replaced by a something like a 1x1\r
+    transparent GIF to make the page would look as if there was\r
+    nothing ever there. Apart from making it harder to catch\r
+    unintended blocking, this might also displease the owners of\r
+    the page, who could argue that such a change constitutes a\r
+    copyright infringement. We think that merely failing to allow\r
+    an included graphic to be accessed would probably not be\r
+    considered an infringement: after all this is what happens when\r
+    a browser is configured not to load images automatically.\r
+    However, we are not lawyers, so anyone in doubt should take\r
+    appropriate advice.</p>\r
+\r
+    <p><a name="done"></a>In a context where the copyright issue is\r
+    resolved satisfactorily, a proxy could simply return a status\r
+    301 or 302 and specify a replacement URL in a <code>\r
+    Location</code> and/or <code>URI</code> header. An alternative\r
+    would be to use inline code to return a 1 x 1 clear GIF. We do\r
+    not publish sample code for this, and we have no way of\r
+    stopping others who have.</p>\r
+\r
+    <h3><a name="size"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Why not block banners based on\r
+    the dimensions of the image?</h3>\r
+\r
+    <p>Many users have pointed out that most banner ads come in\r
+    standard sizes, so why not block all GIFs of those sizes? This\r
+    would theoretically be without fetching the object because the\r
+    dimensions are usually given in the <code>IMG</code> tag, but\r
+    it would require substantial changes in the code, and we doubt\r
+    whether it would be much more effective than a good block\r
+    list.</p>\r
+\r
+    <h3><a name="embedded"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What about non-graphic\r
+    advertising within the pages I want?</h3>\r
+\r
+    <p>The Internet Junkbuster deliberately does not provide a way\r
+    of automatically editing the contents of a page, to remove\r
+    textual advertising or to repair the holes left by blocked\r
+    banners. Other packages such as WebFilter do.</p>\r
+\r
+    <p><a name="base"></a>For the same reason, it has no way of\r
+    stopping a new browser window being created, because this is\r
+    done through the <code>target</code> attribute in the <code>\r
+    &lt;a&gt;</code> and <code>&lt;base&gt;</code> elements, not\r
+    through headers. Nor do we plan to add a feature to paralyze\r
+    animated GIFs.</p>\r
+\r
+    <h3><a name="push"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Does it block ads on the\r
+    broadcasting ``push'' systems? How about pop-up ads?</h3>\r
+\r
+    <p>We haven't tried it but we expect it would probably work on\r
+    image ads on push channels. See also adchoice.</p>\r
+\r
+    <p><a name="pop"></a>Disabling Javascript stops some pop-up\r
+    ads. One problem is that some advertisers throw open a new\r
+    browser window to frame the ad. The ad is easily blocked, but\r
+    the empty window remains. You can kill it easily, but this is a\r
+    chore. We don't see how to stop them other than editing the\r
+    HTML from the parent window, which we don't like to do.</p>\r
+\r
+    <p><a name="TBTD"></a>The TBTF newsletter warned subscribers to\r
+    push information that <a name="LOGTARGET"></a>in IE4, LOGTARGET\r
+    allows servers to determine the URLs viewed at their site even\r
+    if accessed from cache or through a proxy. If you use this\r
+    browser see our instructions on how to disable this.</p>\r
+\r
+    <p><a name="pushy"></a>If you find you have experience using\r
+    the proxy with push, or have any other advice about it, please\r
+    tell us.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <h2><a name="cookies"></a> Cookies</h2>\r
+\r
+    <p>For background information on cookies see our page\r
+    describing their dangers.</p>\r
+\r
+    <h3><a name="breakthrough"></a><img border="0" src="fb.gif"\r
+    alt="*" width="14" height="14">&nbsp; Might some cookies still\r
+    get through? How can I stop them?</h3>\r
+\r
+    <p>Yes, you should expect the occasional cookie to make it\r
+    through to your browser. We know of at least three ways this\r
+    can happen; please tell us if you find any others. One way is\r
+    in secure documents, which are explained below.</p>\r
+\r
+    <p><a name="EQUIV"></a>A few sites set cookies using a line\r
+    such as <code>&lt;META HTTP-EQUIV="Set-Cookie"\r
+    CONTENT="flavor=chocolate"&gt;</code> in the <code>HEAD</code>\r
+    section of an HTML document. <a name="javascript"></a>Cookies\r
+    can also be \r
+    <!-- IEM: http://cgi.netscape.com/eng/mozilla/Gold/handbook/javascript/ref_a-c.html#cookie_property -->\r
+    set and read in JavaScript. To see if this is happening in a\r
+    document, view its source, look in the <code>head</code> for a\r
+    section tagged <code>script language="JavaScript"</code>. If it\r
+    contains a reference to <code>document.cookie</code>, the page\r
+    can manipulate your cookie file without sending any cookie\r
+    headers. The Internet Junkbuster does not tamper with these\r
+    methods. Fortunately they are rarely used at the moment. If a\r
+    cookie gets set, it should be stopped by the proxy on its way\r
+    back to the server when a page is requested, but it can still\r
+    be read in Javascript.</p>\r
+\r
+    <p><a name="alert"></a>To prevent cookies breaking through,\r
+    <strong>always</strong> keep cookie alerts turned on in your\r
+    browser, and disable Java and Javascript. Making the files hard\r
+    to write may also help.</p>\r
+\r
+    <h3><a name="method"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Exactly how do cookies get\r
+    created and stored anyway?</h3>\r
+\r
+    <p>When a web site's server sends you a page it also sends\r
+    certain ``header information'' which your browser records but\r
+    does not display. One of these is a <code>Set-Cookie</code>\r
+    header, which specifies the cookie information that the server\r
+    wants your browser to record. Similarly, when your browser\r
+    requests a page it also sends headers, specifying information\r
+    such as the graphics formats it understands. If a cookie has\r
+    previously been set by a site that matches the URL it is about\r
+    to request, your browser adds a <code>Cookie</code> header\r
+    quoting the previous information.</p>\r
+\r
+    <p><a name="privacy"></a>For more background information on how\r
+    cookies can damage your privacy, see our page on cookies. For\r
+    highly detailed technical information see the RFC. The Internet\r
+    Junkbuster will show you all headers you use the <a href=\r
+    "ijbman.html#debug">debug</a> <code>8</code> option, or you can\r
+    get a sample from our demonstration page.</p>\r
+\r
+    <h3><a name="break"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; If cookies can't get through,\r
+    will some things stop working for me?</h3>\r
+\r
+    <p>Possibly. Some personalized services including certain \r
+    <!-- IEM: http://my.yahoo.com --> chat rooms require cookies.\r
+    <a name="registration"></a>Newspapers that require \r
+    <!-- IEM: http://www.nytimes.com/subscribe/sub-bin/new_sub.cgi#agree -->\r
+    registration or \r
+    <!-- IEM: http://interactive5.wsj.com/regUser.html -->\r
+    subscription will not automatically recognize you if you don't\r
+    send them the cookie they assigned you. And there are a very\r
+    small number of sites that do strange things with cookies; they\r
+    don't work for anyone that blocks cookies by any means. Some\r
+    sites such as Microsoft explain that their content is so\r
+    wonderfully compelling that they will withhold it from you\r
+    unless you submit to their inserting cookies.</p>\r
+\r
+    <p><a name="hotmail"></a>Many free Web-based email services\r
+    require cookies. Hotmail also seems to require allowing both\r
+    <code>msn.com</code> and <code>passport.com</code> to set\r
+    cookies.</p>\r
+\r
+    <p><a name="want"></a>If you want such sites to be given your\r
+    cookies, you can use the <a href="ijbman.html#cookiefile">\r
+    cookiefile</a> option provided you are running Version 1.2 or\r
+    later yourself. Simply include the domain name of those sites\r
+    in the <i>cookiefile</i> specified by this option. If it still\r
+    doesn't work, the problem may be in other headers.</p>\r
+\r
+    <p><a name="one"></a>It's possible to let cookies out but not\r
+    in, which is enough to keep some sites happy, but not all of\r
+    them: one newspaper site seems to go into an endless frenzy if\r
+    deprived of fresh cookies. A cookiefile containing a single\r
+    line consisting of the two characters <code>&gt;*</code>\r
+    (greater-than and star) permits server-bound cookies only. The\r
+    <code>*</code> is a <a href="ijbman.html#wildcard">wildcard</a>\r
+    that matches all domains.</p>\r
+\r
+    <p><a name="else"></a>If someone else is running the Internet\r
+    Junkbuster for you and has a version that \r
+    <!-- IAM: ijbfaq.html#registration --> passes server-bound\r
+    cookies through, you can try editing your browser's cookie file\r
+    to contain just the ones you want, and restart your browser. <a\r
+    name="window"></a>To subscribe to a new service like this after\r
+    you have started using the Internet Junkbuster, you can try the\r
+    following: tell your browser to stop using the Internet\r
+    Junkbuster, fill out and submit your subscription details\r
+    (allowing that web site to set a cookie), then reconfigure your\r
+    browser to use the Internet Junkbuster again (and stop more\r
+    cookies being sent). This also requires the <a href=\r
+    "ijbman.html#cookiefile">cookiefile</a> option, and its success\r
+    depends on the Web site not wanting to change your cookies at\r
+    every session. For this reason it does not work at some major\r
+    newspaper sites, for example. <a name="buyers"></a>But you may\r
+    prefer to look at whether other sites provide the same or\r
+    better services without demanding the opportunity to track your\r
+    behavior. The web is a buyer's market where most prices are\r
+    zero: very few people pay for content with money, so why should\r
+    you pay with your privacy?</p>\r
+\r
+    <h3><a name="crumble"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Can I control cookies on a\r
+    per-site basis?</h3>\r
+\r
+    <p><a name="discard"></a>Yes, since version 1.2 the Internet\r
+    Junkbuster has included advanced cookie management facilities.\r
+    Unless you specify otherwise, cookies are discarded\r
+    (``crumbled'') by the Internet Junkbuster whether they came\r
+    from the server or the browser. In Version 1.2 and later you\r
+    can use the <a href="ijbman.html#cookiefile">cookiefile</a>\r
+    option to specify when cookies are to be passed through intact.\r
+    It uses the same syntax and <a href="ijbman.html#o_b">\r
+    matching</a> algorithm as the blockfile.</p>\r
+\r
+    <p><a name="cook"></a>If the URL matches a pattern in the <i>\r
+    <dfn>cookiefile</dfn></i> then cookies are let through in both\r
+    the browser's request for the URL and in the server's response.\r
+    <a name="directional"></a>One-way permissions can be specified\r
+    by starting the line with the <code>&gt;</code> or <code>\r
+    &lt;</code> character. For example, a cookiefile consisting of\r
+    the four lines<br>\r
+     &nbsp;&nbsp;&nbsp;<code>org</code><br>\r
+     &nbsp;&nbsp;&nbsp; <code>&gt;send-user-cookies.org</code><br>\r
+     &nbsp;&nbsp;&nbsp; <code>\r
+    &lt;accept-server-cookies.org</code><br>\r
+     &nbsp;&nbsp;&nbsp; <code>~block-all-cookies.org</code><br>\r
+     allows cookies to and from <code>.org</code> domains only,\r
+    with the following exceptions:<br>\r
+    </p>\r
+\r
+    <ol type="1">\r
+      <li><a name="fed"></a>Cookies sent from servers in the domain\r
+      <code>send-user-cookies.org</code> are blocked on their way\r
+      to the client, but cookies sent by the browser to that domain\r
+      are still be fed to them.</li>\r
+\r
+      <li><a name="take"></a>The cookies of <code>\r
+      accept-server-cookies.org</code> check in to the proxy and\r
+      are passed through to the browser, but when they come back to\r
+      the proxy they never check out.</li>\r
+\r
+      <li><a name="deny"></a>All cookies to and from <code>\r
+      block-all-cookies.org</code> are blocked.</li>\r
+    </ol>\r
+\r
+    <p><a name="paths"></a>If the <b><code>junkbuster</code></b>\r
+    was compiled with the regular expressions option they may be\r
+    used in paths. Any logging to a ``cookie jar'' is separate and\r
+    not affected.</p>\r
+\r
+    <p><a name="breadth"></a>It's important to give hosts you want\r
+    to be able to set cookies sufficient breadth. For example,\r
+    instead of <code>www.yahoo.com</code> use <code>\r
+    yahoo.com</code> because the company uses many different hosts\r
+    ending in that domain.</p>\r
+\r
+    <h3><a name="wafers"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Can I make up my own fake cookies\r
+    (wafers) to feed to servers?</h3>\r
+\r
+    <p>Yes, using the <a href="ijbman.html#wafer">wafer</a> option.\r
+    We coined the term <i><dfn>wafer</dfn></i> to describe cookies\r
+    chosen by a user, not the Web server. Servers may not find\r
+    wafers as tasty as the cookies they make themselves. But users\r
+    may enjoy controlling servers' diets for various reasons, such\r
+    as the following.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="retaliate"></a>Users who consider cookies to be\r
+      an unwelcome intrusion and a waste of their disk space can\r
+      respond in kind. By writing ``signature wafers'' they can\r
+      express their feelings about cookies, in a place that the\r
+      people in charge of them are most likely to notice.</li>\r
+\r
+      <li>\r
+        <a name="notice"></a>Sites running a proxy that logs\r
+        cookies to a file (such as the Internet Junkbuster does\r
+        with the <a href="ijbman.html#jarfile">jarfile</a> option\r
+        on) may want to notify servers that their cookies are being\r
+        intercepted, deleted or copied. One possible reason for\r
+        doing this is the uncertain copyright status of cookie\r
+        strings. Nothing here should be taken as legal advice: we\r
+        are simply raising a question for any interested parties to\r
+        consider, and make no representation that such measures are\r
+        necessary or sufficient. Concerned proxy sites might decide\r
+        to send a wafer (named ``NOTICE'' for example) containing\r
+        text along the lines of the following. \r
+\r
+        <blockquote>\r
+          <p><a name="licenses_on_cookies_refused"></a>TO WHOM IT\r
+          MAY CONCERN<i><br>\r
+          <br>\r
+           Do not send me any copyrighted information other than\r
+          the document that I am requesting or any of its necessary\r
+          components.<br>\r
+          <br>\r
+           In particular do not send me any cookies that are\r
+          subject to a claim of copyright by anybody. Take notice\r
+          that I refuse to be bound by any license condition\r
+          (copyright or otherwise) applying to any cookie.</i></p>\r
+        </blockquote>\r
+        Any company that tries to argue in court that the proxy\r
+        site was breaching their copyright in the cookies would be\r
+        met with the defense that the proxy site gave that company\r
+        the opportunity to protect its copyright by simply not\r
+        sending cookies after receiving the notice. \r
+\r
+        <p><a name="pointer"></a>Cookies can be as long as four\r
+        thousand characters, so there's plenty of space for\r
+        lawyerly verbosity, but white space, commas, and\r
+        semi-colons are <a href="ijbman.html#o_w">prohibited.</a>\r
+        Spaces can be turned into underscores. Alternatively, a URL\r
+        could be sent as the cookie value, pointing to a document\r
+        containing a notice, perhaps with a suggestive value such\r
+        as<br>\r
+         <code>\r
+        http://www.junkbusters.com/ht/en/ijbfaq.html#licenses_on_cookies_refused</code><br>\r
+\r
+         But including the notice directly would probably be\r
+        preferable because the addressee does not have to look it\r
+        up.</p>\r
+\r
+        <p><a name="vanilla"></a>The Internet Junkbuster 2.0.2\r
+        currently sends a full notice as a ``vanilla wafer'' if\r
+        cookies are being logged to a cookie jar and no other\r
+        wafers have been specified. It can be suppressed with the\r
+        <a href="ijbman.html#suppress-vanilla-wafer">\r
+        suppress-vanilla-wafer</a> option, which might be used in\r
+        situations where there is an established understanding\r
+        between the proxy and all who serve it.</p>\r
+      </li>\r
+    </ol>\r
+\r
+    <p><a name="gimme"></a>Junkbusters provides a CGI script that\r
+    lets you see your wafers as they appear to servers.</p>\r
+\r
+    <p><a name="malfunction"></a>Wafers confuse a few fragile\r
+    servers. Hotmail appears to be one of them. If this troubles\r
+    you, don't use this option.</p>\r
+\r
+    <p><a name="regardless"></a>Any wafers specified are sent to\r
+    all sites regardless of the cookiefile. <a name="compliant">\r
+    </a> They are appended after any genuine cookies, to maintain\r
+    compliance with RFC 2109 in the event that a path was specified\r
+    for a cookie. The RFC's provisions regarding the <code>$</code>\r
+    character (such as the <code>Version</code> attribute) are\r
+    transparent to the proxy; it simply quotes what was recited by\r
+    the browser.</p>\r
+\r
+    <p><a name="personalize"></a>If you want to send wafers only to\r
+    specific sites, you could try putting them your browser's\r
+    cookie file in a format conforming to the Netscape\r
+    specification, and then specify in the proxy's cookiefile that\r
+    cookies are to be sent to but not accepted from those sites, so\r
+    they can't overwrite the file. This may work with Netscape but\r
+    not all other browsers.</p>\r
+\r
+    <h3><a name="jar"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Why would anyone want to save\r
+    their cookies in a ``cookie jar?''</h3>\r
+\r
+    <p>We provided this capability just in case anyone wants it.\r
+    There are a few possible reasons.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="pay"></a>It's conceivable that marketing\r
+      companies might one day buy history files and cookie jars\r
+      from consumers in the same way that they currently pay them\r
+      to fill out survey forms. With this information they could\r
+      gather psychographic information, see which competitors'\r
+      sites the consumer has visited, and discover what advertising\r
+      is being targeted at them.</li>\r
+\r
+      <li><a name="choose"></a>Some consumers might employ\r
+      semi-automated means of sorting through their cookie jars,\r
+      selecting which ones to place in their cookies file for use\r
+      by their browsers. Their decisions could be based on payments\r
+      offered, privacy rating systems such as TRUSTe proposes, or\r
+      their own opinion of the company. It could be done manually\r
+      or with software. There's an Internet Draft on trust\r
+      certification of cookies.</li>\r
+\r
+      <li><a name="share"></a>Users may even start ``sharing''\r
+      cookies among themselves, sending back cookies that servers\r
+      generated for other visitors. Servers that aren't expecting\r
+      this possibility will be misled about their visitors'\r
+      identities. Cookies could be shared among users on a single\r
+      machine, or across continents via FTP and anonymous\r
+      remailers. <a name="disinformation"></a>Privacy activists may\r
+      promote cookie disinformation campaigns as a way to defend\r
+      the public against abuse. If a significant percentage of\r
+      people send disinformative cookies, user tracking via cookies\r
+      may become less reliable and less used.</li>\r
+    </ol>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <h2><a name="anonymity"></a> Anonymity</h2>\r
+\r
+    <p>For details on how your identity can be revealed while you\r
+    surf, see our page on privacy. Once you start using the\r
+    Internet Junkbuster you should find that much of the\r
+    information previously indicated on that page will no longer be\r
+    provided. If the <code>REMOTE HOST</code> indicating your IP\r
+    address is too close for comfort, see our suggestions below on\r
+    how to conceal your IP address. We also recommend that you\r
+    disable JavaScript and Java.</p>\r
+\r
+    <h3><a name="disclose"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; If I use the Internet Junkbuster,\r
+    will my anonymity be guaranteed?</h3>\r
+\r
+    <p>No. Your chances of remaining anonymous are improved, but\r
+    unless you are an expert on Internet security it would be\r
+    safest to assume that everything you do on the Web can be\r
+    attributed to you personally.</p>\r
+\r
+    <p><a name="happen"></a>The Internet Junkbuster removes various\r
+    information about you, but it's still possible that web sites\r
+    can find out who you are. Here's one way this can happen.</p>\r
+\r
+    <p><a name="ftp"></a>A few browsers disclose the user's email\r
+    address in certain situations, such as when transferring a file\r
+    by FTP. The Internet Junkbuster 2.0.2 does not filter the FTP\r
+    stream. If you need this feature, or are concerned about the\r
+    mail handler of your browser disclosing your email address, you\r
+    might consider products such as NSClean.</p>\r
+\r
+    <p><a name="binaries"></a>Browsers downloaded as binaries could\r
+    use non-standard headers to give out any information they can\r
+    have access to: see the manufacturer's license agreement. It's\r
+    impossible to anticipate and prevent every breach of privacy\r
+    that might occur. The professionally paranoid prefer browsers\r
+    available as source code, because anticipating their behavior\r
+    is easier.</p>\r
+\r
+    <h3><a name="should"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Why should I trust my ISP or\r
+    Junkbusters with my browsing data?</h3>\r
+\r
+    <p>You shouldn't have to trust us, and you certainly don't have\r
+    to. We do not run the proxy as a service, where we could\r
+    observe your online behavior. We provide source code so that\r
+    everyone can see that the proxy isn't doing anything\r
+    sneaky.</p>\r
+\r
+    <p><a name="awful"></a>You are already trusting your ISP not to\r
+    look at an awful lot of information on what you do. They\r
+    probably post a privacy policy on their site to reassure you.\r
+    If they run a proxy for you, using it could actually make it\r
+    slightly easier for them to monitor you, but we doubt that any\r
+    sane ISP would try this, because if it were discovered\r
+    customers would desert them.</p>\r
+\r
+    <h3><a name="logging"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Can the proxy be used for logging\r
+    who looks at what?</h3>\r
+\r
+    <p>We don't want institutions to use this software as an\r
+    instrument of surveillance. We have deliberately not provided\r
+    options to add timestamps or records of which IP addresses\r
+    accessed which URLs. However, because we publish source code\r
+    anyone can modify it to do such things, and there is no way a\r
+    remote user can find out if this is happening. Again, you need\r
+    to be able to trust the entity providing your proxy service,\r
+    but you were probably in that position even before using a\r
+    proxy.</p>\r
+\r
+    <h3><a name="header"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What private information from\r
+    server-bound headers is removed?</h3>\r
+\r
+    <p>The Internet Junkbuster pounces on the following HTTP\r
+    headers in requests to servers, unless instructed otherwise in\r
+    the options.</p>\r
+\r
+    <ol type="1">\r
+      <li><a name="from"></a>The <code>FROM</code> header, which a\r
+      few browsers use to tell your email address to servers, is\r
+      dropped unless the <a href="ijbman.html#from">from</a> option\r
+      is set.</li>\r
+\r
+      <li><a name="agent"></a>The <code>USER_AGENT</code> <a name=\r
+      "infer"></a>header is changed to indicate that the browser is\r
+      currently Mozilla (Netscape) 3.01 Gold with an unremarkable\r
+      Macintosh configuration. Misidentification helps resist\r
+      certain attacks. If your browser and hardware happen to be\r
+      accurately identified, you might want to change the default.\r
+      (Earlier versions of the Internet Junkbuster indicated\r
+      different details; by altering them periodically we aim to\r
+      hinder anyone trying to infer whether our proxy is present.)\r
+      <a name="lying"></a>If you don't like the idea of incorrectly\r
+      identifying your computer as a Mac, set it accordingly. \r
+      <!-- Aside: or read Kundera's Unbearable Lightness of Being, 5:5, ``It is a tragicomic fact..'' (p187?) --></li>\r
+\r
+      <li><a name="referer"></a>The <code>REFERER</code> header\r
+      (which indicates where the URL currently being requested was\r
+      found) is dropped. A single static referer to replace all\r
+      real referers may be specified using the <a href=\r
+      "ijbman.html#referer">referer</a> option. Where no referer is\r
+      provided by the browser, none is added; the <a href=\r
+      "ijbman.html#add-header">add-header</a> option with arguments\r
+      such as <code>-x 'Referer: http://me.me.me'</code> can be\r
+      used to send a bogus referer with every request.</li>\r
+    </ol>\r
+\r
+    <p>In Version 1.4 and later you can use the <a href=\r
+    "ijbman.html#o_r">-r @</a> option to selectively disclose\r
+    <code>REFERER</code> and <code>USER_AGENT</code> to only those\r
+    sites you nominate.</p>\r
+\r
+    <p><a name="UA"></a>Some browsers send Referer and User-Agent\r
+    information under different non-standard headers. The Internet\r
+    Junkbuster 2.0.2 stops <code>UA</code> headers, but others may\r
+    get through. This information is also available via JavaScript,\r
+    so disable it. <a name="indexers"></a>Some search engines\r
+    encode the query you typed in the URL that goes to advertisers\r
+    to target a banner ad at you, so you will need to block the ad\r
+    as well as the referer header, unless you want them (and anyone\r
+    they might buy data from) to know everything you ever search\r
+    for.</p>\r
+\r
+    <p><a name="JavaScript"></a>If you have JavaScript enabled (the\r
+    default on most browsers) servers can use it to obtain Referer\r
+    and User Agent, as well as your plug-ins. We recommend\r
+    disabling JavaScript and Java.</p>\r
+\r
+    <p><a name="response"></a>Currently no HTTP response headers\r
+    (browser bound) are removed, not even the <code>\r
+    Forwarded:</code> or <code>X-Forwarded-For:</code> headers. Nor\r
+    are any added, <a href="ijbman.html#o_y">unless requested.</a>\r
+    We are considering a more flexible header management system for\r
+    a future version.</p>\r
+\r
+    <h3><a name="breakage"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Might some things break because\r
+    header information is changed?</h3>\r
+\r
+    <p>Possibly. If used with a browser less advanced than Netscape\r
+    3.0 or IE-3, indicating an advanced browser may encourage pages\r
+    containing extensions that confuse your browser. If this\r
+    becomes a problem upgrade your browser or use the <a href=\r
+    "ijbman.html#user-agent">user-agent</a> option to indicate an\r
+    older browser. In Version 1.4 and later you can selectively\r
+    reveal your real browser to only those sites you nominate.</p>\r
+\r
+    <p><a name="Russian"></a>Because different browsers use\r
+    different encodings of Russian and Czech characters, certain\r
+    web servers convert pages on-the-fly according to the User\r
+    Agent header. Giving a User Agent with the wrong operating\r
+    system or browser manufacturer causes some sites in these\r
+    languages to be garbled; Surfers to Eastern European sites\r
+    should <a href="ijbman.html#o_r">change it</a> to something\r
+    closer.</p>\r
+\r
+    <p><a name="counters"></a>Some page access counters work by\r
+    looking at the referer; they may fail or break when\r
+    deprived.</p>\r
+\r
+    <p><a name="wired"></a>Some sites depend on getting a referer\r
+    header, such as <code>uclick.com</code>, which serves comic\r
+    strips for many newspaper sites, including <cite>\r
+    Doonsbury</cite> for the <cite>Washington Post.</cite> (If you\r
+    click on that last link, you can then get to a page containing\r
+    the strip via the same URL we've linked to under <cite>\r
+    Doonsbury</cite>, but if you click on the <cite>\r
+    Doonsbury</cite> link directly, it gives you an error message\r
+    suggesting that you use a browser that supports referers.) In\r
+    Version 1.4 and later you can use the <a href=\r
+    "ijbman.html#o_r">-r @</a> option and place a line like <code>\r
+    &gt;uclick.com</code> in your cookiefile. Wired News used to\r
+    use referer to decide whether to add a navigation column to the\r
+    page, but they have changed that.</p>\r
+\r
+    <p><a name="Intellicast"></a>The weather maps of Intellicast\r
+    have been blocked by their server when no referer or cookie is\r
+    provided. You can use the same countermeasure with a line such\r
+    as <code>&gt;208.194.150.32</code> (or simply get your weather\r
+    information elsewhere).</p>\r
+\r
+    <p><a name="decide"></a>Some software vendors, including\r
+    Download.com and Intuit use <code>USER_AGENT</code> to decide\r
+    which versions of their products to display to you. With the\r
+    default you get Mac versions.</p>\r
+\r
+    <p><a name="resort"></a>As a last resort if a site you need\r
+    doesn't seem to be working, the proxy configuration of many\r
+    browsers allow you to specify <b class="eg">No Proxy For</b>\r
+    any hostname you want.</p>\r
+\r
+    <p><a name="What"></a>We had reports that on some versions of\r
+    Netscape the What's New feature did not work with the proxy,\r
+    but we think we fixed this in Version 2.0.1.</p>\r
+\r
+    <h3><a name="misidentify"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; How is misidentifying my\r
+    browser good for security and privacy?</h3>\r
+\r
+    <p>Almost every major release of both leading browsers has\r
+    contained bugs that allow malicious servers to compromise your\r
+    privacy and security. Known bugs are quickly fixed, but\r
+    millions of copies of the affected software remain out there,\r
+    and yours is probably one of them. The header that normally\r
+    identifies your browser tells such servers exactly which\r
+    attacks to use against you. By misidentifying your browser you\r
+    reduce the likelihood that they will be able to mount a\r
+    successful attack.</p>\r
+\r
+    <h3><a name="conceal"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Does the Internet Junkbuster\r
+    conceal my IP address?</h3>\r
+\r
+    <p>Web sites get the IP address of any proxy or browser they\r
+    serve pages to. If you run the proxy on your own computer the\r
+    IP address disclosed is the same as your browser would, unless\r
+    you use the <a href="ijbman.html#forwardfile">forwardfile</a>\r
+    option is used to chain to another proxy, in which case servers\r
+    only get the last IP address in the chain. Chaining slightly\r
+    slows browsing of course, but it improves anonymity.</p>\r
+\r
+    <h3><a name="ident"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Does the Internet Junkbuster\r
+    thwart identification by identd?</h3>\r
+\r
+    <p>We think so, provided you are not the user running the\r
+    proxy. If your computer (or your ISP's) is running the <code>\r
+    identd</code> demon, servers can ask it for the identity of the\r
+    user making the request at time you request a page from them.\r
+    But if you're going through a proxy, they will identify the\r
+    user name associated with the proxy, not you. A visit to\r
+    http://ident.junkbusters.com lets you see what's happening.\r
+    This test is (quite rightly) blocked by many firewalls; just\r
+    interrupt the transfer if you get an abnormal wait after\r
+    clicking. Running other applications may also expose you via\r
+    <code>identd</code>; the proxy of course doesn't help then.</p>\r
+\r
+    <h3><a name="detect"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Can web sites tell that I'm using\r
+    the Internet Junkbuster?</h3>\r
+\r
+    <p>With the default options the proxy doesn't announce itself.\r
+    Obvious indications such as Keep-Alive headers are <a href=\r
+    "ijbman.html#o_x">deleted,</a> but sites might notice that you\r
+    can cancel cookies faster than any human could possibly click\r
+    on a mouse. (If you want to provide a plausible explanation for\r
+    this, change the User Agent header to a cookie-free or\r
+    cookie-crunching browser).</p>\r
+\r
+    <p><a name="figure"></a>But when certain options are used they\r
+    could figure out something's going on, even if they're not\r
+    pushing cookies. If you use blocking they can tell from their\r
+    logs that the graphics in their pages are not being requested\r
+    selectively. The <a href="ijbman.html#add-forwarded-header">\r
+    add-forwarded-header</a> option explicitly announces to the\r
+    server that a proxy is present, and sending them wafers is of\r
+    course a dead giveaway.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <h2><a name="security"></a> Security</h2>\r
+\r
+    <h3><a name="encrypt"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; What happens with Secure\r
+    Documents (SSL, https:)?</h3>\r
+\r
+    <p>If you enter a ``Secure Document Area,'' cookies and other\r
+    header information such as User Agent and Referer are sent\r
+    encrypted, so they cannot be filtered. We recommend getting\r
+    your browser to alert you when this happens. (On Netscape: <b\r
+    class="eg">Options</b>; <b class="eg">Security</b>; <b class=\r
+    "eg">General</b>; <b class="eg">Show an alert before entering a\r
+    secure document space</b>.) We also recommend adding the line\r
+    <code>:443</code> to the blockfile to stop all but sites\r
+    specified in an exception after that line from using SSL.</p>\r
+\r
+    <p><a name="passage"></a>It may be possible to filter encrypted\r
+    cookies by combining the blocking proxy with a cryptographic\r
+    proxy along the lines of SafePassage, but we have not tried\r
+    this.</p>\r
+\r
+    <h3><a name="ssl"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Will using this as my Security\r
+    Proxy compromise security?</h3>\r
+\r
+    <p>We're not security experts, but we don't think so. The whole\r
+    point of SSL is that the contents of messages are \r
+    <!-- IEM: http://addy.com/dc/html/what_is_ssl_.html -->\r
+    encrypted by the time they leave the browser and the server.\r
+    Eavesdroppers (including proxies) can see where your messages\r
+    are going whether you are running a proxy or not, but they only\r
+    get to see the contents after they have been encrypted.</p>\r
+\r
+    <h3><a name="restrict"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Can I restrict use of the proxy\r
+    to a set of nominated IP addresses?</h3>\r
+\r
+    <p>Yes, we added an <a href="ijbman.html#aclfile">access\r
+    control</a> file in Version 2.0. But before you use it please\r
+    consider why you want to do it. If the reason is security, it\r
+    probably means you need a firewall.</p>\r
+\r
+    <p><a name="selective"></a>The <a href=\r
+    "ijbman.html#listen-address">listen-address</a> option provides\r
+    a way of binding the proxy to a single IP address/port. The\r
+    right way to do this is to choose a port inside your firewall,\r
+    and deny access to it to those outside the firewall. The\r
+    Internet Junkbuster is not a firewall proxy; it should not be\r
+    expected to solve security problems.</p>\r
+\r
+    <p><a name="firewall"></a>For background information on\r
+    firewalls, see Yahoo or a magazine article or these well-known\r
+    books: <cite>Firewalls and Internet Security: Repelling the\r
+    Wily Hacker</cite> by William R. Cheswick and Steven M.\r
+    Bellovin or <cite>Building Internet Firewalls</cite> by D.\r
+    Brent Chapman and Elizabeth D. Zwicky. There's \r
+    <!-- IEM: http://www.wmd.de/wmd/staff/pauck/misc/fwtk_on_linux.html -->\r
+    free Linux software available, and a large number of commercial\r
+    products and services. For an excellent security overview,\r
+    primer, and compendium reference, see <cite>Practical Unix and\r
+    Internet Security</cite> by Simson Garfinkel and Gene\r
+    Spafford.</p>\r
+\r
+    <h3><a name="others"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Are there any security risks for\r
+    ISPs or others who offer the proxy?</h3>\r
+\r
+    <p>Yes. As with any service offered over the Internet, hackers\r
+    can try to misuse it. A well-run ISP will have professionals\r
+    who are experienced at assessing and containing these\r
+    risks.</p>\r
+\r
+    <p><a name="outside"></a>It's possible to set up your machine\r
+    so that other people can have access to your proxy, but if you\r
+    lack expertise in computer security you probably shouldn't have\r
+    your computer configured to offer this or any other service to\r
+    the outside world.</p>\r
+\r
+    <p><a name="attack"></a>Hackers can attempt to gain access to\r
+    the machine by various attacks, which we have tried to guard\r
+    against but don't guarantee to thwart. They can also use the\r
+    ``anonymizing'' quality of proxies to try to cover their tracks\r
+    while hacking other computers. For this reason we recommend\r
+    preventing it being used as an anonymous <code>telnet</code> by\r
+    putting the pattern <code>:23</code> in the blockfile (it's\r
+    included as standard equipment). (Actually the current\r
+    implementation incidentally blocks telnet due to the way\r
+    headers are handled, but it's best not to rely on this.) If you\r
+    wish to block all ports except the default HTTP port 80, you\r
+    can put the lines<br>\r
+     &nbsp;&nbsp;&nbsp;<code>:</code><br>\r
+     &nbsp;&nbsp;&nbsp;<code>~:80</code><br>\r
+     at the beginning of the blockfile, but be aware that some\r
+    servers run on non-default ports (e.g. 8080). You might also\r
+    want to add the line <code>~:443</code> to allow SSL.</p>\r
+\r
+    <p><a name="root"></a>On UNIX &reg; systems it is neither\r
+    necessary nor desirable for the proxy to run as root.</p>\r
+\r
+    <p><a name="patched"></a>Versions 2.0.1 and below may be\r
+    vulnerable to remote exploitation of a memory buffer bug; for\r
+    security reasons all users are encouraged to upgrade.</p>\r
+\r
+    <p><a name="holes"></a>If you find any security holes in the\r
+    code please tell us, along with any suggestions you may have\r
+    for fixing it. However, we do not claim that we will be able to\r
+    do so.</p>\r
+\r
+    <p><a name="useful"></a>We distribute this code in the hope\r
+    that people will find it useful, but we provide no warranty for\r
+    it, and we are not responsible for anyone's use or misuse of\r
+    it.</p>\r
+\r
+    <p><a name="updates"></a>You may also want to check back\r
+    periodically for updated versions of the code. We do not\r
+    currently maintain a mailing list. To get quick updates,\r
+    bookmark our Distribution Information page.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <p class="sans"><a href="http://ijbswa.sourceforge.net/">\r
+    Website</a> <b class="dot">&middot;</b> <a href="ijbman.html">\r
+    Manual</a> <b class="dot">&middot;</b> <b>FAQ</b> <b class=\r
+    "dot">&middot;</b> <a href="gpl.html">GPL</a></p>\r
+\r
+    <p class="sans"><small><small><a href="gpl.html#text">\r
+    Copyright</a> &copy; 1996-8 <a href=\r
+    "http://www.junkbusters.com/">Junkbusters</a> <a href=\r
+    "http://www.junkbusters.com/ht/en/legal.html#marks">&reg;</a>\r
+    Corporation. <a href="gpl.html#text">Copyright</a> &copy; 2001\r
+    <a href="http://sourceforge.net/projects/ijbswa/">Jon\r
+    Foster</a>. Copying and distribution permitted under the <a\r
+    href="gpl.html">GNU</a> General Public\r
+    License.</small></small></p>\r
+\r
+    <p><small><code><a href=\r
+    "http://sourceforge.net/projects/ijbswa/">\r
+    http://sourceforge.net/projects/ijbswa/</a></code></small></p>\r
+  </body>\r
+</html>\r
+\r
diff --git a/doc/obsolete/ijbman.html b/doc/obsolete/ijbman.html
new file mode 100644 (file)
index 0000000..8329e57
--- /dev/null
@@ -0,0 +1,708 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
+<!-- $Id: ijbman.html,v 1.2 2001/05/17 22:56:17 jongfoster Exp $\r
+\r
+     See copyright details at end of file\r
+\r
+     After changing this file, please run it through "HTML Tidy"\r
+     (from http://www.w3.org/People/Raggett/tidy/)\r
+     It should have no warnings or errors.\r
+-->\r
+\r
+<html>\r
+  <head>\r
+    <title>Internet Junkbuster Technical Information</title>\r
+    <meta name="description" content=\r
+    "The manual page for the Internet Junkbuster, free software to removes banner ads, cookies, and other stuff you don't want from your web browser.">\r
+    <meta name="keywords" content=\r
+    "stop, junk, busters, junkbusters, junkbuster, mail, email, e-mail, direct, spam, privacy, sharing, names, renting, direct, marketing, database, databases, junk mail, lists, environment, consumer, sending, opt out ">\r
+<style type="text/css">\r
+<!--\r
+h2           { text-align: Center; font-family: arial, helvetica, sans-serif }\r
+p.sans       { font-family: arial, helvetica, sans-serif }\r
+b.dot        { color: #FF0000 }\r
+b.eg         { font-family: arial, helvetica, sans-serif }\r
+-->\r
+</style>\r
+  </head>\r
+\r
+  <body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink=\r
+  "#787878">\r
+    <p class="sans"><a href="http://ijbswa.sourceforge.net/">\r
+    Website</a> <b class="dot">&middot;</b> <b>Manual</b> <b class=\r
+    "dot">&middot;</b> <a href="ijbfaq.html">FAQ</a> <b class=\r
+    "dot">&middot;</b> <a href="gpl.html">GPL</a></p>\r
+\r
+    <h1 align="center"><a name="top_of_page"></a>Internet\r
+    J<small>UNK<i style="color: #FF0000">BUSTER</i></small>\r
+    Technical Information</h1>\r
+\r
+    <p align="center" class="sans"><a href="#description">\r
+    Options</a> <b class="dot">&middot;</b> <a href="#show">\r
+    Checking Options</a> <b class="dot">&middot;</b> <a href=\r
+    "#install">Installation</a> <b class="dot">&middot;</b> <a\r
+    href="#copyright">Copyright</a> <b class="dot">&middot;</b> <a\r
+    href="ijbfaq.html#top_of_page">(FAQ)</a></p>\r
+\r
+    <h1>This document is out of date</h1>\r
+\r
+    <p><b>Development of JunkBuster is ongoing and this document is\r
+    no longer current. However, it may provide some assistance. If\r
+    you have problems, please use the <a href=\r
+    "http://groups.yahoo.com/group/junkbuster-users/">Yahoo Groups\r
+    mailing list</a> (which includes an archive of mail), the\r
+    SourceForge.net <a href=\r
+    "http://sourceforge.net/projects/ijbswa/">project page</a>, or\r
+    see the project's <a href="http://ijbswa.sourceforge.net/">home\r
+    page</a>. Please also bear in mind that versions 2.9.x of\r
+    JunkBuster are development releases, and are not production\r
+    quality.</b></p>\r
+\r
+    <h2><a name="man"></a>Manual Page</h2>\r
+\r
+    <p>A copy of this page in standard <code>man</code> macro\r
+    format is included in the <a href="ijbfaq.html#tar">tar\r
+    archive</a>.</p>\r
+\r
+    <h3><a name="name"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Name</h3>\r
+\r
+    <p><b><code>junkbuster</code></b> - The Internet Junkbuster\r
+    Proxy <a href=\r
+    "http://www.junkbusters.com/ht/en/legal.html#marks"><small>\r
+    <sup>TM</sup></small></a></p>\r
+\r
+    <h3><a name="synopsis"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Synopsis</h3>\r
+\r
+    <p><code><b>junkbuster</b></code> <i>configfile</i> (Unix)<br>\r
+     <b><code>junkbstr.exe</code></b> [<i>configfile</i>]\r
+    (Windows)</p>\r
+\r
+    <h3><a name="description"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; Description</h3>\r
+\r
+    <p><b><code>junkbuster</code></b> is an instrumentable proxy\r
+    that filters the HTTP stream between web servers and browsers.\r
+    Its main purposes are to block adverts and enhance privacy.</p>\r
+\r
+    <p><a name="dual"></a>It is configured using a configuration\r
+    file and several files listing URL patterns.&nbsp; The\r
+    configuration file must be specified on the command line.&nbsp;\r
+    The Windows version will default to using the configuration\r
+    file <code>junkbstr.ini</code> if it exists and no argument was\r
+    given.</p>\r
+\r
+    <p><a name="reread"></a>All files except the main configuration\r
+    file are checked for changes before each page is fetched, so\r
+    they may edited without restarting the proxy.</p>\r
+\r
+    <h4>Options</h4>\r
+\r
+    <dl>\r
+      <dt><i><a name="o_b"></a></i><a name=\r
+      "blockfile"></a><code>blockfile</code>&nbsp;&nbsp; <i>\r
+      blockfile</i></dt>\r
+\r
+      <dd>\r
+        <p><a href="ijbfaq.html#blocking">Block</a> requests to\r
+        URLs matching any pattern given in the lines of the <i>\r
+        blockfile</i>. The <b><code>junkbuster</code></b> instead\r
+        returns status 202, indicating that the request has been\r
+        accepted (though not completed), and a <a href=\r
+        "ijbfaq.html#show">message identifying itself</a> (though\r
+        the browser may display only a broken image icon).&nbsp;\r
+        The syntax of a pattern is <code>\r
+        [domain][:port][/path]</code> (the <code>http://</code> or\r
+        <code>https://</code> protocol part is omitted). To decide\r
+        if a pattern matches a target, the domains are compared\r
+        first, then the paths.</p>\r
+\r
+        <p><a name="compare"></a>To compare the domains, the\r
+        pattern domain and the target domain specified in the URL\r
+        are each broken into their components. (Components are\r
+        separated by the <code>.</code> (period) character.) Next\r
+        each of the target components is compared with the\r
+        corresponding pattern component: last with last,\r
+        next-to-last with next-to-last, and so on. (This is called\r
+        <i><dfn>right-anchored</dfn></i> matching.) If all of the\r
+        pattern components find their match in the target, then the\r
+        domains are considered a match. Case is irrelevant when\r
+        comparing domain components.</p>\r
+\r
+        <p><a name="substring"></a>A successfully matching pattern\r
+        can be an anchored substring of a target, but not vice\r
+        versa. Thus if a pattern doesn't specify a domain, it\r
+        matches all domains. <a name="wildcard"></a>Furthermore,\r
+        when comparing two components, the components must either\r
+        match in their entirety or up to a wildcard <code>*</code>\r
+        (star character) in the pattern. The wildcard feature\r
+        implements only a "prefix" match capability ("abc*" vs.\r
+        "abcdefg"), not suffix matching ("*efg" vs. "abcdefg") or\r
+        infix matching ("abc*efg" vs. "abcdefg"). The feature is\r
+        restricted to the domain component; it is unrelated to the\r
+        optional regular expression feature in the path <a href=\r
+        "#regex">(described below).</a></p>\r
+\r
+        <p><a name="numeric"></a>If a numeric port is specified in\r
+        the pattern domain, then the target port must match as\r
+        well. The default port in a target is port 80.</p>\r
+\r
+        <p><a name="onward"></a>If the domain and port match, then\r
+        the target URL path is checked for a match against the path\r
+        in the pattern. Paths are compared with a simple\r
+        case-sensitive left-anchored substring comparison. Once\r
+        again, the pattern can be an anchored substring of the\r
+        target, but not vice versa. A path of <code>/</code>\r
+        (slash) would match all paths. Wildcards are not considered\r
+        in path comparisons.</p>\r
+\r
+        <p><a name="example"></a>For example, the target URL<br>\r
+         &nbsp;&nbsp;&nbsp; <code>\r
+        the.yellow-brick-road.com/TinMan/has_no_brain</code><br>\r
+         would be matched (and blocked) by the following\r
+        patterns<br>\r
+         &nbsp;&nbsp;&nbsp; <code>yellow-brick-road.com</code><br>\r
+         and<br>\r
+         &nbsp;&nbsp;&nbsp;<code>Yellow*.COM</code><br>\r
+         and<br>\r
+         &nbsp;&nbsp;&nbsp;<code>/TinM</code><br>\r
+         but not<br>\r
+         &nbsp;&nbsp;&nbsp; <code>\r
+        follow.the.yellow-brick-road.com</code><br>\r
+         or<br>\r
+         &nbsp;&nbsp;&nbsp;<code>/tinman</code><br>\r
+        </p>\r
+\r
+        <p><a name="comments"></a>Comments in a blockfile start\r
+        with a <code>#</code> (hash) character and end at a new\r
+        line. Blank lines are also ignored.</p>\r
+\r
+        <p><a name="except"></a>Lines beginning with a <code>\r
+        ~</code> (tilde) character are taken to be <a href=\r
+        "ijbfaq.html#exceptions">exceptions:</a> a URL blocked by\r
+        previous patterns that matches the rest of the line is let\r
+        through. (The last match wins.)</p>\r
+\r
+        <p><a name="regex"></a>Patterns may contain POSIX <a href=\r
+        "ijbfaq.html#regex">regular expressions</a> provided the\r
+        <b><code>junkbuster</code></b> was compiled with this\r
+        option (the default in Version 2.0 on). The idiom <code>\r
+        /*.*/ad</code> can then be used to match any URL containing\r
+        <code>/ad</code> (such as <code>\r
+        http://nomatterwhere.com/images/advert/g3487.gif</code> for\r
+        example). These expressions <a href="#substring">don't\r
+        work</a> in the domain part.</p>\r
+\r
+        <p><a name="rereads"></a>In version 1.3 and later the\r
+        blockfile and cookiefile are checked for changes before\r
+        each request.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_w"></a></i><a name=\r
+      "wafer"></a><code>wafer</code>&nbsp;&nbsp; <i>\r
+      NAME=VALUE</i></dt>\r
+\r
+      <dd>\r
+        <p>Specifies a pair to be sent as a cookie with every\r
+        request <a href="ijbfaq.html#wafers">to the server.</a>\r
+        (Such boring cookies are called <i>wafers</i>.) This option\r
+        may be called more than once to generate multiple wafers.\r
+        The original Netscape specification prohibited semi-colons,\r
+        commas and white space; these characters will be\r
+        URL-encoded if used in wafers. \r
+        <!-- Aside: genuine cookies are not encoded --> \r
+        <!-- Aside: we could use quoted string as specified in the new RFC -->\r
+        The Path and Domain attributes are not currently\r
+        supported.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_c"></a></i><a name=\r
+      "cookiefile"></a><code>cookiefile</code>&nbsp;&nbsp; <i>\r
+      cookiefile</i></dt>\r
+\r
+      <dd>\r
+        <p>Enforce the cookie management policy specified in the\r
+        <i>cookiefile.</i> <a name="java"></a>If this option is not\r
+        used all cookies are silently crunched, so that users who\r
+        never want cookies aren't bothered by browsers asking\r
+        whether each cookie should be accepted. However, cookies\r
+        can <a href="ijbfaq.html#breakthrough">still get\r
+        through</a> via <a href=\r
+        "http://www.junkbusters.com/ht/en/links.html#javascript">\r
+        JavaScript</a> and SSL, so alerts should be left on.</p>\r
+\r
+        <p><a name="dropping"></a>In Version 1.2 and later this\r
+        option must be followed by a <a href="ijbfaq.html#crumble">\r
+        filename</a> containing instructions on which sites are\r
+        allowed to receive and set cookies. <a name="drop"></a>By\r
+        default cookies are dropped in both the browser's request\r
+        and the server's response, unless the URL requested matches\r
+        an entry in the <i>cookiefile</i>. The matching algorithm\r
+        is the same as for the blockfile. A leading <code>\r
+        &gt;</code> character allows <a href=\r
+        "ijbfaq.html#directional">server-bound</a> cookies only; a\r
+        <code>&lt;</code> allows only browser-bound cookies; a\r
+        <code>~</code> character stops cookies in <a href=\r
+        "ijbfaq.html#crumble">both directions.</a> Thus a\r
+        cookiefile containing a single line with the two characters\r
+        <code>&gt;*</code> will pass on all cookies to servers but\r
+        not give any new ones to the browser.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_j"></a></i><a name=\r
+      "jarfile"></a><code>jarfile</code>&nbsp;&nbsp; <i>\r
+      jarfile</i></dt>\r
+\r
+      <dd>\r
+        <p>All Set-cookie attempts by the server are <a href=\r
+        "ijbfaq.html#jar">logged</a> to <i>jarfile</i>. If no wafer\r
+        is specified, one containing a <a href=\r
+        "ijbfaq.html#notice">canned notice</a> (the <i>vanilla\r
+        wafer</i>) is added as an alert to the server unless the <a\r
+        href="#suppress-vanilla-wafer">suppress-vanilla-wafer</a>\r
+        option is invoked.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_v"></a></i><a name=\r
+      "suppress-vanilla-wafer"></a><code>suppress-vanilla-wafer</code></dt>\r
+\r
+      <dd>\r
+        <p>Suppress the vanilla wafer.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_t"></a></i><a name=\r
+      "from"></a><code>from</code>&nbsp;&nbsp;<i>from</i></dt>\r
+\r
+      <dd>\r
+        <p>If the browser <a href="ijbfaq.html#from">discloses an\r
+        email address</a> in the <code>FROM</code> header (most\r
+        don't), replace it with <i>from.</i> If <i>from</i> is set\r
+        to <b>.</b> (the period character) the <code>FROM</code> is\r
+        passed to the server unchanged. The default is to delete\r
+        the <code>FROM</code> header.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_r"></a></i><a name=\r
+      "referer"></a><code>referer</code>&nbsp;&nbsp; <i>\r
+      referer</i></dt>\r
+\r
+      <dd>\r
+        <p>Whenever the browser discloses the URL that <a href=\r
+        "ijbfaq.html#referer">led to</a> the current request,\r
+        replace it with <i>referer.</i> If <i>referer</i> is set to\r
+        <b>.</b> (period) the URL is passed to the server\r
+        unchanged. If referer is set to <b>@</b> (at) the URL is\r
+        sent in cases where the cookiefile specifies that a cookie\r
+        would be sent. (No way to send bogus referers selectively\r
+        is provided.) The default is to delete Referer.</p>\r
+\r
+        <p><a name="referrer"></a>Junkbuster also accepts the\r
+        spelling <code>referrer</code>, which most dictionaries\r
+        consider correct.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_u"></a></i><a name=\r
+      "user-agent"></a><code>user-agent</code>&nbsp;&nbsp; <i>\r
+      user-agent</i></dt>\r
+\r
+      <dd>\r
+        <p>Information disclosed by the browser <a href=\r
+        "ijbfaq.html#agent">about itself</a> is replaced with the\r
+        value <i>user-agent.</i> If <i>user-agent</i> is set to <b>\r
+        .</b> (period) the <code>User-Agent</code> header is passed\r
+        to the server unchanged, along with any <code>UA</code>\r
+        headers produced by MS-IE (which would otherwise be\r
+        deleted). If <i>user-agent</i> is set to <b>@</b> (at)\r
+        these headers are sent unchanged in cases where the\r
+        cookiefile specifies that a cookie would be sent, otherwise\r
+        only default <code>User-Agent</code> header is sent. That\r
+        default is Mozilla/3.0 (Netscape) with an unremarkable <a\r
+        href="ijbfaq.html#infer">Macintosh</a> configuration. If\r
+        used with a browser less advanced than Mozilla/3.0 or IE-3,\r
+        the default may encourage pages containing extensions that\r
+        confuse the browser.</p>\r
+      </dd>\r
+\r
+      <dt><a name="o_h"></a><a name=\r
+      "listen-address"></a><code>listen-address</code>&nbsp;&nbsp;\r
+      <i>[host][:port]</i></dt>\r
+\r
+      <dd>\r
+        <p>If <i>host</i> is specified, bind the <b><code>\r
+        junkbuster</code></b> to that IP address. If a <i>port</i>\r
+        is specified, use it. The default port is 8000; the default\r
+        host is <code>localhost</code>.</p>\r
+\r
+        <p>This default host setting means that you can only\r
+        connect to the proxy from ther local computer. This is a\r
+        security measure - if you allow anyone to use the proxy,\r
+        then hackers or fraudsters could use it to help hide their\r
+        identity. It also provides a lot of protection against any\r
+        undiscovered security flaws in JunkBuster - if they can't\r
+        connect to it, then they can't attack it.</p>\r
+\r
+        <p>If you change this value, we recommend you <i>either</i>\r
+        set the host to <code>localhost</code>:<br>\r
+         &nbsp;&nbsp;&nbsp;<code>listen-address\r
+        localhost:8080</code><br>\r
+         <i>or</i>, if you want to share a single internet\r
+        connection over your internal network, then set it to the\r
+        address of your internal ethernet card:<br>\r
+         &nbsp;&nbsp;&nbsp;<code>listen-address\r
+        10.1.1.1:8080</code><br>\r
+         (replace 10.1.1.1 with your internal IP address), <i>\r
+        or</i> set up an <i><a href="#aclfile">aclfile</a></i>. To\r
+        make the proxy accessible from everywhere (e.g. if you're\r
+        using an access control list or if you just don't care\r
+        about security), specify just the port number - e.g:<br>\r
+         &nbsp;&nbsp;&nbsp;<code>listen-address :8000</code><br>\r
+         (This binds the proxy to <b>all</b> IP addresses\r
+        (<code>INADDR_ANY</code>)).</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_f"></a></i><a name=\r
+      "forwardfile"></a><code>forwardfile</code>&nbsp;&nbsp; <i>\r
+      forwardfile</i></dt>\r
+\r
+      <dd>\r
+        <p>Junkbuster has a flexible syntax for forwarding HTTP\r
+        requests. This is used e.g. if you are behind a firewall\r
+        and need to connect through it, or if you want to use a\r
+        cacheing proxy to speed up your web browsing.</p>\r
+\r
+        <p>Every line in the forwardfile consists of four\r
+        components, seperated by whitespace. These are:<br>\r
+        <br>\r
+         <code><i>target &nbsp; forward_to &nbsp; via_gateway_type\r
+        &nbsp; gateway</i></code></p>\r
+\r
+        <p><i>target</i> is a pattern used to select which line of\r
+        the forwardfile is used. "<code>*</code>" is the most\r
+        commonly used value, and matches every URL. As usual, the\r
+        last matching <i>target</i> wins. (If no pattern matches, a\r
+        direct connection will be used)</p>\r
+\r
+        <p><i>forward_to</i> specifies the HTTP proxy server to\r
+        use, or "<code>.</code>" for none. This is used to connect\r
+        to a cacheing proxy such as Squid, and for most types of\r
+        firewall. The port number defaults to 8000 if it is not\r
+        specified.</p>\r
+\r
+        <p>Here is a typical line.</p>\r
+<pre>\r
+*         lpwa.com:8000      .      .\r
+</pre>\r
+\r
+        <p>The target domain need not be a fully qualified\r
+        hostname; it can be a general domain such as <code>\r
+        com</code> or <code>co.uk</code> or even just a port\r
+        number. <a name="nose"></a>For example, because <a href=\r
+        "http://lpwa.com">LPWA</a> does not handle <a href=\r
+        "ijbfaq.html#encrypt">SSL</a>, the line above will\r
+        typically be followed by a line such as</p>\r
+<pre>\r
+:443    .      .      .\r
+</pre>\r
+\r
+        <p>to allow SSL transactions to proceed directly. The\r
+        cautious would also add an entry in their blockfile to stop\r
+        transactions to port 443 for all but specified trusted\r
+        sites.</p>\r
+\r
+        <p><a name="loop"></a>Configure with care: no loop\r
+        detection is performed. When setting up chains of proxies\r
+        that might loop back, try adding <a href="#squid">\r
+        Squid.</a></p>\r
+\r
+        <p><i>via_gateway_type</i> and <i>gateway</i> are used to\r
+        support SOCKS proxies. Some firewalls provide this type of\r
+        proxy. If you do not not want to use a SOCKS proxy, specify\r
+        both of these fields as "<code>.</code>".</p>\r
+\r
+        <p><a name="configure"></a><a name="identify"></a>Note that\r
+        JunkBuster is a SOCKS <b>client</b>, <b>not</b> a SOCKS <b>\r
+        server</b>. The user's browser should <b>not</b> be <a\r
+        href="ijbfaq.html#socks">configured</a> to use <code>\r
+        SOCKS</code>; the proxy conducts the negotiations, not the\r
+        browser.</p>\r
+\r
+        <p>The <code>SOCKS4</code> protocol may be specified by\r
+        setting <i>via_gateway_type</i> to <code>socks</code> or\r
+        <code>socks4</code>. The <code>SOCKS4A</code> protocol is\r
+        specified as <code>socks4a</code>. The <code>SOCKS5</code>\r
+        protocol is not currently supported.</p>\r
+\r
+        <p><i>gateway</i> should be the host and port of the SOCKS\r
+        server. If you just specify a hostname, then the port\r
+        number defaults to 1080.</p>\r
+\r
+        <p>The user identification capabilities of <code>\r
+        SOCKS4</code> are deliberately not used; the user is always\r
+        identified to the <code>SOCKS</code> server as <code>\r
+        userid=anonymous</code>. If the server's policy is to\r
+        reject requests from <code>anonymous</code>, the proxy will\r
+        not work. Use a <a href="#o_d">debug</a> value of 3 to see\r
+        the status returned by the server.</p>\r
+\r
+        <p>If you specify both a HTTP proxy (with <i>\r
+        forward_to</i>) and a SOCKS proxy (with <i>gateway</i>)\r
+        then the SOCKS proxy is used to connect to the HTTP proxy.\r
+        If you just specify a SOCKS proxy, it is used to connect\r
+        directly to the websites.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_d"></a></i><a name=\r
+      "debug"></a><code>debug</code>&nbsp;&nbsp;<i>N</i></dt>\r
+\r
+      <dd>\r
+        <p>Set debug mode. The most common value is 1, to <a href=\r
+        "ijbfaq.html#pinpoint">pinpoint</a> offensive URLs, so they\r
+        can be added to the blockfile. The value of <b>N</b> is a\r
+        bitwise logical-OR of the following values:<br>\r
+         1 = URLs (show each URL requested by the browser);<br>\r
+         2 = Connections (show each connection to or from the\r
+        proxy);<br>\r
+         4 = I/O (log I/O errors);<br>\r
+         8 = Headers (as each header is scanned, show the header\r
+        and what is done to it);<br>\r
+         16 = Log everything (including debugging traces and the\r
+        contents of the pages).<br>\r
+         32 = Record accesses in Common Log Format, as used by most\r
+        web and proxy servers.</p>\r
+\r
+        <p><a name="or"></a>Multiple <code>debug</code> lines are\r
+        permitted; they are logical OR-ed together.</p>\r
+\r
+        <p><a name="single"></a>Because most browsers send several\r
+        requests in parallel the debugging output may appear\r
+        intermingled, so the <a href="#single-threaded">\r
+        single-threaded</a> option is recommended when using <a\r
+        href="#debug">debug</a> with <b>N</b> greater than 1. \r
+        <!-- Aside: Yes, it's clumsy, but it's easy to parse. --></p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_y"></a></i><a name=\r
+      "add-forwarded-header"></a><code>add-forwarded-header</code></dt>\r
+\r
+      <dd>\r
+        <p>Add <code>X-Forwarded-For</code> headers to the\r
+        server-bound HTTP stream indicating the client IP address\r
+        <a href="ijbfaq.html#detect">to the server,</a> in the new\r
+        style of <a href="#squid">Squid 1.1.4.</a> If you want the\r
+        traditional <code>HTTP_FORWARDED</code> response header,\r
+        add it manually with the <a href="#o_x">-x</a> option. This\r
+        also allows other <code>X-Forwarded-For</code> headers to\r
+        be transmitted - usually they are discarded.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_x"></a></i><a name=\r
+      "add-header"></a><code>add-header</code>&nbsp;&nbsp; <i>\r
+      HeaderText</i></dt>\r
+\r
+      <dd>\r
+        <p>Add the <i>HeaderText</i> verbatim to requests to the\r
+        server. Typical uses include adding old-style forwarding\r
+        notices such as <code>Forwarded: by\r
+        http://pro-privacy-isp.net</code> and reinstating the\r
+        <code>Proxy-Connection: Keep-Alive</code> header (which the\r
+        <b><code>junkbuster</code></b> deletes so as <a href=\r
+        "ijbfaq.html#detect">not</a> to reveal its existence). No\r
+        checking is done for correctness or plausibility, so it can\r
+        be used to throw any old trash into the server-bound HTTP\r
+        stream. Please don't litter. \r
+        <!-- Aside: this represents "more than enough rope" --></p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_s"></a></i><a name=\r
+      "single-threaded"></a><code>single-threaded</code></dt>\r
+\r
+      <dd>\r
+        <p>Doesn't <code>fork()</code> a separate process (or\r
+        create a separate thread) to handle each connection. Useful\r
+        when debugging to keep the process single threaded.</p>\r
+      </dd>\r
+\r
+      <dt><i><a name="o_l"></a></i><a name=\r
+      "logfile"></a><code>logfile</code>&nbsp;&nbsp; <i>\r
+      logfile</i></dt>\r
+\r
+      <dd>\r
+        <p>Write all debugging data into <i>logfile.</i> The\r
+        default <i>logfile</i> is the standard output.</p>\r
+      </dd>\r
+\r
+      <dt><br>\r
+       <a name="aclfile"></a><code>aclfile</code>&nbsp;&nbsp; <i>\r
+      aclfile</i></dt>\r
+\r
+      <dd>\r
+        <p>Unless this option is used, the proxy talks to anyone\r
+        who can connect to it, and everyone who can has equal\r
+        permissions on where they can go. An access file allows\r
+        restrictions to be placed on these two policies, by\r
+        distinguishing some <i><dfn>source</dfn></i> IP addresses\r
+        and/or some <i><dfn>destination</dfn></i> addresses. (If a\r
+        <a href="#forwardfile">forwarder or a gateway</a> is being\r
+        used, its address is considered the destination address,\r
+        not the ultimate IP address of the URL requested.)</p>\r
+\r
+        <p><a name="permit"></a>Each line of the access file begins\r
+        with either the word <code>permit</code> or <code>\r
+        deny</code> followed by source and (optionally) destination\r
+        addresses to be matched against those of the HTTP request.\r
+        The last matching line specifies the result: if it was a\r
+        <code>deny</code> line or if no line matched, the request\r
+        will be refused.</p>\r
+\r
+        <p><a name="various"></a>A source or destination can be\r
+        specified as a single numeric IP address, or with a\r
+        hostname, provided that the host's name can be resolved to\r
+        a numeric address: this cannot be used to block all <code>\r
+        .mil</code> domains for example, because there is no single\r
+        address associated with that domain name. Either form may\r
+        be followed by a slash and an integer <code>N</code>,\r
+        specifying a subnet mask of <code>N</code> bits. For\r
+        example, <code>permit 207.153.200.72/24</code> matches the\r
+        entire Class-C subnet from 207.153.200.0 through\r
+        207.153.200.255. (A netmask of 255.255.255.0 corresponds to\r
+        24 bits of ones in the netmask, as with <code>\r
+        *_MASKLEN=24</code>.) A value of 16 would be used for a\r
+        Class-B subnet. A value of zero for <code>N</code> in the\r
+        subnet mask length will cause any address to match; this\r
+        can be used to express a default rule. For more information\r
+        see the example file provided with the distribution.</p>\r
+\r
+        <p><a name="false"></a>If you like these access controls\r
+        you should probably have <a href="ijbfaq.html#firewall">\r
+        firewall</a>; they are not intended to replace one.</p>\r
+      </dd>\r
+\r
+      <dt><br>\r
+       <a name="trustfile"></a><code>trustfile</code>&nbsp;&nbsp;\r
+      <i>trustfile</i></dt>\r
+\r
+      <dd>\r
+        <p>This feature is experimental, has not been fully\r
+        documented and is very subject to change. The goal is for\r
+        parents to be able to choose a page or site whose links\r
+        they regard suitable for their <a href=\r
+        "ijbfaq.html#children">young children</a> and for the proxy\r
+        to allow access only to sites mentioned there. To do this\r
+        the proxy examines the <a href="#o_r">referer</a> variable\r
+        on each page request to check they resulted from a click on\r
+        the ``trusted referer'' site: if so the referred site is\r
+        added to a list of trusted sites, so that the child can\r
+        then move around that site. There are several uncertainties\r
+        in this scheme that experience may be able to iron out;\r
+        check back in the months ahead.</p>\r
+      </dd>\r
+\r
+      <dt><br>\r
+       <a name="trust_info_url">\r
+      </a><code>trust_info_url</code>&nbsp;&nbsp; <i>\r
+      trust_info_url</i></dt>\r
+\r
+      <dd>\r
+        <p>When access is denied due to lack of a trusted referer,\r
+        this URL is displayed with a message pointing the user to\r
+        it for further information.</p>\r
+      </dd>\r
+\r
+      <dt><br>\r
+       <a name="hide-console"></a><code>hide-console</code></dt>\r
+\r
+      <dd>\r
+        <p>In the Windows command-line version only, instructs the\r
+        program to disconnect from and hide the command console\r
+        after starting.</p>\r
+      </dd>\r
+    </dl>\r
+\r
+    <h3><a name="install"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Installation and Use</h3>\r
+\r
+    <p>Browsers must be told where to find the <b><code>\r
+    junkbuster</code></b> (e.g. <code>localhost</code> port 8000).\r
+    To set the HTTP proxy in Netscape 3.0, go through: <b class=\r
+    "eg">Options</b>; <b class="eg">Network Preferences</b>; <b\r
+    class="eg">Proxies</b>; <b class="eg">Manual Proxy\r
+    Configuration</b>; <b class="eg">View</b>. See the <a href=\r
+    "ijbfaq.html">FAQ</a> for other browsers. The <a href=\r
+    "ijbfaq.html#security">Security Proxy</a> should also be set to\r
+    the same values, otherwise <code>shttp:</code> URLs won't\r
+    work.</p>\r
+\r
+    <p><a name="limitations"></a>Note the limitations explained in\r
+    the <a href="ijbfaq.html">FAQ</a>.</p>\r
+\r
+    <h3><a name="show"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; Checking Options</h3>\r
+\r
+    <p>To allow users to <a href="ijbfaq.html#show">check</a> that\r
+    a <b><code>junkbuster</code></b> is running and how it is\r
+    configured, it intercepts requests for any URL ending in <code>\r
+    /show-proxy-args</code> and blocks it, returning instead\r
+    returns information on its version number and current\r
+    configuration including the contents of its blockfile. To get\r
+    an explicit warning that no <b><code>junkbuster</code></b>\r
+    intervened if the proxy was not configured, it's best to point\r
+    it to a URL that does this, such as <a href=\r
+    "http://internet.junkbuster.com/cgi-bin/show-proxy-args">\r
+    http://internet.junkbuster.com/cgi-bin/show-proxy-args</a> on\r
+    Junkbusters's website.</p>\r
+\r
+    <h3><a name="also"></a><img border="0" src="fb.gif" alt="*"\r
+    width="14" height="14">&nbsp; See Also</h3>\r
+\r
+    <p><a href="ijbfaq.html">\r
+    http://www.junkbusters.com/ht/en/ijbfaq.html</a><br>\r
+     <a href="http://www.junkbusters.com/ht/en/cookies.html">\r
+    http://www.junkbusters.com/ht/en/cookies.html</a><br>\r
+     <a href=\r
+    "http://internet.junkbuster.com/cgi-bin/show-proxy-args">\r
+    http://internet.junkbuster.com/cgi-bin/show-proxy-args</a><br>\r
+     <a name="kristol"></a><a href=\r
+    "http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html">http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html</a><br>\r
+\r
+     <a name="squid"></a><a href=\r
+    "http://squid.nlanr.net/Squid/">http://squid.nlanr.net/Squid/</a><br>\r
+\r
+     <a href="http://www-math.uni-paderborn.de/~axel/">\r
+    http://www-math.uni-paderborn.de/~axel/</a></p>\r
+\r
+    <h3><a name="copyright"></a><img border="0" src="fb.gif" alt=\r
+    "*" width="14" height="14">&nbsp; Copyright and GPL</h3>\r
+\r
+    <p>Written and copyright by the Anonymous Coders and\r
+    Junkbusters Corporation and made available under the <a href=\r
+    "gpl.html">GNU General Public License (GPL).</a> This software\r
+    comes with <a href="gpl.html#nowarr">NO WARRANTY.</a> Internet\r
+    Junkbuster Proxy is a <a href=\r
+    "http://www.junkbusters.com/ht/en/legal.html#marks">\r
+    trademark</a> of Junkbusters Corporation.</p>\r
+\r
+    <p align="center"><a href="#top_of_page"><img border="0" src=\r
+    "top.gif" alt="--- Back to Top of Page ---" width="250" height=\r
+    "15"></a></p>\r
+\r
+    <p class="sans"><a href="http://ijbswa.sourceforge.net/">\r
+    Website</a> <b class="dot">&middot;</b> <b>Manual</b> <b class=\r
+    "dot">&middot;</b> <a href="ijbfaq.html">FAQ</a> <b class=\r
+    "dot">&middot;</b> <a href="gpl.html">GPL</a></p>\r
+\r
+    <p class="sans"><small><small><a href="gpl.html#text">\r
+    Copyright</a> &copy; 1996-8 <a href=\r
+    "http://www.junkbusters.com/">Junkbusters</a> <a href=\r
+    "http://www.junkbusters.com/ht/en/legal.html#marks">&reg;</a>\r
+    Corporation. <a href="gpl.html#text">Copyright</a> &copy; 2001\r
+    <a href="http://sourceforge.net/projects/ijbswa/">Jon\r
+    Foster</a>. Copying and distribution permitted under the <a\r
+    href="gpl.html">GNU</a> General Public\r
+    License.</small></small></p>\r
+\r
+    <p><small><code><a href=\r
+    "http://sourceforge.net/projects/ijbswa/">\r
+    http://sourceforge.net/projects/ijbswa/</a></code></small></p>\r
+  </body>\r
+</html>\r
+\r
diff --git a/doc/obsolete/top.gif b/doc/obsolete/top.gif
new file mode 100755 (executable)
index 0000000..8380083
Binary files /dev/null and b/doc/obsolete/top.gif differ
diff --git a/doc/pcrs.3 b/doc/pcrs.3
new file mode 100644 (file)
index 0000000..2a96d5a
--- /dev/null
@@ -0,0 +1,479 @@
+.\" Copyright (c) 2001 Andreas S. Oesterhelt <oes@oesterhelt.org>
+.\"
+.\" This is free documentation; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2 of
+.\" the License, or (at your option) any later version.
+.\"
+.\" The GNU General Public License's references to "object code"
+.\" and "executables" are to be interpreted as the output of any
+.\" document formatting or typesetting system, including
+.\" intermediate and printed output.
+.\"
+.\" This manual is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with this manual; if not, write to the Free
+.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+.\" MA 02111, USA.
+.\"
+.TH PCRS 3 "4 March 2002" "pcrs-0.0.1"
+.SH NAME
+pcrs - Perl-compatible regular substitution.
+.SH SYNOPSIS
+.br
+.B "#include <pcrs.h>"
+.PP
+.br
+.BI "pcrs_job *pcrs_compile(const char *" pattern "," 
+.ti +5n
+.BI "const char *" substitute ", const char *" options ,
+.ti +5n
+.BI "int *" errptr );
+.PP
+.br
+.BI "pcrs_job *pcrs_compile_command(const char *" command ,
+.ti +5n
+.BI "int *" errptr );
+.PP
+.br
+.BI "int pcrs_execute(pcrs_job *" job ", char *" subject ,
+.ti +5n
+.BI "int " subject_length ", char **" result ,
+.ti +5n
+.BI "int *" result_length );
+.PP
+.br
+.BI "int pcrs_execute_list (pcrs_job *" joblist ", char *" subject ,
+.ti +5n
+.BI "int " subject_length ", char **" result ,
+.ti +5n
+.BI "int *" result_length );
+.PP
+.br
+.BI "pcrs_job *pcrs_free_job(pcrs_job *" job );
+.PP
+.br
+.BI "void pcrs_free_joblist(pcrs_job *" joblist );
+.PP
+.br
+.BI "char *pcrs_strerror(int " err );
+.PP
+.br
+
+.SH DESCRIPTION
+
+The
+.SM PCRS
+library is a supplement to the 
+.SB PCRE(3)
+library that implements
+.RB "regular expression based substitution, like provided by " Perl(1) "'s 's'"
+operator. It uses the same syntax and semantics as Perl 5, with just a few
+differences (see below).
+
+In a first step, the information on a substitution, i.e. the pattern, the
+substitute and the options are compiled from Perl syntax to an internal form
+.RB "called " pcrs_job " by using either the " pcrs_compile() " or " 
+.BR pcrs_compile_command() " functions."
+
+Once the job is compiled, it can be used on subjects, which are arbitrary 
+memory areas containing string or binary data, by calling
+.BR pcrs_execute() ". Jobs can be chained to joblists and whole"
+.RB "joblists can be applied to a subject using " pcrs_execute_list() .
+
+There are also convenience functions for freeing the jobs and for errno-to-string
+.RB "conversion, namely " pcrs_free_job() ", " pcrs_free_joblist() " and "
+.BR pcrs_strerror() .
+
+.SH COMPILING JOBS
+
+.RB "The function " pcrs_compile() " is called to compile a " pcrs_job
+.RI "from a " pattern ", " substitute " and " options " string."
+.RB "The resulting " "pcrs_job" " structure is dynamically allocated and it"
+.RB "is the caller's responsibility to call " "pcrs_free_job()" "  when it's no longer needed."
+
+.BR "pcrs_compile_command()" " is a convenience wrapper function that parses a Perl"
+.IR "command" " of the form"
+.BI "s/" "pattern" "/" "substitute" "/[" "options" "]"
+.RB "into its components and then calls " "pcrs_compile()" ". As in Perl, you"
+.RB "are not bound to the '" "/" "' character: Whatever"
+.RB "follows the '" "s" "' will be used as the delimiter. Patterns or substitutes"
+that contain the delimiter need to quote it:
+\fBs/th\\/is/th\\/at/\fR
+.RB "will replace " "th/is" " by " "th/at" " and can be written more simply as" 
+.BR "s|th/is|th/at|" "."
+
+.IR "pattern" ", " "substitute" ", " "options" " and " "command" " must be"
+.RI "zero-terminated C strings. " "substitute" " and " "options" " may be"
+.BR "NULL" ", in which case they are treated like the empty string."
+
+.SS "Return value and diagnostics"
+On success, both functions return a pointer to the compiled job.
+.RB "On failure, " "NULL"
+.RI "is returned. In that case, the pcrs error code is written to *" "err" "."
+
+.SS Patterns
+.RI "For the syntax of the " "pattern" ", see the "
+.BR "PCRE(3)" " manual page."
+
+.SS Substitutes
+.RI "The " "substitute" " uses"
+.RB "Perl syntax as documented in the " "perlre(1)" " manual page, with"
+some exceptions: 
+
+Most notably and evidently, since
+.SM PCRS
+is not Perl, variable interpolation or Perl command substitution won't work.
+Special variables that do get interpolated, are:
+.TP
+.B "$1, $2, ..., $n"
+Like in Perl, these variables refer to what the nth capturing subpattern
+in the pattern matched.
+.TP
+.B "$& and $0"
+.RB "refer to the whole match. Note that " "$0" " is deprecated in recent"
+Perl versions and now refers to the program name.
+.TP
+.B "$+"
+refers to what the last capturing subpattern matched.
+.TP
+.BR "$` and $'" " (backtick and tick)"
+.RI "refer to the areas of the " "subject" " before and after the match, respectively."
+.RB "Note that, like in Perl, the " "unmodified" " subject is used, even"
+if a global substitution previously matched.
+
+.PP
+Perl4-style references to subpattern matches of the form 
+\fB\\1, \\2, ...\fR
+.RB "which only exist in Perl5 for backwards compatibility, are " "not" 
+supported.
+
+Also, since the substitute is a double-quoted string in Perl, you
+might expect all Perl syntax for special characters to apply. In fact,
+only the following are supported:
+
+.TP
+\fB\\n\fR
+newline (0x0a)
+.TP
+\fB\\r\fR
+carriage return (0x0d)
+.TP
+\fB\\t\fR
+horizontal tab (0x09)
+.TP
+\fB\\f\fR
+form feed (0x0c)
+.TP
+\fB\\b\fR
+backspace (0x08)
+.TP
+\fB\\a\fR
+alarm, bell (0x07)
+.TP
+\fB\\e\fR
+escape (0x1b)
+.TP
+\fB\\0\fR
+binary zero (0x00)
+
+.SS "Options"
+.RB "The options " "gmisx" " are supported. " "e" " is not, since it would"
+.RB "require a Perl interpreter and neither is " o ", because the pattern
+is explicitly compiled, anyway. Additionally,
+.SM PCRS
+.RB "honors the options " "U" " and " "T" "."
+Where
+.SM PCRE
+.RB "options are mentioned below, refer to " PCRE(3) " for the subtle differences"
+to Perl behaviour.
+
+.TP
+.B g
+.RB "Replace " all " instances of"
+.IR pattern " in " subject ,
+not just the first one.
+
+.TP
+.B i
+.RI "Match the " pattern " without respect to case. This translates to"
+.SM PCRE_CASELESS.
+
+.TP
+.B m
+.RI "Treat the " subject " as consisting of multiple lines, i.e."
+.RB ' ^ "' matches immediately after, and '" $ "' immediately before each newline."
+Translates to
+.SM PCRE_MULTILINE.
+
+.TP
+.B s
+.RI "Treat the " subject " as consisting of one single line, i.e."
+.RB "let the scope of the '" . "' metacharacter include newlines."
+Translates to
+.SM PCRE_DOTALL.
+
+.TP
+.B x
+.RI "Allow extended regular expression syntax in the " pattern ","
+.RB "enabling whitespace and comments in complex patterns."
+Translates to
+.SM PCRE_EXTENDED.
+
+.TP
+.B U
+.RB "Switch the default behaviour of the '" * "' and '" + "' quantifiers"
+.RB "to ungreedy. Note that appending a '" ? "' switches back to greedy(!)."
+.RB "The explicit in-pattern switches " (?U) " and " (?-U) " remain unaffected."
+Translates to
+.SM PCRE_UNGREEDY.
+
+.TP
+.B T
+.RI "Consider the " substitute " trivial, i.e. do not interpret any references"
+or special character escape sequences in the substitute. Handy for large
+user-supplied substitutes, which would otherwise have to be examined and properly
+quoted.
+
+.PP
+Unsupported options are silently ignored.
+
+.SH EXECUTING JOBS
+
+.RI "Calling " pcrs_execute() " produces a modified copy of the " subject ", in which"
+.RB "the first (or all, if the '" g "' option was given when compiling the job)"
+.RI "occurance(s) of the job's " pattern " in the " subject " is replaced by the job's"
+.IR substitute .
+
+.RI "The first " subject_length " bytes following " subject " are processed, so"
+.RI  "a " subject_length " that exceeds the actual " subject " is dangerous."
+Note that if you want to get your zero-terminated C strings back including their
+.RI "termination, you must let " subject_length " include the binary zero, i.e."
+set it to
+.BI strlen( subject ") + 1."
+
+.RI "The " subject " itself is left untouched, and the " *result " is dynamically"
+.RB "allocated, so it is the caller's responsibility to " free() " it when it's"
+no longer needed.
+
+.RI "The result's length is written to " *result_length "."
+
+.RB "If the job matched, the " PCRS_SUCCESS " flag in"
+.IB job ->flags
+is set.
+
+.SS Return value and diagnostics
+
+.RB "On success, " pcrs_execute() " returns the number of substitutions that"
+were made, which is limited to 0 or 1 for non-global searches.
+.RI "On failure, a negative error code is returned and " result " is set"
+.RB "to " NULL .
+
+.SH FREEING JOBS
+.RB "It is not sufficient to call " free() " on a " pcrs_job ", because it "
+contains pointers to other dynamically allocated structures.
+.RB "Use " pcrs_free_job() " instead. It is safe to pass " NULL " pointers "
+.RB "(or pointers to invalid " pcrs_job "s that contain " NULL " pointers"
+.RB "to dependant structures) to " pcrs_free_job() "."
+
+.SS Return value
+.RB "The value of the job's " next " pointer."
+
+
+.SH CHAINING JOBS
+
+.SM PCRS
+.RB "supports to some extent the chaining of multiple " pcrs_job " structures by"
+.RB "means of their " next " member."
+
+Chaining the jobs is up to you, but once you have built a linked list of jobs,
+.RI "you can execute a whole " joblist " on a given subject by"
+.RB "a single call to " pcrs_execute_list() ", which will sequentially traverse"
+.RB "the linked list until it reaches a " NULL " pointer, and call " pcrs_execute() 
+.RI "for each job it encounters, feeding the " result  " and " result_length " of each"
+.RI "call into the next as the " subject " and " subject_length ". As in the single"
+.RI "job case, the original " subject " remains untouched, but all interim " result "s"
+.RB "are of course " free() "d. The return value is the accumulated number of matches"
+.RI "for all jobs in the " joblist "."
+.RI "Note that while this is handy, it reduces the diagnostic value of " err ", since "
+you won't know which job failed.
+
+.RI "In analogy, you can free all jobs in a given " joblist " by calling"
+.BR pcrs_free_joblist() .
+
+.SH QUOTING
+The quote character is (surprise!) '\fB\\\fR'. It quotes the delimiter in a
+.IR command ", the"
+.RB ' $ "' in  a"
+.IR substitute ", and, of course, itself. Note that the"
+.RB ' $ "' doesn't need to be quoted if it isn't followed by " [0-9+'`&] "."
+
+.RI "For quoting in the " pattern ", please refer to"
+.BR PCRE(3) .
+
+.SH DIAGNOSTICS
+
+.RB "When " compiling " a job either via the " pcrs_compile() " or " pcrs_compile_command()
+.RB "functions, you know that something went wrong when you are returned a " NULL " pointer."
+.RI "In that case, or in the event of non-fatal warnings, the integer pointed to by " err
+contains a nonzero error code, which is either a passed-through
+.SM PCRE
+error code or one generated by
+.SM PCRS.
+Under normal circumstances, it can take the following values:
+.TP
+.B PCRE_ERROR_NOMEMORY
+While compiling the pattern,
+.SM PCRE
+ran out of memory.
+.TP  
+.B  PCRS_ERR_NOMEM
+While compiling the job,
+.SM PCRS
+ran out of memory.
+.TP  
+.B  PCRS_ERR_CMDSYNTAX
+.BR pcrs_compile_command() " didn't find four tokens while parsing the"
+.IR command .
+.TP  
+.B  PCRS_ERR_STUDY
+A
+.SM PCRE
+.RB "error occured while studying the compiled pattern. Since " pcre_study()
+only provides textual diagnostic information, the details are lost.
+.TP  
+.B  PCRS_WARN_BADREF
+.RI "The " substitute " contains a reference to a capturing subpattern that"
+.RI "has a higher index than the number of capturing subpatterns in the " pattern
+or that exceeds the current hard limit of 33 (See LIMITATIONS below). As in Perl,
+this is non-fatal and results in substitutions with the empty string.
+
+.PP
+.RB "When " executing " jobs via " pcrs_execute() " or " pcrs_execute_list() ","
+.RI "a negative return code indicates an error. In that case, *" result
+.RB "is " NULL ". Possible error codes are:"
+.TP
+.B PCRE_ERROR_NOMEMORY
+While matching the pattern,
+.SM PCRE
+ran out of memory. This can only happen if there are more than 33 backrefrences
+.RI "in the " pattern "(!)"
+.BR and " memory is too tight to extend storage for more."
+.TP  
+.B  PCRS_ERR_NOMEM
+While executing the job,
+.SM PCRS
+ran out of memory.
+.TP  
+.B  PCRS_ERR_BADJOB
+.RB "The " pcrs_job "*  passed to " pcrs_execute " was NULL, or the"
+.RB "job is bogus (it contains " NULL " pointers to the compiled
+pattern, extra, or substitute).
+
+.PP
+If you see any other
+.SM PCRE
+error code passed through, you've either messed with the compiled job
+or found a bug in
+.SM PCRS.
+Please send me an email.
+
+.RB "Ah, and don't look for " PCRE_ERROR_NOMATCH ", since this"
+is not an error in the context of
+.SM PCRS.
+.RI "Should there be no match, an exact copy of the " subject " is"
+.RI "found at *" result " and the return code is 0 (matches)."
+
+All error codes can be translated into human readable text by means
+.RB "of the " pcrs_strerror() " function."
+
+
+.SH EXAMPLE
+A trivial command-line test program for
+.SM PCRS
+might look like:
+
+.nf
+#include <pcrs.h>
+#include <stdio.h>
+
+int main(int Argc, char **Argv)
+{
+   pcrs_job *job;
+   char *result;
+   size_t newsize;
+   int err;
+
+   if (Argc != 3)
+   {
+      fprintf(stderr, "Usage: %s s/pattern/substitute/[options]  subject\\n", Argv[0]);
+      return 1;
+   }
+
+   if (NULL == (job = pcrs_compile_command(Argv[1], &err)))
+   {
+      fprintf(stderr, "%s: compile error:  %s (%d).\\n", Argv[0], pcrs_strerror(err), err);
+   }
+
+   if (0 > (err = pcrs_execute(job, Argv[2], strlen(Argv[2]) + 1, &result, &newsize)))
+   {
+      fprintf(stderr, "%s: Exec error:  %s (%d).\\n", Argv[0], pcrs_strerror(err), err);
+   }
+   else
+   {
+      printf("Result: *%s*\\n", result);
+      free(result);
+   }
+
+   pcrs_free_job(job);
+   return(err < 0);
+
+}
+
+.fi
+
+
+.SH LIMITATIONS
+The number of matches that a global job can have is only limited by the
+available memory. An initial storage for 40 matches is reserved, which
+is dynamically resized by the factor 1.6 whenever it is exhausted.
+
+The number of capturing subpatterns is currently limited to 33, which
+is a Bad Thing[tm]. It should be dynamically expanded until it reaches the
+.SM PCRE
+limit of 99.
+
+All of the above values can be adjusted in the "Capacity" section
+.RB "of " pcrs.h "."
+
+The Perl-style escape sequences for special characters \\\fInnn\fR,
+\\x\fInn\fR, and \\c\fIX\fR are currently unsupported.
+
+.SH BUGS
+This library has only been tested in the context of one application
+and should be considered high risk.
+
+.SH HISTORY
+.SM PCRS
+was originally written for the Internet Junkbuster project
+(http://sourceforge.net/projects/ijbswa/).
+
+.SH SEE ALSO
+.B PCRE(3), perl(1), perlre(1)
+
+.SH AUTHOR
+
+.SM PCRS
+is Copyright 2000, 2001 by Andreas Oesterhelt <andreas@oesterhelt.org> and is
+licensed under the terms of the GNU Lesser General Public License (LGPL),
+version 2.1, which should be included in this distribution, with the exception
+that the permission to replace that license with the GNU General Public
+License (GPL) given in section 3 is restricted to version 2 of the GPL.
+
+If it is missing from this distribution, the LGPL can be obtained from
+http://www.gnu.org/licenses/lgpl.html or by mail: Write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
diff --git a/doc/pdf/.gitignore b/doc/pdf/.gitignore
new file mode 100644 (file)
index 0000000..76701ee
--- /dev/null
@@ -0,0 +1,6 @@
+*.sgml
+*.dsl
+*.out
+*.tex
+*.log
+*.aux
diff --git a/doc/pdf/privoxy-developer-manual.pdf b/doc/pdf/privoxy-developer-manual.pdf
new file mode 100644 (file)
index 0000000..2575a0b
Binary files /dev/null and b/doc/pdf/privoxy-developer-manual.pdf differ
diff --git a/doc/pdf/privoxy-faq.pdf b/doc/pdf/privoxy-faq.pdf
new file mode 100644 (file)
index 0000000..e5a458c
Binary files /dev/null and b/doc/pdf/privoxy-faq.pdf differ
diff --git a/doc/pdf/privoxy-user-manual.pdf b/doc/pdf/privoxy-user-manual.pdf
new file mode 100644 (file)
index 0000000..012e2e4
Binary files /dev/null and b/doc/pdf/privoxy-user-manual.pdf differ
diff --git a/doc/source/.gitignore b/doc/source/.gitignore
new file mode 100644 (file)
index 0000000..2fa6e00
--- /dev/null
@@ -0,0 +1,6 @@
+developer-manual
+faq
+ldpOK.dsl
+user-manual
+temp
+ldp.dsl
\ No newline at end of file
diff --git a/doc/source/announce.sgml b/doc/source/announce.sgml
new file mode 100644 (file)
index 0000000..28691e8
--- /dev/null
@@ -0,0 +1,109 @@
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!entity % dummy "IGNORE"> 
+<!entity supported SYSTEM "../supported.sgml">
+<!entity p-intro SYSTEM "../privoxy.sgml">
+<!entity contacting SYSTEM "../contacting.sgml">
+<!entity history SYSTEM "../history.sgml">
+<!entity newfeatures SYSTEM "../newfeatures.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "INCLUDE">       <!-- define we are a text only doc    -->
+<!entity % p-doc "IGNORE">         <!-- and never a text doc             -->
+<!entity % announce-big "IGNORE"> <!-- toggle for short vs long version -->
+]>
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/announce.sgml,v $
+
+ Purpose     :  Announcement text
+                
+ $Id: announce.sgml,v 1.0 2002/05/10 01:48:20 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation. You have been warned!
+ Failure to abide by this rule will result in the revocation of your license 
+ to live a peaceful existence!
+ ========================================================================
+
+ ===================================================================
+ NOTE: This will is designed to build a generic announcement for use 
+ with new releases of Privoxy. It will build both a short and long 
+ version. Also, both text and html versions are generated, so that 
+ press release packages can contain both formats for those that might 
+ prefer HTML ready announce text.
+
+ This may require a small bit of hand editing before processing. 
+ The intention is to minimize this as much as possible.
+
+ To create: make announce
+ ===================================================================
+
+-->
+<article id="index">
+<![%dummy;[
+ <para>
+ <comment>
+  This is here to keep vim syntax file from breaking :/
+  If I knew enough to fix it, I would.
+  PLEASE DO NOT REMOVE! HB: hal@foobox.net
+ </comment>
+ </para>
+]]>
+
+<para>
+ Announcing <application>Privoxy</application> 
+ v.&p-version;<![%p-not-stable;[-&p-status;]]>, and release candidate for 
+ v3.0 stable.
+</para>
+
+<!-- Include privoxy.sgml boilerplate: -->
+ &p-intro;
+<!-- end boilerplate -->
+
+<para>
+ In addition to the traditional features of <application>Internet
+ Junkbuster</application>, such as ad and banner blocking, cookie
+ management/protection, and HTTP header manipulation,
+ <application>Privoxy</application> 
+ adds many enhancements, and new features in the same vein.
+</para>
+
+<![%announce-big;[
+<!-- Include newfeatures.sgml boilerplate: -->
+  &newfeatures;
+<!-- end boilerplate -->
+
+<!-- Include history.sgml boilerplate: -->
+ <!-- &history; this doesn't work so well here --> 
+<!-- end boilerplate -->
+
+<para>
+ <application>Junkbuster</application> was originally written by Anonymous
+ Coders and Junkbusters Corporation, and was released as free open-source
+ software under the GNU GPL. Stefan Waldherr made many improvements, and
+ started the SourceForge project Privoxy to rekindle development. There are
+ now several active developers contributing.
+</para>
+]]>
+
+<para> 
+ <literallayout>Download location: 
+  <ulink url="http://sourceforge.net/projects/ijbswa/">http://sourceforge.net/projects/ijbswa/</ulink>
+ </literallayout>
+</para>
+
+<para> 
+ <literallayout>Home Page: 
+  <ulink url="http://www.privoxy.org/">http://www.privoxy.org/</ulink>
+ </literallayout>
+</para>
+
+
+<epigraph><attribution>Privoxy Developers</attribution><para></para></epigraph>
+
+</article>
diff --git a/doc/source/authors.sgml b/doc/source/authors.sgml
new file mode 100644 (file)
index 0000000..64b6728
--- /dev/null
@@ -0,0 +1,67 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/authors.sgml,v $
+
+ Purpose     :  AUTHORS file for Privoxy
+                
+ $Id: authors.sgml,v 1.7 2002/05/04 08:44:44 swa Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation. You have been warned!
+ Failure to abide by this rule will result in the revocation of your license 
+ to live a peaceful existence!
+ ========================================================================
+
+ ===================================================================
+ READ: Document Note: This file generates the AUTHORS file in the 
+ top level source directory. See p-authors.sgml for list of developers
+ and contributors, etc. They were split from here for use in man page.
+ ===================================================================
+
+-->
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!entity % dummy "IGNORE"> 
+<!entity authors SYSTEM "p-authors.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "INCLUDE">           <!-- define we are a text only doc -->
+<!entity % p-authors-formal "INCLUDE"> <!-- include additional text, etc  -->
+]>
+
+<article id="index">
+
+<![%dummy;[
+ <para>
+ <comment>
+  This is here to keep vim syntax file from breaking :/
+  If I knew enough to fix it, I would.
+  PLEASE DO NOT REMOVE! HB: hal@foobox.net
+ </comment>
+ </para>
+]]>
+
+<literallayout>
+              Authors of <application>Privoxy</application> v2.9.x and 3.x
+===========================================================================
+</literallayout>
+
+<!-- include boilerplate p-authors.sgml -->
+ &authors;
+<!-- end boilerplate -->
+
+<para>
+ If we've missed you off this list, please let us know!
+</para>
+
+<literallayout>
+ Privoxy team. <ulink url="http://www.privoxy.org/">http://www.privoxy.org/</ulink>
+ <email>ijbswa-developers@lists.sourceforge.net</email>
+</literallayout>
+
+</article>
diff --git a/doc/source/buildsource.sgml b/doc/source/buildsource.sgml
new file mode 100644 (file)
index 0000000..8e4ee79
--- /dev/null
@@ -0,0 +1,111 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/buildsource.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: buildsource.sgml,v 1.8 2002/05/03 17:41:41 oes Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  user-manual
+  README
+
+-->
+
+<para>
+ To build <application>Privoxy</application> from source, 
+ <ulink url="http://www.gnu.org/software/autoconf/autoconf.html">autoconf</ulink>,
+ <ulink
+ url="http://www.gnu.org/software/make/make.html">GNU make
+ (gmake)</ulink>, and, of course, a C compiler like <ulink
+ url="http://www.gnu.org/software/gcc/gcc.html">gcc</ulink> are required.
+</para>
+
+<para>
+ When building from a source tarball (either release version or
+ <ulink
+ url="http://cvs.sourceforge.net/cvstarballs/ijbswa-cvsroot.tar.gz">nightly CVS
+ tarball</ulink>), first unpack the source: 
+</para>
+
+<para>
+ <screen>
+ tar xzvf privoxy-&p-version;<![%p-not-stable;[-beta]]>-src* [.tgz or .tar.gz]
+ cd privoxy-&p-version;<![%p-not-stable;[-beta]]>
+</screen>
+</para>
+
+<para>
+ For retrieving the current CVS sources, you'll need CVS installed.
+ Note that sources from CVS are development quality, and may not be
+ stable, or well tested. To download CVS source:
+</para>
+
+<para>
+ <screen>
+  cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co current
+  cd current
+</screen>
+</para>
+
+<para>
+ This will create a directory named <filename>current/</filename>, which will 
+ contain the source tree.
+</para>
+
+<para>
+ Then, in either case, to build from unpacked tarball or CVS source:
+</para>
+
+<para>
+ <screen>
+ autoheader
+ autoconf
+ ./configure      # (--help to see options)
+ make             # (the make from gnu, gmake for *BSD) 
+ su 
+ make -n install  # (to see where all the files will go)
+ make install     # (to really install)
+</screen>
+</para>
+
+<para>
+  If you have gnu make, you can have the first four steps 
+  automatically done for you by just typing:
+</para>
+
+<para>
+ <screen>
+  make
+</screen>
+</para>
+
+<para>
+  in the freshly downloaded or unpacked source directory.
+</para>
+
+<para>
+ For more detailed instructions on how to build Redhat and SuSE RPMs,
+ Windows self-extracting installers, building on platforms with
+ special requirements etc, please consult the <ulink
+ url="../developer-manual/newrelease.html">developer manual</ulink>.
+</para>
+
+<!-- print for README only -->
+ <![%p-readme;[
+ <para>
+  For binary RPM installation, and other platforms, see the user-manual 
+  as well.
+ </para>
+]]>
diff --git a/doc/source/contacting.sgml b/doc/source/contacting.sgml
new file mode 100644 (file)
index 0000000..d677c13
--- /dev/null
@@ -0,0 +1,119 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa//current/doc/source/contacting.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: contacting.sgml,v 1.14 2002/05/17 13:32:12 oes Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ This file is included into:
+
+  faq
+  developer-manual
+  README
+  user-manual
+  webserver/index.sgml
+
+-->
+
+<!-- READ: -->
+<!-- Careful of the literallayout tags and finished formatting -->
+
+<para>
+ We value your feedback. In fact, we rely on it to improve
+ <application>Privoxy</application> and its configuration.
+ However, please note the following hints, so we can 
+ provide you with the best support:
+</para>
+
+<sect2 id="contact-support"><title>Get Support</title>
+<para>
+ For casual users, our support forum at
+ <ulink url="http://sourceforge.net/">SourceForge</ulink>
+ is probably best suited:
+ <ulink url="http://sourceforge.net/tracker/?group_id=11118&#38;atid=211118">http://sourceforge.net/tracker/?group_id=11118&#38;atid=211118</ulink>
+</para>
+
+<para>
+ All users are of course welcome to discuss their issues on the <ulink
+ url="http://lists.sourceforge.net/lists/listinfo/ijbswa-users">users
+ mailing list</ulink>, where the developers also hang around.
+</para>
+
+</sect2>
+
+<sect2 id="contact-bugs"><title>Report Bugs</title>
+<para>
+ Please report all bugs <emphasis>only</emphasis> through our
+ bug tracker: 
+ <ulink url="http://sourceforge.net/tracker/?group_id=11118&#38;atid=111118">http://sourceforge.net/tracker/?group_id=11118&#38;atid=111118</ulink>. 
+</para>
+
+<para>
+  Before doing so, please make sure that the bug has not already been submitted
+  and observe the aditional hints at the top of the <ulink
+  url="http://sourceforge.net/tracker/?func=add&amp;group_id=11118&amp;atid=111118">submit
+  form</ulink>.
+</para>
+
+<para> 
+  Please try to verify that it is a <application>Privoxy</application> bug,
+  and not a browser or site bug first. If unsure,
+  try <ulink url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&amp;set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">toggling
+  off</ulink> <application>Privoxy</application>, and see if the problem persists.
+  The <ulink url="http://www.privoxy.org/user-manual/appendix.html#ACTIONSANAT">appendix
+  of the user manual</ulink> also has helpful information 
+  on action debugging. If you are using your own custom configuration, please try
+  the stock configs to see if the problem is configuration related.
+</para>
+
+<para>
+  If not using the latest version, chances are that the bug has been found
+  and fixed in the meantime. We would appreciate if you could take the time
+  to <ulink url="http://www.privoxy.org/user-manual/installation.html">upgrade
+  to the latest version</ulink> (or  even the latest CVS snapshot) and verify
+  your bug, but this is not required for reporting.
+</para>
+</sect2>
+
+<sect2 id="contact-feature"><title>Request New Features</title>
+<para>
+ You are welcome to submit ideas on new features or other proposals
+ for improvement through our feature request tracker at
+ <ulink url="http://sourceforge.net/tracker/?atid=361118&#38;group_id=11118">http://sourceforge.net/tracker/?atid=361118&#38;group_id=11118</ulink>.
+</para>
+</sect2>
+
+<sect2 id="contact-ads"><title>Report Ads or Other Actions-Related Problems</title>
+<para>
+ Please send feedback on ads that slipped through, innocent images that were blocked,
+ and any other problems relating to the <filename>default.action</filename> file through
+ our actions feedback mechanism located at
+ <ulink url="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">http://www.privoxy.org/actions/</ulink>.
+ On this page, you will also find a bookmark which will take you back there from
+ any troubled site and even pre-fill the form!
+</para> 
+
+<para>
+ New, improved <filename>default.action</filename> files will occasionally be made
+ available based on your feedback. These will be announced on the <ulink
+ url="http://lists.sourceforge.net/lists/listinfo/ijbswa-announce">ijbswa-announce</ulink>
+ list and available from our <ulink url="http://sf.net/projects/ijbswa/">project page</ulink>.
+</para>
+</sect2>
+
+<sect2 id="contact-other"><title>Other</title>
+<para>
+For any other issues, feel free to use the mailing lists. Technically interested users
+and people who wish to contribute to the project are also welcome on the developers list!
+You can find an overview of all <application>Prixoxy</application>-related mailing lists,
+including list archives, at:
+<ulink url="http://sourceforge.net/mail/?group_id=11118">http://sourceforge.net/mail/?group_id=11118</ulink>.
+</para>
+</sect2>
diff --git a/doc/source/copyright.sgml b/doc/source/copyright.sgml
new file mode 100644 (file)
index 0000000..854d019
--- /dev/null
@@ -0,0 +1,47 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/copyright.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: copyright.sgml,v 1.6 2002/05/07 00:37:31 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  privoxy-man-page
+  user-manual
+  developer-manual
+  faq
+
+ **************************************************************
+ NOTE: the &my-copy entity must be defined in any file that will 
+ include this file. (This is a workaround for docbook2man not 
+ handling the standard &copy entity in the man page processing.)
+ **************************************************************
+
+-->
+
+<!--
+ GFDL:
+ http://www.gnu.org/licenses/fdl.html
+-->
+
+<para>
+ Copyright &my-copy; 2001, 2002 by Privoxy Developers <email>developers@privoxy.org</email>
+</para>
+
+<para>
+ Some source code is based on code Copyright &my-copy; 1997 by Anonymous Coders
+ and Junkbusters, Inc. and licensed under the <citetitle>GNU General Public
+ License</citetitle>.
+</para>
+
diff --git a/doc/source/developer-manual.sgml b/doc/source/developer-manual.sgml
new file mode 100644 (file)
index 0000000..5049edd
--- /dev/null
@@ -0,0 +1,2977 @@
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[
+<!entity % dummy "IGNORE"> 
+<!entity supported SYSTEM "supported.sgml">
+<!entity newfeatures SYSTEM "newfeatures.sgml">
+<!entity p-intro SYSTEM "privoxy.sgml">
+<!entity history SYSTEM "history.sgml">
+<!entity seealso SYSTEM "seealso.sgml">
+<!entity contacting SYSTEM "contacting.sgml">
+<!entity copyright SYSTEM "copyright.sgml">
+<!entity license SYSTEM "license.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "IGNORE">        <!-- define we are not a text only doc -->
+<!entity % p-doc "INCLUDE">        <!-- and we are a formal doc           -->
+<!entity  my-copy "&copy;">        <!-- kludge for docbook2man            -->
+]>
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/developer-manual.sgml,v $
+
+ Purpose     :  developer manual
+                This file belongs into
+                ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+                
+ $Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation. You have been warned!
+ Failure to abide by this rule will result in the revocation of your license 
+ to live a peaceful existence!
+ ========================================================================
+
+-->
+
+<article id="index">
+  <artheader>
+    <title>Privoxy Developer Manual</title>
+    <pubdate>
+     <subscript>
+    <!-- Completely the wrong markup, but very little is allowed  -->
+    <!-- in this part of an article. FIXME -->
+      <link linkend="copyright">Copyright</link> &my-copy; 2001, 2002 by 
+      <ulink url="http://www.privoxy.org">Privoxy Developers</ulink>
+     </subscript>
+    </pubdate>
+
+
+    <pubdate>$Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $</pubdate>
+
+<!--
+
+Note: this should generate a separate page, and a live link to it. 
+But it doesn't for some mysterious reason. Please leave commented
+unless it can be fixed proper. For the time being, the copyright 
+statement will be in copyright.smgl.
+
+Hal.
+
+<legalnotice id="legalnotice"> 
+ <para>
+  text goes here ........
+ </para>
+</legalnotice>
+
+-->
+
+    <abstract>
+
+<![%dummy;[
+ <para>
+ <comment>
+  This is here to keep vim syntax file from breaking :/
+  If I knew enough to fix it, I would.
+  PLEASE DO NOT REMOVE! HB: hal@foobox.net
+ </comment>
+ </para>
+ ]]>
+<para>
+ The developer manual provides guidance on coding, testing, packaging, documentation
+ and other issues of importance to those involved with
+ <application>Privoxy</application> development. It is mandatory (and helpful!) reading
+ for anyone who wants to join the team.
+</para>
+
+<!-- Include privoxy.sgml boilerplate text: -->
+
+<!--  &p-intro; Someone interested enough in the project to contribute
+                will already know at this point what Privoxy is. -->
+
+<!-- end boilerplate -->
+
+<para>
+ You can find the latest version of the this manual at <ulink
+ url="http://www.privoxy.org/developer-manual/">http://www.privoxy.org/developer-manual/</ulink>.
+ Please see <link linkend="contact">the Contact section</link> 
+ on how to contact the developers.
+</para>
+<!--        <para> -->
+<!--    Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>. -->
+<!--   </para> -->
+
+    </abstract>
+  </artheader>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="introduction"><title>Introduction</title>
+<!--
+
+ I don't like seeing blank space :) So added *something* here.
+
+ --> 
+    <para>
+     <application>Privoxy</application>, as an heir to
+     <application>Junkbuster</application>, is an Open Source project 
+     and licensed under the GPL. As such, <application>Privoxy</application>
+     development is potentially open to anyone who has the time, knowledge,
+     and desire to contribute in any capacity. Our goals are simply to
+     continue the mission, to improve <application>Privoxy</application>, and
+     to make it available to as wide an audience as possible. 
+    </para>
+    <para>
+     One does not have to be a programmer to contribute. Packaging, testing,
+     and porting, are all important jobs as well.
+    </para>
+
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect2 id="quickstart"><title>Quickstart to Privoxy Development</title>
+    <para>
+      You'll need an account on <ulink
+      url="http://sourceforge.net/">Sourceforge</ulink> to support our
+      development.  Mail your ID to <ulink
+      url="mailto:developers@privoxy.org">the list</ulink> and wait until a
+      project manager has added you.
+    </para>
+    <para>
+      For the time being (read, this section is under construction), please
+      refer to the extensive comments in the source code.
+    </para>
+   </sect2>
+  </sect1>
+
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="cvs"><title>The CVS Repository</title>
+    <para>
+      If you intend to help us with programming, documentation or packaging
+      you will need write access to our holy grail, the CVS repository.
+      Please read this chapter completely before accessing via CVS.
+    </para>
+
+    <sect2 id="cvsaccess"><title>Access to CVS</title>
+      <para>
+        The project's CVS repository is hosted on
+        <ulink url="http://sourceforge.net/">SourceForge.</ulink>
+        Please refer to the chapters 6 and 7 in
+        <ulink url="http://sourceforge.net/docman/?group_id=1">SF's site
+        documentation</ulink> for the technical access details for your
+        operating system. For historical reasons, the CVS server is
+        called <literal>cvs.ijbswa.sourceforge.net</literal>, the repository is
+        called <literal>ijbswa</literal>, and the source tree module is called
+        <literal>current</literal>.
+      </para>
+    </sect2>
+
+    <sect2 id="cvscommit"><title>CVS Commit Guideline</title>
+      <para>
+        The source tree is the heart of every software project. Every effort must
+        be made to ensure that it is readable, compilable and consistent at all
+        times. We therefore ask anyone with CVS access to strictly adhere to the
+        following guidelines:
+        <itemizedlist>
+          <listitem><para>
+            Never (read: <emphasis>never, ever</emphasis>) be tempted to commit
+            that small change without testing it thoroughly first. When we're
+            close to a public release, ask a fellow developer to review your 
+            changes.
+          </para></listitem>
+          <listitem><para>
+            Your commit message should give a concise overview of <emphasis>what you
+            changed</emphasis> (no big details) and <emphasis>why you changed it</emphasis>
+            Just check previous messages for good examples.
+          </para></listitem>
+          <listitem><para>
+            Don't use the same message on multiple files, unless it equally applies to
+            all those files.
+          </para></listitem>
+          <listitem><para>
+            If your changes span multiple files, and the code won't recompile unless
+            all changes are commited (e.g. when changing the signature of a function),
+            then commit all files one after another, without long delays in beween.
+            If necessary, prepare the commit messages in advance.
+          </para></listitem>
+          <listitem><para>
+            Before changing things on CVS, make sure that your changes are in line
+            with the team's general consensus on what should be done (see below).
+          </para></listitem>
+        </itemizedlist>
+      </para>
+    </sect2>
+
+    <sect2 id="cvswhenask"><title>Discussing Changes First</title>
+      <para>
+        We don't have a too formal policy on this, just use common sense. Hints: If it is..
+        <orderedlist numeration="arabic">
+          <listitem><para>
+            ..a bugfix / clean-up / cosmetic thing: shoot
+          </para></listitem>
+          <listitem><para>
+            ..a new feature that can be turned off: shoot
+          </para></listitem>
+          <listitem><para>
+            ..a clear improvement w/o side effects on other parts of the code: shoot
+          </para></listitem>
+          <listitem><para>
+            ..a matter of taste: <ulink url="mailto:developers@privoxy.org">ask the list</ulink>
+          </para></listitem>
+          <listitem><para>
+            ..a major redesign of some part of the code: <ulink url="mailto:developers@privoxy.org">ask
+            the list</ulink>
+          </para></listitem>
+        </orderedlist>
+      </para>
+      <para>
+        Note that near a major public release, we get a bit more cautious - if
+        unsure, it doesn't hurt to ask first. There is always the possibility
+        to submit a patch to the <ulink
+        url="http://sourceforge.net/tracker/?atid=311118&amp;group_id=11118&amp;func=browse">patches
+        tracker</ulink> instead.
+      </para>
+    </sect2>
+  </sect1>
+       
+  <!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="documentation"><title>Documentation Guidelines</title>
+  <para>
+    All formal documents are maintained in Docbook SGML and located in the
+    <computeroutput>doc/source/*</computeroutput> directory. You will need
+    <ulink url="http://www.docbook.org">Docbook</ulink>, the Docbook 
+    DTD's and the Docbook modular stylesheets (or comparable alternatives),
+    and either <application>jade</application> or
+    <application>openjade</application> (recommended) installed in order to
+    build docs from source. Currently there is <ulink
+    url="../user-manual/index.html"><citetitle>user-manual</citetitle></ulink>,
+    <ulink url="../faq/index.html"><citetitle>FAQ</citetitle></ulink>, and, of
+    course this, the <citetitle>developer-manual</citetitle> in this format.
+    The <citetitle>README</citetitle>, <citetitle>AUTHORS</citetitle>
+    <citetitle>privoxy.1</citetitle> (man page) files are also now maintained
+    as Docbook SGML. The finished files are all in the top-level source
+    directory are generated files! Also, <filename>index.html</filename>, the
+    <application>Privoxy</application> home page, is maintained as SGML.
+    <emphasis>DO NOT edit these directly</emphasis>. Edit the SGML source, or
+    contact someone involved in the documentation (at present Stefan and
+    Hal).
+    </para> 
+    <para>
+     Other, less formal documents (e.g. <filename>LICENSE</filename>,
+     <filename>INSTALL</filename>) are maintained as plain text files in the
+     top-level source directory. At least for the time being.
+    </para>
+    <para>
+     Packagers are encouraged to include this documentation. For those without
+     the ability to build the docs locally, text versions of each are kept in
+     CVS. HTML versions are also now being kept in CVS under 
+     <filename>doc/webserver/*</filename>.
+    </para>
+    <para>
+     Formal documents are built with the Makefile targets of
+     <computeroutput>make dok</computeroutput>, or alternately
+     <computeroutput>make redhat-dok</computeroutput>. If you have problems,
+     try both. The build process uses the document SGML sources in
+     <computeroutput>doc/source/*/*</computeroutput> to update all text files in
+     <computeroutput>doc/text/</computeroutput> and to update all HTML
+     documents in <computeroutput>doc/webserver/</computeroutput>.
+    </para>
+    <para>
+     Documentation writers should please make sure documents build
+     successfully before committing to CVS, if possible.
+    </para>
+    <para>
+     How do you update the webserver (i.e. the pages on privoxy.org)?
+     
+     <orderedlist numeration="arabic">
+      <listitem><para>
+        First, build the docs by running <computeroutput>make
+        dok</computeroutput> (or alternately <computeroutput>make
+        redhat-dok</computeroutput>).                 
+      </para></listitem>
+      <listitem><para>
+        Run <computeroutput>make webserver</computeroutput> which copies all
+        files from <computeroutput>doc/webserver</computeroutput> to the
+        sourceforge webserver via scp.
+      </para></listitem>
+     </orderedlist>
+  </para>
+
+  <para>
+   Finished docs should be occasionally submitted to CVS
+   (<filename>doc/webserver/*/*.html</filename>) so that those without 
+   the ability to build them locally, have access to them if needed.
+   This is especially important just prior to a new release! Please
+   do this <emphasis>after</emphasis> the <literal>$VERSION</literal> and
+   other release specific data in <filename>configure.in</filename> has been
+   updated (this is done just prior to a new release).
+  </para>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="sgml">
+<title>Quickstart to Docbook and SGML</title>
+<para>
+ If you are not familiar with SGML, it is a markup language similar to HTML. 
+ Actually, not a mark up language per se, but a language used to define 
+ markup languages. In fact, HTML is an SGML application. Both will use
+ <quote>tags</quote> to format text and other content. SGML tags can be much
+ more varied, and flexible, but do much of the same kinds of things. The tags,
+ or <quote>elements</quote>, are definable in SGML. There is no set
+ <quote>standards</quote>. Since we are using
+ <application>Docbook</application>, our tags are those that are defined by 
+ <application>Docbook</application>. Much of how the finish document is
+ rendered is determined by the <quote>stylesheets</quote>.
+ The stylesheets determine how each tag gets translated to HTML, or other
+ formats.
+</para>
+
+<para>
+ Tags in Docbook SGML need to be always <quote>closed</quote>. If not, you
+ will likely generate errors. Example: <literal>&lt;title&gt;My
+ Title&lt;/title&gt;</literal>. They are also case-insensitive, but we
+ strongly suggest using all lower case. This keeps compatibility with
+ [Docbook] <application>XML</application>.
+</para>
+
+<para>
+ Our documents use <quote>sections</quote> for the most part. Sections
+ will be processed into HTML headers (e.g. <literal>h1</literal> for 
+ <literal>sect1</literal>). The <application>Docbook</application> stylesheets
+ will use these to also generate the Table of Contents for each doc. Our 
+ TOC's are set to a depth of three. Meaning <literal>sect1</literal>, 
+ <literal>sect2</literal>, and <literal>sect3</literal> will have TOC 
+ entries, but <literal>sect4</literal> will not. Each section requires 
+ a <literal>&lt;title&gt;</literal> element, and at least one 
+ <literal>&lt;para&gt;</literal>. There is a limit of five section 
+ levels in Docbook, but generally three should be sufficient for our 
+ purposes.
+</para>
+
+<para>
+ Some common elements that you likely will use: 
+</para>
+
+<para>
+  <simplelist>
+    <member>
+      <emphasis>&lt;para&gt;&lt;/para&gt;</emphasis>, paragraph delimiter. Most 
+      text needs to be within paragraph elements (there are some exceptions).
+    </member>
+    <member>
+      <emphasis>&lt;emphasis&gt;&lt;/emphasis&gt;</emphasis>, the stylesheets
+      make this italics.
+    </member>
+    <member>
+      <emphasis>&lt;filename&gt;&lt;/filename&gt;</emphasis>, files and directories.
+    </member>
+    <member>
+      <emphasis>&lt;command&gt;&lt;/command&gt;</emphasis>, command examples.
+    </member>
+    <member>
+      <emphasis>&lt;literallayout&gt;&lt;/literallayout&gt;</emphasis>, like 
+      <literal>&lt;pre&gt;</literal>, more or less.
+    </member>
+    <member>
+      <emphasis>&lt;itemizedlist&gt;&lt;/itemizedlist&gt;</emphasis>, list with bullets.
+    </member>
+    <member>
+      <emphasis>&lt;listitem&gt;&lt;/listitem&gt;</emphasis>, member of the above.
+    </member>
+    <member>
+      <emphasis>&lt;screen&gt;&lt;/screen&gt;</emphasis>, screen output, implies 
+      <literal>&lt;literallayout&gt;</literal>.
+    </member>
+    <member>
+      <emphasis>&lt;ulink url="example.com"&gt;&lt;/ulink&gt;</emphasis>, like 
+      HTML <literal>&lt;a&gt;</literal> tag.
+    </member>
+    <member>
+      <emphasis>&lt;quote&gt;&lt;/quote&gt;</emphasis>, for, doh, quoting text. 
+    </member>
+  </simplelist>
+</para>
+
+<para>
+ Look at any of the existing docs for examples of all these and more.
+</para>
+
+<para>
+ You might also find <quote><ulink
+ url="http://www.bureau-cornavin.com/opensource/crash-course/">Writing Documentation
+ Using DocBook - A Crash Course</ulink></quote> useful.
+</para>
+</sect2>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+  <sect2 id="docstyle">
+  <title><application>Privoxy</application> Documentation Style</title>
+   <para>
+    It will be easier if everyone follows a similar writing style. This 
+    just makes it easier to read what someone else has written if it 
+    is all done in a similar fashion.
+   </para>
+   <para>
+    Here it is:
+   </para>
+   <para>
+    <itemizedlist>
+     <listitem>
+      <para>
+       All tags should be lower case.
+      </para>
+    </listitem> 
+    <listitem>
+     <para>
+       Tags delimiting a <emphasis>block</emphasis> of text (even small
+       blocks) should be on their own line. Like:
+       <literallayout>
+ &lt;para&gt;
+  Some text goes here.
+ &lt;/para&gt;
+       </literallayout>
+       Tags marking individual words, or few words, should be in-line:
+       <literallayout>
+  Just to &lt;emphasis&gt;emphasize&lt;/emphasis&gt;, some text goes here.
+       </literallayout>
+     </para>
+   </listitem> 
+   <listitem>
+    <para>
+      Tags should be nested and step indented for block text like: (except
+      in-line tags) 
+     <literallayout>
+ &lt;para&gt;
+  &lt;itemizedlist&gt;
+   &lt;para&gt;
+    &lt;listitem&gt;
+      Some text goes here in our list example.
+     &lt;/listitem&gt;
+   &lt;/para&gt;
+  &lt;/itemizedlist&gt;
+ &lt;/para&gt;
+       </literallayout>
+      This makes it easier to find the text amongst the tags ;-)
+    </para>
+   </listitem> 
+   <listitem>
+    <para>
+     Use white space to separate logical divisions within a document, 
+     like between sections. Running everything together consistently 
+     makes it harder to read and work on.
+    </para>
+   </listitem> 
+   <listitem>
+    <para>
+     Do not hesitate to make comments. Comments can either use the 
+     &lt;comment&gt; element, or the &lt;!--  --&gt; style comment 
+     familiar from HTML. (Note in Docbook v4.x &lt;comment&gt; is 
+     replaced by &lt;remark&gt;.)
+    </para>
+  </listitem> 
+  <listitem>
+   <para>
+     We have an international audience. Refrain from slang, or English 
+     idiosyncrasies (too many to list :). Humor also does not translate 
+     well sometimes.
+   </para>
+  </listitem> 
+  <listitem>
+   <para>
+    Try to keep overall line lengths in source files to 80 characters or less
+    for obvious reasons. This is not always possible, with lengthy URLs for
+    instance.
+   </para>
+  </listitem> 
+  <listitem>
+   <para>
+    Our documents are available in differing formats. Right now, they 
+    are just plain text, and HTML, but PDF, and others is always a 
+    future possibility. Be careful with URLs (&lt;ulink&gt;), and avoid 
+    this mistake:
+   </para>
+   <para>
+     My favorite site is &lt;ulink url="http://example.com"&gt;here&lt;/ulink&gt;.
+   </para>
+   <para>
+     This will render as <quote>My favorite site is here</quote>, which is 
+     not real helpful in a text doc. Better like this:
+   </para>
+   <para>
+     My favorite site is &lt;ulink url="http://example.com"&gt;example.com&lt;/ulink&gt;.
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    All documents should be spell checked occasionally.
+    <application>aspell</application> can check SGML with the
+    <literal>-H</literal> option. (<application>ispell</application> I think
+    too.)
+   </para>
+  </listitem> 
+
+  </itemizedlist>
+ </para> 
+  
+  </sect2>
+
+  
+ <!--   ~~~~~       New section      ~~~~~     -->
+
+ <sect2><title>Privoxy Custom Entities</title>
+ <para>
+  <application>Privoxy</application> documentation is using 
+  a number of customized <quote>entities</quote> to facilitate 
+  documentation maintenance. 
+ </para>
+ <para>
+  We are using a set of <quote>boilerplate</quote> files with generic text,
+  that is used by multiple docs. This way we can write something once, and use
+  it repeatedly without having to re-write the same content over and over again.
+  If editing such a file, keep in mind that it should be
+  <emphasis>generic</emphasis>. That is the purpose; so it can be used in varying 
+  contexts without additional modifications.
+ </para>
+ <para>
+  We are also using what <application>Docbook</application> calls 
+  <quote>internal entities</quote>. These are like variables in 
+  programming. Well, sort of. For instance, we have the
+  <literal>p-version</literal> entity that contains the current 
+  <application>Privoxy</application> version string. You are strongly 
+  encouraged to use these where possible. Some of these obviously 
+  require re-setting with each release (done by the Makefile). A sampling of
+  custom entities are listed below. See any of the main docs for examples.
+ </para>
+
+ <para>
+  <itemizedlist>
+  <listitem>
+   <para>
+    Re- <quote>boilerplate</quote> text entities are defined like:
+   </para>
+   <para>
+    <literal>&lt;!entity supported SYSTEM "supported.sgml"&gt;</literal>
+   </para>
+   <para>
+     In this example, the contents of the file,
+     <filename>supported.sgml</filename> is available for inclusion anywhere 
+     in the doc. To make this happen, just reference the now defined 
+     entity: <literal>&#38;supported;</literal> (starts with an ampersand 
+     and ends with a semi-colon), and the contents will be dumped into 
+     the finished doc at that point.
+   </para>
+  </listitem> 
+  <listitem>
+   <para>
+    Commonly used <quote>internal entities</quote>:
+  </para>
+  <simplelist>
+   <member>
+    <emphasis>p-version</emphasis>: the <application>Privoxy</application> 
+    version string, e.g. <quote>&p-version;</quote>.
+   </member>
+   <member>
+    <emphasis>p-status</emphasis>: the project status, either 
+    <quote>alpha</quote>, <quote>beta</quote>, or <quote>stable</quote>.
+   </member>
+   <member>
+    <emphasis>p-not-stable</emphasis>: use to conditionally include 
+    text in <quote>not stable</quote> releases (e.g. <quote>beta</quote>).
+   </member>
+   <member>
+    <emphasis>p-stable</emphasis>: just the opposite.
+   </member>
+   <member>
+    <emphasis>p-text</emphasis>: this doc is only generated as text.
+   </member>
+  </simplelist>
+ </listitem> 
+ </itemizedlist>
+ </para> 
+ <para>
+  There are others in various places that are defined for a specific 
+  purpose. Read the source!
+ </para>
+ </sect2>
+  
+ </sect1>
+
+<!--     <listitem><para>be consistent with the redirect script (i.e. the <application>Privoxy</application> program -->
+<!--       points via the redirect URL at sf to valid end-points in the document)</para></listitem> -->
+
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="coding"><title>Coding Guidelines</title>
+
+    <sect2 id="s1"><title>Introduction</title>
+
+    <para>This set of standards is designed to make our lives easier.  It is
+    developed with the simple goal of helping us keep the "new and improved
+    <application>Privoxy</application>" consistent and reliable. Thus making
+    maintenance easier and increasing chances of success of the
+    project.</para>
+
+    <para>And that of course comes back to us as individuals. If we can
+    increase our development and product efficiencies then we can solve more
+    of the request for changes/improvements and in general feel good about
+    ourselves. ;-></para>
+
+  </sect2>
+
+    <sect2 id="s2"><title>Using Comments</title>
+
+    <sect3 id="s3"><title>Comment, Comment, Comment</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Comment as much as possible without commenting the obvious.
+    For example do not comment "aVariable is equal to bVariable".
+    Instead explain why aVariable should be equal to the bVariable.
+    Just because a person can read code does not mean they will
+    understand why or what is being done. A reader may spend a lot
+    more time figuring out what is going on when a simple comment
+    or explanation would have prevented the extra research. Please
+    help your brother IJB'ers out!</para>
+
+    <para>The comments will also help justify the intent of the code.
+    If the comment describes something different than what the code
+    is doing then maybe a programming error is occurring.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+/* if page size greater than 1k ... */
+if ( PageLength() > 1024 )
+{
+    ... "block" the page up ...
+}
+
+/* if page size is small, send it in blocks */
+if ( PageLength() > 1024 )
+{
+    ... "block" the page up ...
+}
+
+This demonstrates 2 cases of "what not to do".  The first is a
+"syntax comment".  The second is a comment that does not fit what
+is actually being done.
+</programlisting>
+  </sect3>
+
+    
+
+    <sect3 id="s4"><title>Use blocks for comments</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Comments can help or they can clutter. They help when they
+    are differentiated from the code they describe. One line
+    comments do not offer effective separation between the comment
+    and the code. Block identifiers do, by surrounding the code
+    with a clear, definable pattern.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+/*********************************************************************
+ * This will stand out clearly in your code!
+ *********************************************************************/
+if ( thisVariable == thatVariable )
+{
+   DoSomethingVeryImportant();
+}
+
+
+/* unfortunately, this may not */
+if ( thisVariable == thatVariable )
+{
+   DoSomethingVeryImportant();
+}
+
+
+if ( thisVariable == thatVariable ) /* this may not either */
+{
+   DoSomethingVeryImportant();
+}</programlisting>
+
+    <para><emphasis>Exception:</emphasis></para>
+
+    <para>If you are trying to add a small logic comment and do not
+    wish to "disrupt" the flow of the code, feel free to use a 1
+    line comment which is NOT on the same line as the code.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s5"><title>Keep Comments on their own line</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>It goes back to the question of readability. If the comment
+    is on the same line as the code it will be harder to read than
+    the comment that is on its own line.</para>
+
+    <para>There are three exceptions to this rule, which should be
+    violated freely and often: during the definition of variables,
+    at the end of closing braces, when used to comment
+    parameters.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+/*********************************************************************
+ * This will stand out clearly in your code,
+ * But the second example won't.
+ *********************************************************************/
+if ( thisVariable == thatVariable )
+{
+   DoSomethingVeryImportant();
+}
+
+if ( thisVariable == thatVariable ) /*can you see me?*/
+{
+   DoSomethingVeryImportant(); /*not easily*/
+}
+
+
+/*********************************************************************
+ * But, the encouraged exceptions:
+ *********************************************************************/
+int urls_read     = 0;     /* # of urls read + rejected */
+int urls_rejected = 0;     /* # of urls rejected */
+
+if ( 1 == X )
+{
+   DoSomethingVeryImportant();
+}
+
+
+short DoSomethingVeryImportant(
+   short firstparam,   /* represents something */
+   short nextparam     /* represents something else */ )
+{
+   ...code here...
+
+}   /* -END- DoSomethingVeryImportant */
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s6"><title>Comment each logical step</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Logical steps should be commented to help others follow the
+    intent of the written code and comments will make the code more
+    readable.</para>
+
+    <para>If you have 25 lines of code without a comment, you should
+    probably go back into it to see where you forgot to put
+    one.</para>
+
+    <para>Most "for", "while", "do", etc... loops _probably_ need a
+    comment. After all, these are usually major logic
+    containers.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s7"><title>Comment All Functions Thoroughly</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>A reader of the code should be able to look at the comments
+    just prior to the beginning of a function and discern the
+    reason for its existence and the consequences of using it. The
+    reader should not have to read through the code to determine if
+    a given function is safe for a desired use. The proper
+    information thoroughly presented at the introduction of a
+    function not only saves time for subsequent maintenance or
+    debugging, it more importantly aids in code reuse by allowing a
+    user to determine the safety and applicability of any function
+    for the problem at hand. As a result of such benefits, all
+    functions should contain the information presented in the
+    addendum section of this document.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s8"><title>Comment at the end of braces if the
+    content is more than one screen length</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Each closing brace should be followed on the same line by a
+    comment that describes the origination of the brace if the
+    original brace is off of the screen, or otherwise far away from
+    the closing brace. This will simplify the debugging,
+    maintenance, and readability of the code.</para>
+
+    <para>As a suggestion , use the following flags to make the
+    comment and its brace more readable:</para>
+
+    <para>use following a closing brace: } /* -END- if() or while ()
+    or etc... */</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+if ( 1 == X )
+{
+   DoSomethingVeryImportant();
+   ...some long list of commands...
+} /* -END- if x is 1 */
+
+or:
+
+if ( 1 == X )
+{
+   DoSomethingVeryImportant();
+   ...some long list of commands...
+} /* -END- if ( 1 == X ) */
+</programlisting>
+  </sect3>
+    
+  </sect2>
+
+    <sect2 id="s9"><title>Naming Conventions</title>
+
+    
+
+    <sect3 id="s10"><title>Variable Names</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Use all lowercase, and separate words via an underscore
+    ('_'). Do not start an identifier with an underscore. (ANSI C
+    reserves these for use by the compiler and system headers.) Do
+    not use identifiers which are reserved in ANSI C++. (E.g.
+    template, class, true, false, ...). This is in case we ever
+    decide to port Privoxy to C++.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+int ms_iis5_hack = 0;</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>
+<programlisting>
+int msiis5hack = 0; int msIis5Hack = 0;
+</programlisting>
+</para>
+
+    
+
+  </sect3>    
+
+    <sect3 id="s11"><title>Function Names</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Use all lowercase, and separate words via an underscore
+    ('_'). Do not start an identifier with an underscore. (ANSI C
+    reserves these for use by the compiler and system headers.) Do
+    not use identifiers which are reserved in ANSI C++. (E.g.
+    template, class, true, false, ...). This is in case we ever
+    decide to port Privoxy to C++.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+int load_some_file( struct client_state *csp )</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>
+<programlisting>
+int loadsomefile( struct client_state *csp )
+int loadSomeFile( struct client_state *csp )
+</programlisting>
+</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s12"><title>Header file prototypes</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Use a descriptive parameter name in the function prototype
+    in header files. Use the same parameter name in the header file
+    that you use in the c file.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+(.h) extern int load_aclfile( struct client_state *csp );
+(.c) int load_aclfile( struct client_state *csp )</programlisting>
+
+    <para><emphasis>Instead of:</emphasis>
+<programlisting>
+(.h) extern int load_aclfile( struct client_state * ); or 
+(.h) extern int load_aclfile(); 
+(.c) int load_aclfile( struct client_state *csp )
+</programlisting>
+</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s13"><title>Enumerations, and #defines</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Use all capital letters, with underscores between words. Do
+    not start an identifier with an underscore. (ANSI C reserves
+    these for use by the compiler and system headers.)</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+(enumeration) : enum Boolean { FALSE, TRUE };
+(#define) : #define DEFAULT_SIZE 100;</programlisting>
+
+    <para><emphasis>Note:</emphasis> We have a standard naming scheme for #defines
+    that toggle a feature in the preprocessor: FEATURE_>, where
+    > is a short (preferably 1 or 2 word) description.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+#define FEATURE_FORCE 1
+
+#ifdef FEATURE_FORCE
+#define FORCE_PREFIX blah
+#endif /* def FEATURE_FORCE */
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s14"><title>Constants</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Spell common words out entirely (do not remove vowels).</para>
+
+    <para>Use only widely-known domain acronyms and abbreviations.
+    Capitalize all letters of an acronym.</para>
+
+    <para>Use underscore (_) to separate adjacent acronyms and
+    abbreviations. Never terminate a name with an underscore.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+#define USE_IMAGE_LIST 1</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>
+<programlisting>
+#define USE_IMG_LST 1 or 
+#define _USE_IMAGE_LIST 1 or
+#define USE_IMAGE_LIST_ 1 or 
+#define use_image_list 1 or
+#define UseImageList 1
+</programlisting>
+</para>
+
+    
+  </sect3>
+
+  </sect2>
+    
+
+    <sect2 id="s15"><title>Using Space</title>
+
+    
+
+    <sect3 id="s16"><title>Put braces on a line by themselves.</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>The brace needs to be on a line all by itself, not at the
+    end of the statement. Curly braces should line up with the
+    construct that they're associated with. This practice makes it
+    easier to identify the opening and closing braces for a
+    block.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+if ( this == that )
+{
+   ...
+}</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>if ( this == that ) { ... }</para>
+
+    <para>or</para>
+
+    <para>if ( this == that ) { ... }</para>
+
+    <para><emphasis>Note:</emphasis> In the special case that the if-statement is
+    inside a loop, and it is trivial, i.e. it tests for a
+    condition that is obvious from the purpose of the block,
+    one-liners as above may optically preserve the loop structure
+    and make it easier to read.</para>
+
+    <para><emphasis>Status:</emphasis> developer-discretion.</para>
+
+    <para><emphasis>Example exception:</emphasis></para>
+<programlisting>
+while ( more lines are read )
+{
+   /* Please document what is/is not a comment line here */
+   if ( it's a comment ) continue;
+
+   do_something( line );
+}
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s17"><title>ALL control statements should have a
+    block</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Using braces to make a block will make your code more
+    readable and less prone to error. All control statements should
+    have a block defined.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+if ( this == that )
+{
+   DoSomething();
+   DoSomethingElse();
+}</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>if ( this == that ) DoSomething(); DoSomethingElse();</para>
+
+    <para>or</para>
+
+    <para>if ( this == that ) DoSomething();</para>
+
+    <para><emphasis>Note:</emphasis> The first example in "Instead of" will execute
+    in a manner other than that which the developer desired (per
+    indentation). Using code braces would have prevented this
+    "feature". The "explanation" and "exception" from the point
+    above also applies.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s18"><title>Do not belabor/blow-up boolean
+    expressions</title>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+structure->flag = ( condition );</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>if ( condition ) { structure->flag = 1; } else {
+    structure->flag = 0; }</para>
+
+    <para><emphasis>Note:</emphasis> The former is readable and concise. The later
+    is wordy and inefficient. Please assume that any developer new
+    to the project has at least a "good" knowledge of C/C++. (Hope
+    I do not offend by that last comment ... 8-)</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s19"><title>Use white space freely because it is
+    free</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Make it readable. The notable exception to using white space
+    freely is listed in the next guideline.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+int firstValue   = 0;
+int someValue    = 0;
+int anotherValue = 0;
+int thisVariable = 0;
+
+if ( thisVariable == thatVariable )
+
+firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s20"><title>Don't use white space around structure
+    operators</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>- structure pointer operator ( "->" ) - member operator (
+    "." ) - functions and parentheses</para>
+
+    <para>It is a general coding practice to put pointers, references,
+    and function parentheses next to names. With spaces, the
+    connection between the object and variable/function name is not
+    as clear.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+aStruct->aMember;
+aStruct.aMember;
+FunctionName();</programlisting>
+
+    <para><emphasis>Instead of:</emphasis> aStruct -> aMember; aStruct . aMember;
+    FunctionName ();</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s21"><title>Make the last brace of a function stand
+    out</title>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+int function1( ... )
+{
+   ...code...
+   return( retCode );
+
+}   /* -END- function1 */
+
+
+int function2( ... )
+{
+}   /* -END- function2 */
+</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>int function1( ... ) { ...code... return( retCode ); } int
+    function2( ... ) { }</para>
+
+    <para><emphasis>Note:</emphasis> Use 1 blank line before the closing brace and 2
+    lines afterward. This makes the end of function standout to
+    the most casual viewer. Although function comments help
+    separate functions, this is still a good coding practice. In
+    fact, I follow these rules when using blocks in "for", "while",
+    "do" loops, and long if {} statements too. After all whitespace
+    is free!</para>
+
+    <para><emphasis>Status:</emphasis> developer-discretion on the number of blank
+    lines. Enforced is the end of function comments.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s22"><title>Use 3 character indentions</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>If some use 8 character TABs and some use 3 character TABs,
+    the code can look *very* ragged. So use 3 character indentions
+    only. If you like to use TABs, pass your code through a filter
+    such as "expand -t3" before checking in your code.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+static const char * const url_code_map[256] =
+{
+   NULL, ...
+};
+
+
+int function1( ... )
+{
+   if ( 1 )
+   {
+      return( ALWAYS_TRUE );
+   }
+   else
+   {
+      return( HOW_DID_YOU_GET_HERE );
+   }
+
+   return( NEVER_GETS_HERE );
+
+}
+</programlisting>
+  </sect3>
+
+  </sect2>
+    
+
+    <sect2 id="s23"><title>Initializing</title>
+
+    
+
+    <sect3 id="s24"><title>Initialize all variables</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Do not assume that the variables declared will not be used
+    until after they have been assigned a value somewhere else in
+    the code. Remove the chance of accidentally using an unassigned
+    variable.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+short anShort = 0;
+float aFloat  = 0;
+struct *ptr = NULL;</programlisting>
+
+    <para><emphasis>Note:</emphasis> It is much easier to debug a SIGSEGV if the
+    message says you are trying to access memory address 00000000
+    and not 129FA012; or arrayPtr[20] causes a SIGSEV vs.
+    arrayPtr[0].</para>
+
+    <para><emphasis>Status:</emphasis> developer-discretion if and only if the
+    variable is assigned a value "shortly after" declaration.</para>
+
+  </sect3>
+  </sect2>
+    
+
+    <sect2 id="s25"><title>Functions</title>
+
+    
+
+    <sect3 id="s26"><title>Name functions that return a boolean as a
+    question.</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Value should be phrased as a question that would logically
+    be answered as a true or false statement</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+ShouldWeBlockThis();
+ContainsAnImage();
+IsWebPageBlank();
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s27"><title>Always specify a return type for a
+    function.</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>The default return for a function is an int. To avoid
+    ambiguity, create a return for a function when the return has a
+    purpose, and create a void return type if the function does not
+    need to return anything.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s28"><title>Minimize function calls when iterating by
+    using variables</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>It is easy to write the following code, and a clear argument
+    can be made that the code is easy to understand:</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+for ( size_t cnt = 0; cnt &lt; blockListLength(); cnt ++ )
+{
+   ....
+}</programlisting>
+
+    <para><emphasis>Note:</emphasis> Unfortunately, this makes a function call for
+    each and every iteration. This increases the overhead in the
+    program, because the compiler has to look up the function each
+    time, call it, and return a value. Depending on what occurs in
+    the blockListLength() call, it might even be creating and
+    destroying structures with each iteration, even though in each
+    case it is comparing "cnt" to the same value, over and over.
+    Remember too - even a call to blockListLength() is a function
+    call, with the same overhead.</para>
+
+    <para>Instead of using a function call during the iterations,
+    assign the value to a variable, and evaluate using the
+    variable.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+size_t len = blockListLength();
+
+for ( size_t cnt = 0; cnt &lt; len; cnt ++ )
+{
+   ....
+}</programlisting>
+
+    <para><emphasis>Exceptions:</emphasis> if the value of blockListLength() *may*
+    change or could *potentially* change, then you must code the
+    function call in the for/while loop.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s29"><title>Pass and Return by Const Reference</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>This allows a developer to define a const pointer and call
+    your function. If your function does not have the const
+    keyword, we may not be able to use your function. Consider
+    strcmp, if it were defined as: extern int strcmp( char *s1,
+    char *s2 );</para>
+
+    <para>I could then not use it to compare argv's in main: int main(
+    int argc, const char *argv[] ) { strcmp( argv[0], "privoxy"
+    ); }</para>
+
+    <para>Both these pointers are *const*! If the c runtime library
+    maintainers do it, we should too.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s30"><title>Pass and Return by Value</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Most structures cannot fit onto a normal stack entry (i.e.
+    they are not 4 bytes or less). Aka, a function declaration
+    like: int load_aclfile( struct client_state csp )</para>
+
+    <para>would not work. So, to be consistent, we should declare all
+    prototypes with "pass by value": int load_aclfile( struct
+    client_state *csp )</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s31"><title>Names of include files</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Your include statements should contain the file name without
+    a path. The path should be listed in the Makefile, using -I as
+    processor directive to search the indicated paths. An exception
+    to this would be for some proprietary software that utilizes a
+    partial path to distinguish their header files from system or
+    other header files.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+#include &lt;iostream.h&gt;     /* This is not a local include */
+#include "config.h"       /* This IS a local include */
+</programlisting>
+
+    <para><emphasis>Exception:</emphasis></para>
+
+    <para>
+<programlisting>
+/* This is not a local include, but requires a path element. */ 
+#include &lt;sys/fileName.h&gt;
+</programlisting>
+</para>
+
+    <para><emphasis>Note:</emphasis> Please! do not add "-I." to the Makefile
+    without a _very_ good reason. This duplicates the #include
+    "file.h" behavior.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s32"><title>Provide multiple inclusion
+    protection</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Prevents compiler and linker errors resulting from
+    redefinition of items.</para>
+
+    <para>Wrap each header file with the following syntax to prevent
+    multiple inclusions of the file. Of course, replace PROJECT_H
+    with your file name, with "." Changed to "_", and make it
+    uppercase.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+#ifndef PROJECT_H_INCLUDED
+#define PROJECT_H_INCLUDED
+ ...
+#endif /* ndef PROJECT_H_INCLUDED */
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s33"><title>Use `extern "C"` when appropriate</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>If our headers are included from C++, they must declare our
+    functions as `extern "C"`. This has no cost in C, but increases
+    the potential re-usability of our code.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* def __cplusplus */
+
+... function definitions here ...
+
+#ifdef __cplusplus
+}
+#endif /* def __cplusplus */
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s34"><title>Where Possible, Use Forward Struct
+    Declaration Instead of Includes</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Useful in headers that include pointers to other struct's.
+    Modifications to excess header files may cause needless
+    compiles.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+/*********************************************************************
+ * We're avoiding an include statement here!
+ *********************************************************************/
+struct file_list;
+extern file_list *xyz;</programlisting>
+
+    <para><emphasis>Note:</emphasis> If you declare "file_list xyz;" (without the
+    pointer), then including the proper header file is necessary.
+    If you only want to prototype a pointer, however, the header
+    file is unnecessary.</para>
+
+    <para><emphasis>Status:</emphasis> Use with discretion.</para>
+
+    
+  </sect3>
+  </sect2>
+
+    <sect2 id="s35"><title>General Coding Practices</title>
+
+    
+
+    <sect3 id="s36"><title>Turn on warnings</title>
+
+    <para><emphasis>Explanation</emphasis></para>
+
+    <para>Compiler warnings are meant to help you find bugs. You
+    should turn on as many as possible. With GCC, the switch is
+    "-Wall". Try and fix as many warnings as possible.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s37"><title>Provide a default case for all switch
+    statements</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>What you think is guaranteed is never really guaranteed. The
+    value that you don't think you need to check is the one that
+    someday will be passed. So, to protect yourself from the
+    unknown, always have a default step in a switch statement.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+switch( hash_string( cmd ) )
+{
+   case hash_actions_file :
+      ... code ...
+      break;
+
+   case hash_confdir :
+      ... code ...
+      break;
+
+   default :
+      log_error( ... );
+      ... anomaly code goes here ...
+      continue; / break; / exit( 1 ); / etc ...
+
+} /* end switch( hash_string( cmd ) ) */</programlisting>
+
+    <para><emphasis>Note:</emphasis> If you already have a default condition, you
+    are obviously exempt from this point. Of note, most of the
+    WIN32 code calls `DefWindowProc' after the switch statement.
+    This API call *should* be included in a default statement.</para>
+
+    <para><emphasis>Another Note:</emphasis> This is not so much a readability issue
+    as a robust programming issue. The "anomaly code goes here" may
+    be no more than a print to the STDERR stream (as in
+    load_config). Or it may really be an ABEND condition.</para>
+
+    <para><emphasis>Status:</emphasis> Programmer discretion is advised.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s38"><title>Try to avoid falling through cases in a
+    switch statement.</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>In general, you will want to have a 'break' statement within
+    each 'case' of a switch statement. This allows for the code to
+    be more readable and understandable, and furthermore can
+    prevent unwanted surprises if someone else later gets creative
+    and moves the code around.</para>
+
+    <para>The language allows you to plan the fall through from one
+    case statement to another simply by omitting the break
+    statement within the case statement. This feature does have
+    benefits, but should only be used in rare cases. In general,
+    use a break statement for each case statement.</para>
+
+    <para>If you choose to allow fall through, you should comment both
+    the fact of the fall through and reason why you felt it was
+    necessary.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s39"><title>Use 'long' or 'short' Instead of
+    'int'</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>On 32-bit platforms, int usually has the range of long. On
+    16-bit platforms, int has the range of short.</para>
+
+    <para><emphasis>Status:</emphasis> open-to-debate. In the case of most FSF
+    projects (including X/GNU-Emacs), there are typedefs to int4,
+    int8, int16, (or equivalence ... I forget the exact typedefs
+    now). Should we add these to IJB now that we have a "configure"
+    script?</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s40"><title>Don't mix size_t and other types</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>The type of size_t varies across platforms. Do not make
+    assumptions about whether it is signed or unsigned, or about
+    how long it is. Do not compare a size_t against another
+    variable of a different type (or even against a constant)
+    without casting one of the values. Try to avoid using size_t if
+    you can.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s41"><title>Declare each variable and struct on its
+    own line.</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>It can be tempting to declare a series of variables all on
+    one line. Don't.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+long a = 0;
+long b = 0;
+long c = 0;</programlisting>
+
+    <para><emphasis>Instead of:</emphasis></para>
+
+    <para>long a, b, c;</para>
+
+    <para><emphasis>Explanation:</emphasis> - there is more room for comments on the
+    individual variables - easier to add new variables without
+    messing up the original ones - when searching on a variable to
+    find its type, there is less clutter to "visually"
+    eliminate</para>
+
+    <para><emphasis>Exceptions:</emphasis> when you want to declare a bunch of loop
+    variables or other trivial variables; feel free to declare them
+    on 1 line. You should, although, provide a good comment on
+    their functions.</para>
+
+    <para><emphasis>Status:</emphasis> developer-discretion.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s42"><title>Use malloc/zalloc sparingly</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>Create a local struct (on the stack) if the variable will
+    live and die within the context of one function call.</para>
+
+    <para>Only "malloc" a struct (on the heap) if the variable's life
+    will extend beyond the context of one function call.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+If a function creates a struct and stores a pointer to it in a
+list, then it should definitely be allocated via `malloc'.
+</programlisting>
+  </sect3>
+    
+
+    <sect3 id="s43"><title>The Programmer Who Uses 'malloc' is
+    Responsible for Ensuring 'free'</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>If you have to "malloc" an instance, you are responsible for
+    insuring that the instance is `free'd, even if the deallocation
+    event falls within some other programmer's code. You are also
+    responsible for ensuring that deletion is timely (i.e. not too
+    soon, not too late). This is known as "low-coupling" and is a
+    "good thing (tm)". You may need to offer a
+    free/unload/destuctor type function to accommodate this.</para>
+
+    <para><emphasis>Example:</emphasis></para>
+<programlisting>
+int load_re_filterfile( struct client_state *csp ) { ... }
+static void unload_re_filterfile( void *f ) { ... }</programlisting>
+
+    <para><emphasis>Exceptions:</emphasis></para>
+
+    <para>The developer cannot be expected to provide `free'ing
+    functions for C run-time library functions ... such as
+    `strdup'.</para>
+
+    <para><emphasis>Status:</emphasis> developer-discretion. The "main" use of this
+    standard is for allocating and freeing data structures (complex
+    or nested).</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s44"><title>Add loaders to the `file_list' structure
+    and in order</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>I have ordered all of the "blocker" file code to be in alpha
+    order. It is easier to add/read new blockers when you expect a
+    certain order.</para>
+
+    <para><emphasis>Note:</emphasis> It may appear that the alpha order is broken in
+    places by POPUP tests coming before PCRS tests. But since
+    POPUPs can also be referred to as KILLPOPUPs, it is clear that
+    it should come first.</para>
+
+    
+  </sect3>
+    
+
+    <sect3 id="s45"><title>"Uncertain" new code and/or changes to
+    existing code, use FIXME</title>
+
+    <para><emphasis>Explanation:</emphasis></para>
+
+    <para>If you have enough confidence in new code or confidence in
+    your changes, but are not *quite* sure of the repercussions,
+    add this:</para>
+
+    <para>/* FIXME: this code has a logic error on platform XYZ, *
+    attempting to fix */ #ifdef PLATFORM ...changed code here...
+    #endif</para>
+
+    <para>or:</para>
+
+    <para>/* FIXME: I think the original author really meant this...
+    */ ...changed code here...</para>
+
+    <para>or:</para>
+
+    <para>/* FIXME: new code that *may* break something else... */
+    ...new code here...</para>
+
+    <para><emphasis>Note:</emphasis> If you make it clear that this may or may not
+    be a "good thing (tm)", it will be easier to identify and
+    include in the project (or conversely exclude from the
+    project).</para>
+
+    
+  </sect3>
+
+  </sect2>
+
+    <sect2 id="s46"><title>Addendum: Template for files and function
+    comment blocks:</title>
+
+    <para><emphasis>Example for file comments:</emphasis></para>
+<programlisting>
+const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $";
+/*********************************************************************
+ *
+ * File        :  $S<!-- Break CVS Substitution -->ource$
+ *
+ * Purpose     :  (Fill me in with a good description!)
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $L<!-- Break CVS Substitution -->og$
+ *
+ *********************************************************************/
+
+
+#include "config.h"
+
+   ...necessary include files for us to do our work...
+
+const char FILENAME_h_rcs[] = FILENAME_H_VERSION;
+</programlisting>
+
+    <para><emphasis>Note:</emphasis> This declares the rcs variables that should be
+    added to the "show-proxy-args" page. If this is a brand new
+    creation by you, you are free to change the "Copyright" section
+    to represent the rights you wish to maintain.</para>
+
+    <para><emphasis>Note:</emphasis> The formfeed character that is present right
+    after the comment flower box is handy for (X|GNU)Emacs users to
+    skip the verbiage and get to the heart of the code (via
+    `forward-page' and `backward-page'). Please include it if you
+    can.</para>
+
+    <para><emphasis>Example for file header comments:</emphasis></para>
+<programlisting>
+#ifndef _FILENAME_H
+#define _FILENAME_H
+#define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $"
+/*********************************************************************
+ *
+ * File        :  $S<!-- Break CVS Substitution -->ource$
+ *
+ * Purpose     :  (Fill me in with a good description!)
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $L<!-- Break CVS Substitution -->og$
+ *
+ *********************************************************************/
+
+
+#include "project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+   ... function headers here ...
+
+
+/* Revision control strings from this header and associated .c file */
+extern const char FILENAME_rcs[];
+extern const char FILENAME_h_rcs[];
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef _FILENAME_H */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
+</programlisting>
+
+    <para><emphasis>Example for function comments:</emphasis></para>
+<programlisting>
+/*********************************************************************
+ *
+ * Function    :  FUNCTION_NAME
+ *
+ * Description :  (Fill me in with a good description!)
+ *
+ * parameters  :
+ *          1  :  param1 = pointer to an important thing
+ *          2  :  x      = pointer to something else
+ *
+ * Returns     :  0 => Ok, everything else is an error.
+ *
+ *********************************************************************/
+int FUNCTION_NAME( void *param1, const char *x )
+{
+   ...
+   return( 0 );
+
+}
+</programlisting>
+
+    <para><emphasis>Note:</emphasis> If we all follow this practice, we should be
+    able to parse our code to create a "self-documenting" web
+    page.</para>
+
+  </sect2>
+
+  </sect1>
+
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="testing"><title>Testing Guidelines</title>
+    <para>To be filled.
+</para>
+
+    <!--   ~~~~~       New section      ~~~~~     -->
+    <sect2 id="testing-plan"><title>Testplan for releases</title>
+      <para>
+       Explain release numbers. major, minor. developer releases. etc.
+
+<orderedlist numeration="arabic">
+          <listitem><para>
+Remove any existing rpm with rpm -e
+</para></listitem>
+          <listitem><para>
+Remove any file that was left over. This includes (but is not limited to)
+      <itemizedlist>
+                <listitem><para>/var/log/privoxy</para></listitem>
+                <listitem><para>/etc/privoxy</para></listitem>
+                <listitem><para>/usr/sbin/privoxy</para></listitem>
+                <listitem><para>/etc/init.d/privoxy</para></listitem>
+                <listitem><para>/usr/doc/privoxy*</para></listitem>
+              </itemizedlist>
+</para></listitem>
+          <listitem><para>
+Install the rpm. Any error messages?
+</para></listitem>
+          <listitem><para>start,stop,status <application>Privoxy</application> with the specific script
+      (e.g. /etc/rc.d/init/privoxy stop). Reboot your machine. Does
+      autostart work?</para></listitem>
+          <listitem><para>Start browsing. Does <application>Privoxy</application> work? Logfile written?</para></listitem>
+          <listitem><para>Remove the rpm. Any error messages? All files removed?</para></listitem>
+        </orderedlist>
+</para>
+    </sect2>
+
+    <!--   ~~~~~       New section      ~~~~~     -->
+    <sect2 id="testing-report"><title>Test reports</title>
+      <para>
+Please submit test reports only with the <ulink url="http://sourceforge.net/tracker/?func=add&amp;group_id=11118&amp;atid=395005">test form</ulink>
+at sourceforge. Three simple steps:
+        <itemizedlist>
+          
+          <listitem><para>Select category: the distribution you test on.</para></listitem>
+          <listitem><para>Select group: the version of <application>Privoxy</application> that we are about to release.</para></listitem>
+          <listitem><para>Fill the Summary and Detailed Description with something
+              intelligent (keep it short and precise).</para>
+          </listitem>
+        </itemizedlist>
+        Do not mail to the mailinglist (we cannot keep track on issues there).
+      </para>
+    </sect2>
+    
+  </sect1>
+
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="newrelease"><title>Releasing a New Version</title>
+    <para>
+        When we release versions of <application>Privoxy</application>,
+        our work leaves our cozy secret lab and has to work in the cold
+        RealWorld[tm]. Once it is released, there is no way to call it
+        back, so it is very important that great care is taken to ensure
+        that everything runs fine, and not to introduce problems in the
+        very last minute.
+    </para>
+    <para>
+        So when releasing a new version, please adhere exactly to the
+        procedure outlined in this chapter.
+    </para>
+
+    <para>
+       The following programs are required to follow this process:
+       <filename>ncftpput</filename> (ncftp), <filename>scp, ssh</filename> (ssh),
+        <filename>gmake</filename> (GNU's version of make), autoconf, cvs.
+    </para>
+
+    <sect2 id="versionnumbers">
+    <title>Version numbers</title>
+
+    <para>
+      First you need to determine which version number the release will have. 
+      <application>Privoxy</application> version numbers consist of three numbers,
+      separated by dots, like in X.Y.Z, where:
+        <itemizedlist>
+          <listitem>
+            <para>
+              X, the version major, is rarely ever changed. It is increased by one if
+              turning a development branch into stable substantially changes the functionality,
+              user interface or configuration syntax. Majors 1 and 2 were 
+              <application>Junkbuster</application>, and 3 will be the first stable
+              <application>Privoxy</application> release.
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              Y, the version minor, represents the branch within the major version.
+              At any point in time, there are two branches being maintained:
+              The stable branch, with an even minor, say, 2N, in which no functionality is
+              being added and only bugfixes are made, and 2N+1, the development branch, in
+              which the further development of <application>Privoxy</application> takes
+              place.
+              This enables us to turn the code upside down and inside out, while at the same time
+              providing and maintaining a stable version.
+              The minor is reset to zero (and one) when the major is inrcemented. When a development
+              branch has matured to the point where it can be turned into stable, the old stable branch
+              2N is given up (i.e. no longer maintained), the former development branch 2N+1 becomes the
+              new stable branch 2N+2, and a new development branch 2N+3 is opened.
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              Z, the point or sub version, represents a release of the software within a branch.
+              It is therefore incremented immediately before each code freeze. 
+              In development branches, only the even point versions correspond to actual releases,
+              while the odd ones denote the evolving state of the sources on CVS in between.
+              It follows that Z is odd on CVS in development branches most of the time. There, it gets
+              increased to an even number immediately before a code freeze, and is increased to an odd
+              number again immediately thereafter.
+              This ensures that builds from CVS snapshots are easily distinguished from released versions.
+              The point version is reset to zero when the minor changes.
+            </para>
+          </listitem>
+        </itemizedlist>
+    </para>
+
+    </sect2>
+     
+    <sect2 id="beforerelease">
+    <title>Before the Release: Freeze</title>
+     <para>
+       The following <emphasis>must be done by one of the
+       developers</emphasis> prior to each new release.
+     </para>
+     <para>
+      <itemizedlist>
+       <listitem>
+        <para>
+         Make sure that everybody who has worked on the code in the last
+         couple of days has had a chance to yell <quote>no!</quote> in case
+         they have pending changes/fixes in their pipelines. Announce the
+         freeze so that nobody will interfere with last minute changes.
+        </para>
+      </listitem> 
+      <listitem>
+       <para>
+         Increment the version number (point from odd to even in development
+         branches!) in <filename>configure.in</filename>.
+       </para>
+      </listitem> 
+      <listitem>
+       <para>
+        If <filename>default.action</filename> has changed since last
+        release (i.e. software release or standalone actions file release),
+        bump up its version info to A.B in this line:
+       </para>
+       <para> 
+        <programlisting>
+  {+add-header{X-Actions-File-Version: A.B} -filter -no-popups}
+</programlisting>
+       </para>
+       <para> 
+        Then change the version info in doc/webserver/actions/index.php,
+        line: '$required_actions_file_version = "A.B";'
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+        If the HTML documentation is not in sync with the SGML sources
+        you need to regenerate and upload it to the webserver. (If in
+        doubt, just do it.) See the Section "Updating the webserver" in
+        this manual for details.
+       </para>
+      </listitem> 
+      <listitem>
+       <para>
+        <emphasis>Commit all files that were changed in the above steps!</emphasis>
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+        Tag all files in CVS with the version number with
+        <quote><command>cvs tag v_X_Y_Z</command></quote>.
+        Don't use vX_Y_Z, ver_X_Y_Z, v_X.Y.Z (won't work) etc.
+       </para>
+      </listitem> 
+     <listitem>
+       <para>
+        If the release was in a development branch, increase the point version
+        from even to odd (X.Y.(Z+1)) again in <filename>configure.in</filename> and
+        commit your change.
+       </para>
+      </listitem> 
+     <listitem>
+       <para>
+        On the webserver, copy the user manual to a new top-level directory
+        called <filename>X.Y.Z</filename>. This ensures that help links from the CGI
+        pages, which have the version as a prefix, will go into the right version of the manual.
+        If this is a development branch release, also symlink <filename>X.Y.(Z-1)</filename>
+        to <filename>X.Y.Z</filename> and <filename>X.Y.(Z+1)</filename> to
+        <filename>.</filename> (i.e. dot). 
+       </para>
+      </listitem> 
+      </itemizedlist>
+     </para> 
+    </sect2>
+    
+    <sect2 id="therelease">
+    <title>Building and Releasing the Packages</title>
+     <para>
+      Now the individual packages can be built and released. Note that for
+      GPL reasons the first package to be released is always the source tarball.
+     </para>
+     <para>
+      For <emphasis>all</emphasis> types of packages, including the source tarball,
+      <emphasis>you must make sure that you build from clean sources by exporting
+      the right version from CVS into an empty directory:</emphasis>.
+     </para>
+      
+     <para>
+      <programlisting>
+  mkdir dist # delete or choose different name if it already exists
+  cd dist
+  cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r v_X_Y_Z current
+</programlisting>
+    </para>
+  
+    <para>
+     <emphasis>Do NOT change</emphasis> a single bit, including, but not limited to
+     version information after export from CVS. This is to make sure that
+     all release packages, and with them, all future bug reports, are based
+     on exactly the same code.
+    </para>
+  
+    <para>
+     Please find additional instructions for the source tarball and the
+     individual platform dependent binary packages below. And details 
+     on the Sourceforge release process below that.
+    </para>
+
+    <sect3 id="pack-guidelines">
+    <title>Note on Privoxy Packaging</title>
+     <para>
+      Please keep these general guidelines in mind when putting together 
+      your package. These apply to <emphasis>all</emphasis> platforms!
+     </para>
+     <para>
+      <itemizedlist>
+       <listitem>
+        <para>
+          <application>Privoxy</application> <emphasis>requires</emphasis>
+          write access to: all <filename>*.action</filename> files, all 
+          logfiles, and the <filename>trust</filename> file. You will 
+          need to determine the best way to do this for your platform.
+        </para>
+       </listitem> 
+       <listitem>
+        <para>
+          Please include up to date documentation. At a bare minimum:
+        </para>
+        <simplelist>
+         <member>
+          <filename>LICENSE</filename> (toplevel directory)
+         </member>
+        </simplelist>
+        <simplelist>
+         <member>
+          <filename>README</filename> (toplevel directory)
+         </member>
+        </simplelist>
+        <simplelist>
+         <member>
+          <filename>AUTHORS</filename> (toplevel directory)
+         </member>
+        </simplelist>
+        <simplelist>
+         <member>
+          <filename>man page</filename> (toplevel directory, Unix-like
+          platforms only)
+         </member>
+        </simplelist>
+        <simplelist>
+         <member>
+          <filename>The User Manual</filename> (doc/webserver/user-manual/)
+         </member>
+        </simplelist>
+        <simplelist>
+         <member>
+          <filename>FAQ</filename> (doc/webserver/faq/)
+         </member>
+        </simplelist>
+        <para>
+          Also suggested: <filename>Developer Manual</filename>
+          (doc/webserver/devel-manual) and <filename>ChangeLog</filename>
+          (toplevel directory). <filename>FAQ</filename> and the manuals are
+          HTML docs. There are also text versions in
+          <filename>doc/text/</filename> which could conceivably also be
+          included.
+        </para>
+        <para>
+         The documentation has been designed such that the manuals are linked
+         to each other from parallel directories, and should be packaged 
+         that way. <filename>index.html</filename> can also be included and 
+         can serve as a focal point for docs and other links of interest.
+         This should be one level up from the manuals. There are two 
+         css stylesheets that can be included for better presentation:
+         <filename>p_doc.css</filename> and <filename>p_web.css</filename>.
+         These should be in the same directory with
+         <filename>index.html</filename>, (i.e. one level up from the manual 
+         directories).
+        </para>
+      </listitem> 
+      <listitem>
+       <para>
+        <filename>user.action</filename> is designed for local preferences. 
+        Make sure this does not get overwritten!
+       </para>
+      </listitem> 
+      <listitem>
+       <para>
+        Other configuration files should be installed as the new defaults, 
+        but all previously installed configuration files should be preserved
+        as backups. This is just good manners :-)
+       </para>
+     </listitem> 
+     <listitem>
+      <para>
+       Please check platform specific notes in this doc, if you haven't 
+       done <quote>Privoxy</quote> packaging before for other platform 
+       specific issues. Conversely, please add any notes that you know 
+       are important for your platform (or contact one of the doc 
+       maintainers to do this if you can't).
+      </para>
+    </listitem> 
+
+      </itemizedlist>
+     </para> 
+    
+    </sect3>
+
+    <sect3 id="newrelease-tarball"><title>Source Tarball</title>
+        <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then do:
+       </para>
+       <para>
+       <programlisting>
+  make tarball-dist
+</programlisting>
+       </para>
+       <para>
+       To upload the package to Sourceforge, simply issue
+       </para>
+       <para>
+       <programlisting>
+  make tarball-upload
+</programlisting>
+       </para>
+       <para>
+       Go to the displayed URL and release the file publicly on Sourceforge.
+        For the change log field, use the relevant section of the
+        <filename>ChangeLog</filename> file.
+      </para>
+    </sect3>
+
+    <sect3 id="newrelease-rpm"><title>SuSE, Conectiva or Red Hat RPM</title>
+        <para>
+        In following text, replace <replaceable class="parameter">dist</replaceable>
+        with either <quote>rh</quote> for Red Hat or <quote>suse</quote> for SuSE.
+        </para>
+        <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). 
+       </para>
+       <para>
+        As the only exception to not changing anything after export from CVS,
+        now examine the file <filename>privoxy-</filename><replaceable class="parameter">dist</replaceable><filename>.spec</filename>
+        and make sure that the version information and the RPM release number are
+        correct. The RPM release numbers for each version start at one. Hence it must
+        be reset to one if this is the first RPM for
+        <replaceable class="parameter">dist</replaceable> which is built from version
+        X.Y.Z. Check the
+        <ulink url="http://sourceforge.net/project/showfiles.php?group_id=11118">file
+        list</ulink> if unsure. Else, it must be set to the highest already available RPM
+        release number for that version plus one.
+       </para>
+       <para>
+        Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then do
+       </para>
+       <para>
+       <programlisting>
+  make <replaceable class="parameter">dist</replaceable>-dist
+</programlisting>
+       </para>
+       <para>
+       To upload the package to Sourceforge, simply issue
+       </para>
+       <para>
+       <programlisting>
+  make <replaceable class="parameter">dist</replaceable>-upload <replaceable class="parameter">rpm_packagerev</replaceable>
+</programlisting>
+       </para>
+       <para>
+        where <replaceable class="parameter">rpm_packagerev</replaceable> is the
+        RPM release number as determined above.
+       Go to the displayed URL and release the file publicly on Sourceforge.
+        Use the release notes and change log from the source tarball package.
+      </para>
+    </sect3>
+
+    <sect3 id="newrelease-os2"><title>OS/2</title>
+      <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then get the OS/2 Setup module:
+       </para>
+       <para>
+       <programlisting>
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co os2setup
+</programlisting>
+       </para>
+       <para>
+       You will need a mix of development tools.
+       The main compilation takes place with IBM Visual Age C++.
+       Some ancillary work takes place with GNU tools, available from
+       various sources like hobbes.nmsu.edu.
+       Specificially, you will need <filename>autoheader</filename>,
+       <filename>autoconf</filename> and <filename>sh</filename> tools.
+       The packaging takes place with WarpIN, available from various sources, including
+       its home page: <ulink url="http://www.xworkplace.org/">xworkplace</ulink>.
+       </para>
+       <para>
+       Change directory to the <filename>os2setup</filename> directory.
+       Edit the os2build.cmd file to set the final executable filename.
+       For example, 
+       </para>
+       <para>
+       <programlisting>
+  installExeName='privoxyos2_setup_X.Y.Z.exe'
+</programlisting>
+       </para>
+       <para>
+       Next, edit the <filename>IJB.wis</filename> file so the release number matches
+       in the <filename>PACKAGEID</filename> section:
+       </para>
+       <para>
+       <programlisting>
+  PACKAGEID="Privoxy Team\Privoxy\Privoxy Package\X\Y\Z"
+</programlisting>
+       </para>
+       <para>
+       You're now ready to build.  Run:
+       </para>
+       <para>
+       <programlisting>
+  os2build
+</programlisting>
+       </para>
+       <para>
+         You will find the  WarpIN-installable executable in the
+        <filename>./files</filename> directory. Upload this anonymously to
+         <filename>uploads.sourceforge.net/incoming</filename>, create a release
+         for it, and you're done. Use the release notes and Change Log from the
+         source tarball package.
+       </para>
+    </sect3>
+
+    <sect3 id="newrelease-solaris"><title>Solaris</title>
+      <para>
+       Login to Sourceforge's compilefarm via ssh:
+       </para>
+       <para>
+       <programlisting>
+  ssh cf.sourceforge.net
+</programlisting>
+       </para>
+       <para>
+       Choose the right operating system (not the Debian one).
+        When logged in, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then run
+       </para>
+       <para>
+       <programlisting>
+  gmake solaris-dist
+</programlisting>
+       </para>
+       <para>
+       which creates a gzip'ed tar archive. Sadly, you cannot use <command>make
+       solaris-upload</command> on the Sourceforge machine (no ncftpput). You now have
+       to manually upload the archive to Sourceforge's ftp server and release
+       the file publicly. Use the release notes and Change Log from the
+        source tarball package.
+       </para>
+    </sect3>
+
+    <sect3 id="newrelease-windows"><title>Windows</title>
+      <para>
+        You should ensure you have the latest version of Cygwin (from
+        <ulink url="http://www.cygwin.com/">http://www.cygwin.com/</ulink>).
+        Run the following commands from within a Cygwin bash shell.
+      </para>
+      <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then get the Windows setup module:
+      </para>
+      <para>
+      <programlisting>
+        cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co winsetup
+</programlisting>
+      </para>
+      <para>
+        Then you can build the package.  This is fully automated, and is
+        controlled by <filename>winsetup/GNUmakefile</filename>.
+        All you need to do is:
+      </para>
+      <para>
+      <programlisting>
+        cd winsetup
+        make
+</programlisting>
+      </para>
+      <para>
+        Now you can manually rename <filename>privoxy_setup.exe</filename> to
+        <filename>privoxy_setup_X_Y_Z.exe</filename>, and upload it to
+        SourceForge. When releasing the package on SourceForge, use the release notes
+        and Change Log from the source tarball package.
+      </para>
+    </sect3>
+
+    <sect3 id="newrelease-debian"><title>Debian</title>
+      <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then, run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then do FIXME.
+       </para>
+    </sect3>
+
+    <sect3 id="newrelease-macosx"><title>Mac OSX</title>
+      <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then get the Mac OSX setup module:
+       </para>
+       <para>
+       <programlisting>
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co osxsetup
+</programlisting>
+       </para>
+       <para>
+       Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd osxsetup
+  build
+</programlisting>
+       </para>
+       <para>
+       This will run <filename>autoheader</filename>, <filename>autoconf</filename> and
+       <filename>configure</filename> as well as <filename>make</filename>.
+       Finally, it will copy over the necessary files to the ./osxsetup/files directory
+       for further processing by <filename>PackageMaker</filename>.
+       </para>
+       <para>
+       Bring up PackageMaker with the PrivoxyPackage.pmsp definition file, modify the package
+       name to match the release, and hit the "Create package" button.
+       If you specify ./Privoxy.pkg as the output package name, you can then create
+       the distributable zip file with the command:
+       </para>
+       <para>
+       <programlisting>
+zip -r privoxyosx_setup_x.y.z.zip Privoxy.pkg
+</programlisting>
+       </para>
+       <para>
+       You can then upload <filename>privoxyosx_setup_x.y.z.zip</filename> anonymously to 
+       <filename>uploads.sourceforge.net/incoming</filename>,
+       create a release for it, and you're done. Use the release notes
+        and Change Log from the source tarball package.
+       </para>
+    </sect3>
+
+    <sect3 id="newrelease-freebsd"><title>FreeBSD</title>
+      <para>
+       Login to Sourceforge's compilefarm via ssh:
+       </para>
+       <para>
+       <programlisting>
+  ssh cf.sourceforge.net
+</programlisting>
+       </para>
+       <para>
+       Choose the right operating system.
+        When logged in, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then run:
+       </para>
+       <para>
+       <programlisting>
+  gmake freebsd-dist
+</programlisting>
+       </para>
+       <para>
+       which creates a gzip'ed tar archive. Sadly, you cannot use <command>make
+       freebsd-upload</command> on the Sourceforge machine (no ncftpput). You now have
+       to manually upload the archive to Sourceforge's ftp server and release
+       the file publicly. Use the release notes and Change Log from the
+        source tarball package.
+       </para>
+    </sect3>
+
+    <sect3 id="newrelease-hpux"><title>HP-UX 11</title>
+      <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then do FIXME.
+       </para>
+    </sect3>
+
+    <sect3 id="newrelease-amiga"><title>Amiga OS</title>
+      <para>
+       First, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then do FIXME.
+       </para>
+    </sect3>
+
+    <sect3 id="newrelease-aix"><title>AIX</title>
+      <para>
+       Login to Sourceforge's compilefarm via ssh:
+       </para>
+       <para>
+       <programlisting>
+  ssh cf.sourceforge.net
+</programlisting>
+       </para>
+       <para>
+       Choose the right operating system.
+        When logged in, <emphasis>make sure that you have freshly exported the right
+        version into an empty directory</emphasis>. (See "Building and releasing
+        packages" above). Then run:
+       </para>
+       <para>
+       <programlisting>
+  cd current
+  autoheader && autoconf && ./configure
+</programlisting>
+       </para>
+       <para>
+       Then run:
+       </para>
+       <para>
+       <programlisting>
+  make aix-dist
+</programlisting>
+       </para>
+       <para>
+       which creates a gzip'ed tar archive. Sadly, you cannot use <command>make
+       aix-upload</command> on the Sourceforge machine (no ncftpput). You now have
+       to manually upload the archive to Sourceforge's ftp server and release
+       the file publicly. Use the release notes and Change Log from the
+        source tarball package.
+       </para>
+    </sect3>
+   </sect2>
+
+   <sect2 id="releasing">
+   <title>Uploading and Releasing Your Package</title>
+    <para>
+      After the package is ready, it is time to upload it 
+      to SourceForge, and go through the release steps. The upload
+      is done via FTP:
+    </para>
+     <para>
+      <itemizedlist>
+       <listitem>
+        <para>
+          Upload to: <ulink url="ftp://upload.sourceforge.net/incoming">ftp://upload.sourceforge.net/incoming</ulink>
+        </para>
+      </listitem> 
+      <listitem>
+       <para>
+         user: <literal>anonymous</literal>
+       </para>
+      </listitem> 
+      <listitem>
+       <para>
+         password: <literal>ijbswa-developers@lists.sourceforge.net</literal>
+       </para>
+      </listitem> 
+     </itemizedlist>
+    </para> 
+    <para>
+     Or use the <command>make</command> targets as described above.
+    </para>
+    <para>
+     Once this done go to <ulink url="http://sourceforge.net/project/admin/editpackages.php?group_id=11118">http://sourceforge.net/project/admin/editpackages.php?group_id=11118</ulink>, 
+     making sure you are logged in. Find your target platform in the 
+     second column, and click <literal>Add Release</literal>. You will 
+     then need to create a new release for your package, using the format 
+     of <literal>$VERSION ($CODE_STATUS)</literal>, e.g. <emphasis>&p-version;
+     (beta)</emphasis>.
+    </para>
+    <para>
+     Now just follow the prompts. Be sure to add any appropriate Release
+     notes. You should see your freshly uploaded packages in 
+     <quote>Step 2. Add Files To This Release</quote>. Check the 
+     appropriate box(es). Remember at each step to hit the 
+     <quote>Refresh/Submit</quote> buttons! You should now see your 
+     file(s) listed in Step 3. Fill out the forms with the appropriate 
+     information for your platform, being sure to hit <quote>Update</quote>
+     for each file. If anyone is monitoring your platform, check the 
+     <quote>email</quote> box at the very bottom to notify them of 
+     the new package. This should do it!
+    </para>
+    <para>
+     If you have made errors, or need to make changes, you can go through 
+     essentially the same steps, but select <literal>Edit Release</literal>, 
+     instead of <literal>Add Release</literal>.
+    </para>
+   </sect2>
+
+    <sect2 id="afterrelease">
+    <title>After the Release</title>
+     <para>
+      When all (or: most of the) packages have been uploaded and made available,
+      send an email to the <ulink url="mailto:ijbswa-announce@lists.sourceforge.net">announce
+      mailing list</ulink>, Subject: "Version X.Y.Z available for download". Be sure to
+      include the
+      <ulink url="http://sourceforge.net/project/showfiles.php?group_id=11118">download
+      location</ulink>, the release notes and the change log.
+     </para>
+   </sect2>
+
+  </sect1>
+  
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="webserver-update"><title>Update the Webserver</title>
+   <para>
+    When updating the webserver, please follow these steps to make
+    sure that no broken links, incosistent contents or permission
+    problems will occur:
+   </para>
+   <para>
+    If you have changed anything in the documentation source SGML files,
+    do:
+   </para>
+   <para>
+    <programlisting>
+  make dok # (or make redkat-dok if make dok doesn't work for you)
+</programlisting>
+   </para>
+   <para>
+    That will generate <filename>doc/webserver/user-manual</filename>,
+    <filename>doc/webserver/developer-manual</filename>,
+    <filename>doc/webserver/faq</filename> and
+    <filename>doc/webserver/index.html</filename> automatically.
+   </para>
+   <para>
+    If you changed the manual page source, generate
+    <filename>doc/webserver/man-page/privoxy-man-page.html</filename>
+    by running <quote><command>make man</command></quote>. (This is
+    a separate target due to dependencies on some obscure perl scripts. 
+    See comments in <filename>GNUmakefile</filename>.)
+   </para>
+   <para>
+    If you want to add new files to the webserver, create them locally in
+    the <filename>doc/webserver/*</filename> directory (or
+    create new directories under <filename>doc/webserver</filename>).
+   </para>
+   <para>
+    Next, commit any changes from the above steps to CVS. All set? Then do
+   </para>
+   <para>
+    <programlisting>
+  make webserver
+</programlisting>
+   </para>
+   <para>
+    This will do the upload to <ulink url="http://www.privoxy.org/">the
+    webserver</ulink> (www.privoxy.org) and ensure all files and directories
+    there are group writable.
+   </para>
+   <para>
+    Please do <emphasis>NOT</emphasis> use any other means of transferring
+    files to the webserver to avoid permission problems.
+   </para>
+  </sect1>
+
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="contact"><title>Contacting the developers, Bug Reporting and Feature Requests</title>
+<!-- Include contacting.sgml  -->
+ &contacting;
+<!-- end contacting -->
+  </sect1>
+  
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+<sect1 id="copyright"><title>Privoxy Copyright, License and History</title>
+
+<!-- Include copyright.sgml -->
+ &copyright;
+<!-- end -->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2><title>License</title>
+<!-- Include copyright.sgml: -->
+ &license;
+<!-- end copyright -->
+</sect2>
+<!--  ~  End section  ~  -->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2><title>History</title>
+<!-- Include history.sgml -->
+ &history;
+<!-- end -->
+</sect2>
+
+</sect1>
+  
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="seealso"><title>See also</title>
+<!-- Include seealso.sgml -->
+ &seealso;
+<!-- end  -->
+
+  </sect1>
+
+  <!--
+
+  This program is free software; you can redistribute it 
+  and/or modify it under the terms of the GNU General
+  Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at
+  your option) any later version.
+
+  This program is distributed in the hope that it will
+  be useful, but WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  The GNU General Public License should be included with
+  this file.  If not, you can view it at
+  http://www.gnu.org/copyleft/gpl.html
+  or write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  $Log: developer-manual.sgml,v $
+  Revision 1.45  2002/05/19 23:01:54  hal9
+  Add small section on general packaging guidelines (e.g. actions files must
+  be writable).
+
+  Revision 1.44  2002/05/15 03:55:17  hal9
+  Fix ulink -> link, and minor modification to release process section for
+  clarification.
+
+  Revision 1.43  2002/05/10 01:48:19  hal9
+  This is mostly proposed copyright/licensing additions and changes. Docs
+  are still GPL, but licensing and copyright are more visible. Also, copyright
+  changed in doc header comments (eliminate references to JB except FAQ).
+
+  Revision 1.42  2002/05/05 20:26:02  hal9
+  Sorting out license vs copyright in these docs.
+
+  Revision 1.41  2002/05/04 08:44:44  swa
+  bumped version
+
+  Revision 1.40  2002/05/04 00:43:43  hal9
+  -Remove TOC/first page kludge with proper stylesheet fix.
+  -Combined the two very brief sections: Intro and Quickstart.
+
+  Revision 1.39  2002/05/02 15:08:25  oes
+  Added explanation about version numbers and RPM package revisions
+
+  Revision 1.38  2002/04/29 02:20:31  hal9
+  Add info on steps for uploading and the release process on SF.
+
+  Revision 1.37  2002/04/26 17:23:29  swa
+  bookmarks cleaned, changed structure of user manual, screen and programlisting cleanups, and numerous other changes that I forgot
+
+  Revision 1.36  2002/04/26 05:25:23  hal9
+  Mass commit to catch a few scattered fixes.
+
+  Revision 1.35  2002/04/17 15:16:15  oes
+  Added link to docbook crash course
+
+  Revision 1.34  2002/04/15 23:39:32  oes
+   - Extended & fixed the release section
+   - Added CVS guideline sections
+   - Separated webserver section from release section
+   - Commented out boilerplate inclusion (If you don't know yet what it is,
+     you shouldn't mess with its code ;-)
+   - Nits & fixes
+
+  Revision 1.33  2002/04/12 03:49:53  hal9
+  Spell checked. Clarification on where docs are kept.
+
+  Revision 1.32  2002/04/11 21:29:58  jongfoster
+  Documenting Win32 release procedure
+
+  Revision 1.31  2002/04/11 09:32:52  oes
+  more nits
+
+  Revision 1.30  2002/04/11 09:24:53  oes
+  nits
+
+  Revision 1.29  2002/04/10 18:45:14  swa
+  generated
+
+  Revision 1.28  2002/04/08 22:59:26  hal9
+  Version update. Spell chkconfig correctly :)
+
+  Revision 1.27  2002/04/08 15:31:18  hal9
+  Touch ups to documentation section.
+
+  Revision 1.26  2002/04/07 23:50:08  hal9
+  Documentation changes to reflect HTML docs now in CVS, and new generated files
+  list.
+
+  Revision 1.25  2002/04/06 05:07:28  hal9
+  -Add privoxy-man-page.sgml, for man page.
+  -Add authors.sgml for AUTHORS (and p-authors.sgml)
+  -Reworked various aspects of various docs.
+  -Added additional comments to sub-docs.
+
+  Revision 1.24  2002/04/04 21:33:37  hal9
+  More on documenting the documents.
+
+  Revision 1.23  2002/04/04 18:46:47  swa
+  consistent look. reuse of copyright, history et. al.
+
+  Revision 1.22  2002/04/04 17:27:56  swa
+  more single file to be included at multiple points. make maintaining easier
+
+  Revision 1.21  2002/04/04 06:48:37  hal9
+  Structural changes to allow for conditional inclusion/exclusion of content
+  based on entity toggles, e.g. 'entity % p-not-stable  "INCLUDE"'. And
+  definition of internal entities, e.g. 'entity p-version "2.9.13"' that will
+  eventually be set by Makefile.
+  More boilerplate text for use across multiple docs.
+
+  Revision 1.20  2002/04/04 03:28:27  david__schmidt
+  Add Mac OSX section
+
+  Revision 1.19  2002/04/03 15:09:42  david__schmidt
+  Add OS/2 build section
+
+  Revision 1.18  2002/04/03 03:51:48  hal9
+  Touch ups.
+
+  Revision 1.17  2002/04/03 01:21:17  hal9
+  Implementing Andreas's suggestions for Release sections.
+
+  Revision 1.16  2002/03/31 23:04:40  hal9
+  Fleshed out the doc section, and added something for an intro so it was not
+  blank.
+
+  Revision 1.15  2002/03/30 22:29:47  swa
+  wrong make flavour
+
+  Revision 1.14  2002/03/30 19:04:08  swa
+  people release differently. no good.
+  I want to make parts of the docs only.
+
+  Revision 1.13  2002/03/27 01:16:41  hal9
+  ditto
+
+  Revision 1.12  2002/03/27 01:02:51  hal9
+  Touch up on name change...
+
+  Revision 1.11  2002/03/26 22:29:55  swa
+  we have a new homepage!
+
+  Revision 1.10  2002/03/24 12:33:01  swa
+  more additions.
+
+  Revision 1.9  2002/03/24 11:01:05  swa
+  name change
+
+  Revision 1.8  2002/03/23 15:13:11  swa
+  renamed every reference to the old name with foobar.
+  fixed "application foobar application" tag, fixed
+  "the foobar" with "foobar". left junkbustser in cvs
+  comments and remarks to history untouched.
+
+  Revision 1.7  2002/03/11 13:13:27  swa
+  correct feedback channels
+
+  Revision 1.6  2002/02/24 14:25:06  jongfoster
+  Formatting changes.  Now changing the doctype to DocBook XML 4.1
+  will work - no other changes are needed.
+
+  Revision 1.5  2001/10/31 18:16:51  swa
+  documentation added: howto generate docs in text and html
+  format, howto move stuff to the webserver.
+
+  Revision 1.4  2001/09/23 10:13:48  swa
+  upload process established. run make webserver and
+  the documentation is moved to the webserver. documents
+  are now linked correctly.
+
+  Revision 1.3  2001/09/13 15:27:40  swa
+  cosmetics
+
+  Revision 1.2  2001/09/13 15:20:17  swa
+  merged standards into developer manual
+
+  Revision 1.1  2001/09/12 15:36:41  swa
+  source files for junkbuster documentation
+
+  Revision 1.3  2001/09/10 17:43:59  swa
+  first proposal of a structure.
+
+  Revision 1.2  2001/06/13 14:28:31  swa
+  docs should have an author.
+
+  Revision 1.1  2001/06/13 14:20:37  swa
+  first import of project's documentation for the webserver.
+
+  -->
+
+</article>
diff --git a/doc/source/faq.sgml b/doc/source/faq.sgml
new file mode 100644 (file)
index 0000000..e32b52d
--- /dev/null
@@ -0,0 +1,1779 @@
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[
+<!entity % dummy "IGNORE"> 
+<!entity supported SYSTEM "supported.sgml">
+<!entity newfeatures SYSTEM "newfeatures.sgml">
+<!entity p-intro SYSTEM "privoxy.sgml">
+<!entity seealso SYSTEM "seealso.sgml">
+<!entity contacting SYSTEM "contacting.sgml">
+<!entity history SYSTEM "history.sgml">
+<!entity copyright SYSTEM "copyright.sgml">
+<!entity license SYSTEM "license.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "IGNORE">        <!-- define we are not a text only doc -->
+<!entity % p-doc "INCLUDE">        <!-- and we are a formal doc           -->
+<!entity % p-supp-userman "INCLUDE"> <!-- Include all from supported.sgml -->
+<!entity  my-copy "&copy;">          <!-- kludge for docbook2man          -->
+]>
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/faq.sgml,v $
+
+ Purpose     :  FAQ
+                This file belongs into
+                ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+                
+ $Id: faq.sgml,v 1.60 2002/05/22 17:17:48 oes Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ Based partially on the Internet Junkbuster FAQ originally written by and
+ Copyright (C) 1997 Anonymous Coders and Junkbusters Corporation.
+ http://www.junkbusters.com/
+
+ <Qandaset defaultlabel='qanda'>
+  <QandAEntry>
+   <question>
+    <para> 
+     How are you?
+    </para>
+   </question>
+   <answer>
+    <para> 
+     Fine.
+    </para>
+   </answer>
+  </QandAEntry>
+ </QandASet>
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation. You have been warned!
+ Failure to abide by this rule will result in the revocation of your license 
+ to live a peaceful existence!
+ ========================================================================
+
+
+-->
+
+
+<article id="index" class="faq">
+<artheader>
+<title>Privoxy Frequently Asked Questions</title>
+
+<pubdate>
+ <subscript>
+<!-- Completely the wrong markup, but very little is allowed  -->
+<!-- in this part of an article. FIXME -->
+ <link linkend="copyright">Copyright</link> &my-copy; 2001, 2002 by 
+ <ulink url="http://www.privoxy.org">Privoxy Developers</ulink>
+ </subscript>
+</pubdate>
+
+<pubdate>$Id: faq.sgml,v 1.60 2002/05/22 17:17:48 oes Exp $</pubdate>
+
+<!--
+
+Note: this should generate a separate page, and a live link to it. 
+But it doesn't for some mysterious reason. Please leave commented
+unless it can be fixed proper. For the time being, the copyright 
+statement will be in copyright.smgl.
+
+Hal.
+
+<legalnotice id="legalnotice"> 
+ <para>
+  text goes here ........
+ </para>
+</legalnotice>
+
+-->
+
+<!--
+<authorgroup>
+ <author>
+  <affiliation>
+   <orgname>By: Privoxy Developers</orgname>
+   </affiliation>
+ </author>
+</authorgroup>
+-->
+<abstract>
+<![%dummy;[
+<para>
+ <comment>
+  This is here to keep vim syntax file from breaking :/
+  If I knew enough to fix it, I would.
+  PLEASE DO NOT REMOVE! HB: hal@foobox.net
+ </comment>
+</para>
+]]>
+ <para>
+ This FAQ gives quick answers to frequently asked  questions about
+ <ulink url="http://www.privoxy.org/">Privoxy</ulink> 
+ <![%p-stable;[ v.&p-version]]>. It can't and doesn't replace the
+ <ulink url="../user-manual/index.html">user manual</ulink>.
+ </para>
+
+<!-- Include privoxy.sgml boilerplate: -->
+ &p-intro;
+<!-- end boilerplate -->
+
+ <para>
+  You can find the latest version of the document at <ulink
+  url="http://www.privoxy.org/faq/">http://www.privoxy.org/faq/</ulink>.
+  Please see the Contact section if you want to contact the developers.
+ </para>
+
+<!--   <para> -->
+<!--    Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>. -->
+<!--   </para> -->
+</abstract>
+</artheader>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1 id="general"><title>General Information</title>
+
+<sect2 renderas="sect3" id="newjb"><title>What is this new version of <application>Privoxy</application>?</title>
+
+<!-- Include history.sgml -->
+ &history;
+<!-- end -->
+
+</sect2>
+
+
+<sect2 renderas="sect3">
+<title id="whyprivoxy">Why <quote>Privoxy</quote>? Why a name change at all?</title>
+<para>
+ <application>Privoxy</application> is the 
+ <quote><emphasis>Privacy Enhancing Proxy</emphasis></quote>. Also, its content
+ modification and junk suppression allow you to browse your
+ <quote><emphasis>private</emphasis> edition</quote> of the web.
+</para>
+<para>
+ <ulink url="http://junkbusters.com/">Junkbusters Corporation</ulink>
+ continues to offer their original version of the <application>Internet
+ Junkbuster</application>, so publishing our
+ <application> Junkbuster</application>-derived software under the same name
+ led to confusion.
+</para>
+<para>
+ There are also potential legal complications from the continued use of the 
+ <application>Junkbuster</application> name, which is a registered trademark of 
+ <ulink url="http://junkbusters.com/">Junkbusters Corporation</ulink>.
+ There are, however, no objections from Junkbusters Corporation to the 
+ <application>Privoxy</application> project itself, and they, in fact, still
+ share our ideals and goals.
+</para>
+<para>
+ The developers also believed that there are so many changes from the original 
+ code, that it was time to make a clean break from the past and make 
+ a name in their own right<![%p-not-stable;[, especially now with the pending
+ release of version 3.0]]>.
+</para>
+</sect2>
+
+
+<sect2 renderas="sect3" id="differs"><title>How does <application>Privoxy</application> differ
+from the old <application>Junkbuster?</application></title> 
+<para>
+ <application>Privoxy</application> picks up where
+ <application>Junkbuster</application> left off. All the old features remain.
+ The new <application>Privoxy</application> still blocks ads and banners,
+ still manages cookies, and still helps protect your privacy. But, these are
+ all enhanced, and many new features have been added, all in the same vein.
+ </para>
+ <para>
+ The configuration has changed significantly as well. This is something that
+ users will notice right off the bat if upgrading from 
+ <application>Junkbuster</application> 2.0.x. The <quote>blocklist</quote>
+ <quote>cookielist</quote>, <quote>imagelist</quote> and much more has been
+ combined into the <quote>actions</quote> files, with a completely different
+ syntax. See the <ulink url="../user-manual/upgradersnote.html">note to
+ upgraders</ulink> for  details.
+</para>
+<para>
+ <application>Privoxy</application>'s new features include:
+</para>
+
+<!-- Include newfeatures.sgml: --> 
+ &newfeatures;
+<!-- end include -->
+
+</sect2>
+
+<sect2 renderas="sect3" id="proxymoron"><title>What is a <quote>proxy</quote>? How does
+<application>Privoxy</application> work? </title>
+ <para>
+  A web proxy is a service, based on a software such as <application>Privoxy</application>,
+  that clients (i.e. browsers) can use instead of connecting directly to the web
+  servers on the Internet. The clients then ask the proxy to fetch the objects
+  they need (web pages, images, movies etc) on their behalf, and when the proxy
+  has done so, it hands the results back to the client.
+ </para>
+ <para>
+  There are many reasons to use web proxies, such as security (firewalling),
+  efficiency (caching) and others, and there are just as many different proxies
+  to accommodate those needs.
+ </para>
+ <para>
+  <application>Privoxy</application> is a proxy that is solely focused on privacy
+  protection and junk elimination. Sitting between your browser(s) and the Internet,
+  it is in a perfect position to filter outbound personal information that your
+  browser is leaking, as well as inbound junk. It uses a variety of techniques to do
+  this, all of which are under your control via the various configuration
+  files and options.
+ </para>
+</sect2>
+
+
+<sect2 renderas="sect3" id="whatsanad">
+<title id="knows">How does <application>Privoxy</application> know what is
+an ad, and what is not?</title>
+<para>
+ <application>Privoxy</application>'s approach to blocking ads is twofold:
+</para>
+<para>
+ First, there are certain patterns in the <emphasis>locations</emphasis> (URLs)
+ of banner images. This applies to both the path (you wouldn't guess how many
+ web sites serve their banners from a directory called <quote>banners</quote>!)
+ and the host (blocking the big banner hosting services like doublecklick.net
+ already helps a lot). <application>Privoxy</application> takes advantage of this
+ fact by using <ulink url="../user-manual/actions-file.html#AF-PATTERNS">URL
+ patterns</ulink> to sort out and block the requests for banners.
+</para>
+<para>
+ Second, banners tend to come in certain <emphasis>sizes</emphasis>. But you
+ can't tell the size of an image by its URL without downloading it, and if you
+ do, it's too late to save bandwidth. Therefore, <application>Privoxy</application>
+ also inspects the HTML sources of web pages while they are loaded, and replaces
+ references to images with standard banner sizes by dummy references, so that
+ your browser doesn't request them anymore in the first place.
+</para>
+<para>
+ Both of this involves a certain amount of guesswork and is, of course, freely
+ configurable.
+</para>
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="mistakes">Can <application>Privoxy</application> make mistakes? 
+This does not sound very scientific.</title>
+<para>
+ Actually, it's a black art ;-) And yes, it is always possible to have a broad
+ rule accidentally block or change something by mistake. There is a good chance
+ you may run into such a situation at some point. It is tricky writing rules to
+ cover every conceivable possibility, and not occasionally get false positives.
+</para>
+
+<para>
+ But this should not be a big concern since the
+ <application>Privoxy</application> configuration is very flexible, and
+ includes tools to help identify these types of situations so they can be
+ addressed as needed, allowing you to customize your installation.
+ (<link linkend="badsite">See the Troubleshooting section below</link>.)
+</para>
+
+</sect2>
+
+
+<sect2 renderas="sect3" id="browsers2"><title>My browser does the same things as
+<application>Privoxy</application>. Why should I use
+<application>Privoxy</application> at all?</title>
+ <para>
+  Modern browsers do indeed have <emphasis>some</emphasis> of the same
+  functionality as <application>Privoxy</application>. Maybe this is
+  adequate for you. But <application>Privoxy</application> is much more
+  versatile and powerful, and can do a number of things that browsers just can't.
+ </para>
+ <para>
+  In addition, a proxy is good choice if you use multiple browsers, or 
+  have a LAN with multiple computers. This way all the configuration 
+  is in one place, and you don't have to maintain a similar configuration 
+  for possibly many browsers.
+ </para>
+</sect2>
+
+
+
+<sect2 renderas="sect3" id="license"><title>Is there is a license or fee? What about a 
+warranty? Registration?</title>
+ <para>
+  <application>Privoxy</application> is licensed under the <ulink
+  url="http://www.gnu.org/copyleft/gpl.html">GNU General Public License (GPL)</ulink>.
+  It is free to use, copy, modify or distribute as you wish under the terms of this
+  license.  Please see the <link linkend="copyright">Copyright</link> section for more
+  information on the license and copyright. Or the <filename>LICENSE</filename> file 
+  that should be included.
+ </para>
+ <para>
+  There is <emphasis>no warranty</emphasis> of any kind, expressed, implied or otherwise.
+  That is something that would cost real money ;-) There is no registration either.
+  <application>Privoxy</application> really is <emphasis>free</emphasis>
+  in every respect!
+ </para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="jointeam"><title>I would like to help you, what do I do?</title>
+
+<sect3 renderas="sect4" id="jointeam-money"><title>Money Money Money</title>
+<para>
+ We, of course, welcome donations and could use money for domain registering,
+ buying software to test <application>Privoxy</application> with, and, of course,
+ for regular world-wide get-togethers (hahaha). If you enjoy the software and feel
+ like helping us with a donation, just <ulink
+ url="mailto:developers@privoxy.org">drop us a note</ulink>.
+</para>
+</sect3>
+
+<sect3 renderas="sect4" id="jointeam-software"><title>Software</title>
+<para>
+ If you are a vendor of a web-related software like a browser, web server
+ or proxy, and would like us to ensure that <application>Privoxy</application>
+ runs smoothly with your product, you might consider supplying us with a
+ copy or license. We can't, however, guarantee that we will fix all potential
+ compatibility issues as a result.
+</para>
+</sect3>
+
+<sect3 renderas="sect4" id="jointeam-work"><title>You want to work with us?</title>
+<para>
+   Well, helping the team is always a good idea. We welcome new developers,
+   packaging gurus or documentation writers. Simply <ulink
+   url="https://sourceforge.net/account/register.php">get an account on SourceForge.net</ulink>
+   and mail your id to the <ulink url="mailto:developers@privoxy.org">developers
+   mailing list</ulink>. Then read the <ulink
+   url="../developer-manual/index.html">Developer's Manual</ulink>.
+</para>
+<para>
+ Once we have added you to the team, you'll have write access to the <ulink
+ url="http://sourceforge.net/cvs/?group_id=11118">CVS repository</ulink>, and
+ together we'll find a suitable task for you.
+</para>
+</sect3>
+
+</sect2>
+
+</sect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1  id="installation"><title>Installation</title>
+
+<sect2 renderas="sect3" id="whichbrowsers">
+<title>Which browsers are supported by <application>Privoxy</application>?</title>
+<para>
+ Any browser that can be configured to use a proxy, which 
+ should be virtually all browsers. Direct browser support is not necessary
+ since <application>Privoxy</application> runs as a separate application and
+ talks to the browser in the standardized HTTP protocol, just like a web server
+ does.
+</para>
+</sect2>
+
+<sect2 renderas="sect3" id="whichos">
+<title>Which operating systems are supported?</title>
+<!--
+Include supported.sgml here:
+-->
+&supported;
+</sect2>
+
+<sect2 renderas="sect3" id="newinstall"><title>Can I install  
+ <application>Privoxy</application> over <application>Junkbuster</application>?</title>
+ <para>
+   We recommend you un-install <application>Junkbuster</application>
+   first to minimize conflicts and confusion. You may want to 
+   save your old configuration files for future reference. The configuration
+   files and syntax have substantially changed, so you will need to manually
+   port your old patterns. See the <ulink url="../user-manual/upgradersnote.html">note
+   to upgraders</ulink> and <ulink url="../user-manual/installation.html">installation
+   chapter</ulink> in the <ulink url="../user-manual/index.html">user manual</ulink>
+   for details.
+ </para>
+ <para>
+  Note: Some installers may automatically un-install
+  <application>Junkbuster</application>, if present!
+ </para>
+
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="firststep">I just installed <application>Privoxy</application>. Is there anything 
+special I have to do now?</title>
+
+<para>
+ All browsers must be told to use <application>Privoxy</application> 
+ as a proxy by specifying the correct proxy address and port number 
+ in the appropriate configuration area for the browser. See below.
+ You should also flush your browser's memory and disk cache to get rid of any
+ cached junk items.
+
+</para>
+
+</sect2>
+
+
+<sect2 renderas="sect3" id="localhost"><title>What is the proxy address of <application>Privoxy</application>?</title>
+ <para>
+  If you set up the <application>Privoxy</application> to run on
+  the computer you browse from (rather than your ISP's server or some
+  networked computer on a LAN), the proxy will be on <literal>127.0.0.1</literal> 
+  (sometimes referred to as <quote>localhost</quote>,
+  which is the special name used by every computer on the Internet to refer
+  to itself) and the port will be 8118 (unless you have <application>Privoxy</application>
+  to run on a different port with the <ulink
+  url="../user-manual/config.html#LISTEN-ADDRESS">listen-address</ulink> config option). 
+ </para>
+ <para>
+  When configuring your browser's proxy settings you typically enter
+  the word <quote>localhost</quote> or the IP address <quote>127.0.0.1</quote>
+  in the boxes next to <quote>HTTP</quote> and <quote>Secure</quote> (HTTPS) and
+  then the number <quote>8118</quote> for <quote>port</quote>. 
+  This tells your browser to send all web requests to <application>Privoxy</application>
+  instead of directly to the Internet.
+ </para>
+ <para>
+  <application>Privoxy</application> can also be used to proxy for 
+  a Local Area Network. In this case, your would enter either the IP 
+  address of the LAN host where <application>Privoxy</application> 
+  is running, or the equivalent hostname. Port assignment would be 
+  same as above. Note that <application>Privoxy</application> doesn't
+  listen on any LAN interfaces by default.
+ </para>
+ <para>
+  <application>Privoxy</application> does not currently handle
+  protocols such as FTP, SMTP, IM, IRC, ICQ, or other Internet
+  protocols. 
+ </para>
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="nothing">I just installed <application>Privoxy</application>, and nothing is happening.
+All the ads are there. What's wrong?</title>
+
+<para>
+ Did you configure your browser to use <application>Privoxy</application> 
+ as a proxy? It does not sound like it. See above. You might also try flushing
+ the browser's caches to force a full re-reading of pages. You can verify 
+ that <application>Privoxy</application> is running, and your browser 
+ is correctly configured by entering the special URL: 
+ <ulink url="http:/config.privoxy.org/">http://config.privoxy.org/</ulink>.
+ This should take you to a page titled <quote>This is Privoxy..</quote> with
+ access to <application>Privoxy's</application> internal configuration.
+ If you see this, then you are good to go. If you receive a page saying 
+ <quote>Privoxy is not running</quote>, then the browser is not set up to use
+ your <application>Privoxy</application> installation.
+ If you receive anything else (probably nothing at all), it could either
+ be that the browser is not set up correctly, or that
+ <application>Privoxy</application> is not running at all. Check the <ulink
+ url="../user-manual/config.html#LOGFILE">log file</ulink>.
+
+
+</para>
+
+</sect2>
+
+</sect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1 id="configuration"><title>Configuration</title>
+
+<sect2 renderas="sect3" id="newconfig"><title>Can I use my old config files?</title>
+ <para>
+   The syntax, number, and purpose of configuration files has substantially
+   changed from <application>Junkbuster</application> and earlier versions
+   of <application>Privoxy</application>. The old files, like <filename>blocklist</filename>
+   will not work at all. If you are upgrading from a 2.0.x version, you will
+   need to port your configuration data to the new format. Note that even the
+   pattern syntax has changed! Even configuration files from the 2.9.x versions
+   will need to be adapted, as configuration syntax has been very much in flow
+   in the 2.9.x series.
+ </para>
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="actionsfile">What is an <quote>actions</quote> file?</title>
+
+<para>
+ <ulink url="../user-manual/actions-file.html">Actions files</ulink>
+ are where various <ulink url="../user-manual/actions-file.html#ACTIONS">actions</ulink>
+ that <application>Privoxy</application> might take while processing a certain
+ request, are configured. Typically, you would define a set of default actions
+ that apply to all URLs, then add exceptions to these defaults where needed.
+</para>
+<para>
+ Actions can be defined on a <ulink
+ url="../user-manual/actions-file.html#AF-PATTERNS">URL pattern</ulink> basis, i.e.
+ for single URLs, whole web sites, groups or parts thereof etc. Actions can also be
+ grouped together and then applied to requests matching one or more patterns.
+ There are many possible actions that might apply to any given site. As an example,
+ if you are blocking cookies as one of your default actions, but need to accept
+ cookies from a given site, you would need to define an exception for this
+ site in one of your actions files, preferably in <filename>user.action</filename>
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="actionss">
+<title>The <quote>actions</quote> concept confuses me. Please list 
+some of these <quote>actions</quote>.</title>
+<para>
+ For a comprehensive discussion of the actions concept, please refer
+ to the <ulink url="../user-manual/actions-file.html">actions file
+ chapter</ulink> in the <ulink url="../user-manual/index.html">user
+ manual</ulink>. It includes a <ulink
+ url="../user-manual/actions-file.html#ACTIONS">list of all actions</ulink>
+ and an <ulink url="../user-manual/actions-file.html#ACT-EXAMPLES">actions
+ file tutorial</ulink> to get you started.
+</para>
+</sect2>
+
+
+<sect2 renderas="sect3">
+<title id="actconfig">How are actions files configured? What is the easiest
+way to do this?</title> 
+
+<para>
+ Actions files are just text files in a special syntax and can be edited
+ with a text editor. The probably easiest way is to access
+ <application>Privoxy</application>'s user interface with your web browser
+ at <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>
+ (Shortcut: <ulink url="http://p.p/">http://p.p/</ulink>) and then select
+ <quote><ulink url="http://config.privoxy.org/show-status">View &
+ change the current configuration</ulink></quote> from the menu.
+</para>
+</sect2>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 renderas="sect3">
+<title>There are several different <quote>actions</quote> files. What are
+the differences?</title>
+<para>
+ As of <application>Privoxy</application> v2.9.15, three actions files 
+ are being included, to be used for 
+ different purposes: These are 
+ <filename>default.action</filename>, the <quote>main</quote> actions file
+ which is actively maintained by the <application>Privoxy</application>
+ developers, <filename>user.action</filename>, where users are encouraged
+ to make their private customizations, and <filename>standard.action</filename>, 
+ which is for internal <application>Privoxy</application> use only.
+ Please see <ulink url="../user-manual/actions-file.html">the actions chapter</ulink>
+ in the <ulink url="../user-manual/index.html">user manual</ulink> for a more
+ detailed explanation.
+</para>
+
+<para>
+ Earlier versions included three different versions of the 
+ <filename>default.action</filename> file. The new scheme allows for 
+ greater flexibility of local configuration, and for browser based 
+ selection of pre-defined <quote>aggressiveness</quote> levels.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="yahoo"><title>How can I make my Yahoo/Hotmail/GMX account work?</title>
+ <para>
+  The default configuration shouldn't impact the usability of any of these services.
+  It will, however, make all cookies temporary, so that your browser will forget your
+  login credentials in between browser sessions. If you would like not to have to log
+  in manually each time you access those websites, simply turn off all cookie handling
+  for them in the <filename>user.action</filename> file. An example for yahoo might
+  look like:
+ </para>
+ <para>
+  <screen># Allow all cookies for Yahoo login:
+#
+{ -<ulink url="../user-manual/actions-file.html#CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</ulink> -<ulink url="../user-manual/actions-file.html#CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</ulink> -<ulink url="../user-manual/actions-file.html#SESSION-COOKIES-ONLY">session-cookies-only</ulink> }
+.login.yahoo.com</screen>
+ </para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="configfiles"> <title>What's the difference between the
+<quote>Cautious</quote>, <quote>Medium</quote> and <quote>Advenced</quote> defaults?</title>
+ <para>
+  Configuring <application>Privoxy</application> is not entirely trivial. To help you get
+  started, we provide you with three different default action <quote>packages</quote> in
+  the web based actions file editor at <ulink
+  url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>.
+  The following table shows you, which of the most important features are enabled in each
+  configuration:
+ </para>
+ <para>
+<table frame=all><title>Default Configurations</title>
+<tgroup cols=4 align=left colsep=1 rowsep=1>
+<colspec colname=c1>
+<colspec colname=c2>
+<colspec colname=c3>
+<colspec colname=c4>
+<thead>
+<row>
+  <entry>Feature</entry>
+  <entry>Cautious</entry>
+  <entry>Intermadiate</entry>
+  <entry>Advanced</entry>
+</row>
+</thead>
+<!--  <tfoot> -->
+<!--  <row> -->
+<!--    <entry>f1</entry> -->
+<!--    <entry>f2</entry> -->
+<!--    <entry>f3</entry> -->
+<!--    <entry>f4</entry> -->
+<!--  </row> -->
+<!--  </tfoot> -->
+<tbody>
+
+<row>
+  <entry>Ad-blocking by URL</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>Ad-filtering by size</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>GIF de-animation</entry>
+  <entry>no</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>Referer forging</entry>
+  <entry>no</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>Cookie handling</entry>
+  <entry>none</entry>
+  <entry>session-only</entry>
+  <entry>kill</entry>
+</row>
+
+<row>
+  <entry>Pop-up killing</entry>
+  <entry>no</entry>
+  <entry>no</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>Fast redirects</entry>
+  <entry>no</entry>
+  <entry>no</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>HTML taming</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>JavaScript taming</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>Web-bug killing</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+  <entry>yes</entry>
+</row>
+
+<row>
+  <entry>Fun text replacements</entry>
+  <entry>no</entry>
+  <entry>no</entry>
+  <entry>yes</entry>
+</row>
+
+</tbody>
+</tgroup>
+</table>
+</para>
+<para>
+ Where the defaults are likely to break some sites, exceptions for
+ known popular <quote>problem</quote> sites are included, but in
+ general, the more aggressive your default settings are, the more
+ exceptions you will have to make later. See the <ulink
+ url="../user-manual/index.html">user manual</ulink> for a more
+ deatiled discussion.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="browseconfig"> <title>Why can I change the configuration 
+with a browser? Does that not raise security issues?</title>
+ <para>
+  It may seem strange that regular users can edit the config files with their
+  browsers, although the whole <filename>/etc/privoxy</filename> hierarchy
+  belongs to the user <quote>privoxy</quote>, with only 644 permissions.
+ </para>
+ <para>
+  When you use the browser-based editor, <application>Privoxy</application>
+  itself is writing to the config files.  Because
+  <application>Privoxy</application> is running as the user <quote>privoxy</quote>,
+  it can update the config files.
+ </para>
+ <para>
+  If you run <application>Privoxy</application> for multiple untrusted users (e.g. in
+  a LAN), you will probably want to turn the web-based editor and remote toggle
+  features off by setting <quote><literal><ulink
+  url="../user-manual/config.html#ENABLE-EDIT-ACTIONS">enable-edit-actions</ulink>
+  0</literal></quote> and <quote><literal><ulink
+  url="../user-manual/config.html#ENABLE-REMOTE-TOGGLE">enable-remote-toggle</ulink>
+  0</literal></quote> in the <ulink url="../user-manual/config.html">main configuration file</ulink>.
+ </para>
+ <para>
+  Note that in the default configuration, only local users (i.e. those on
+  <quote>localhost</quote>) can connect to <application>Privoxy</application>,
+  so this is not (normally) a security problem.
+ </para>
+</sect2>
+
+
+<sect2 renderas="sect3">
+<title id="filterfile">What is the <filename>default.filter</filename> file?</title>
+<para>
+ The <ulink url="../user-manual/filter-file.html"><filename>default.filter</filename></ulink>
+ file is where <emphasis>filters</emphasis> are defined, which can be used to modify or
+ remove, web page content on the fly. This applies to <emphasis>anything</emphasis>
+ in the page source, including HTML tags, and JavaScript. Regular expressions are used
+ to accomplish this. There are a number of pre-defined filters to deal with common
+ annoyances. The filters are only defined here, to invoke them, you need to use the
+ <ulink url="../user-manual/actions-file.html#FILTER"><literal>filter</literal> action</ulink>.
+</para>
+
+<para>
+ If you are familiar with regular expressions, and HTML, you can look at 
+ the provided <filename>default.filter</filename> with a text editor and define
+ your own filters.  This is potentially a very powerful feature, but
+ requires some expertise. 
+</para>
+
+<para>
+ Presently, there is no GUI editor option for this part of the configuration, 
+ but you can disable/enable the various pre-defined filters of the included 
+ <filename>default.filter</filename> file with the <ulink
+ url="http://config.privoxy.org/show-status">web-based actions file editor</ulink>.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="lanconfig">How can I set up <application>Privoxy</application> to act as a proxy for my 
+ LAN?</title>
+<para>
+ By default, <application>Privoxy</application> only responds to requests 
+ from <literal>127.0.0.1</literal> (localhost). To have it act as a server for
+ a network, this needs to be changed in the <ulink
+ url="../user-manual/config.html">main configuration file</ulink>. Look for
+ the <literal><ulink
+ url="../user-manual/config.html#LISTEN-ADDRESS">listen-address</ulink></literal>
+ option, which may be commented out with a <quote>#</quote> symbol. Make sure
+ it is uncommented, and assign it the address of the LAN gateway interface,
+ and port number to use. Assuming your LAN address is 192.168.1.1 and you
+ wish to run <application>Privoxy</application> on port 8118, this line
+ schould look like:
+</para>
+
+<para>
+ <screen>
+  listen-address  192.168.1.1:8118</screen>
+</para>
+
+<para>
+ Save the file, and restart <application>Privoxy</application>. Configure 
+ all browsers on the network then to use this address and port number.
+</para>
+
+<para>
+ If you run <application>Privoxy</application> on a LAN with untrusted users,
+ we recommend that you double-check the <ulink
+ url="../user-manual/config.html#ACCESS-CONTROL">access control and security</ulink>
+ options!
+</para>
+
+</sect2>
+
+
+<sect2 renderas="sect3">
+<title id="noseeum">Instead of ads, now I get a checkerboard pattern. I don't want to see anything.</title>
+<para>
+ The replacement for blocked images can be controlled with the <ulink
+ url="../user-manual/actions-file.html#SET-IMAGE-BLOCKER"><literal>set-image-blocker</literal>
+ action</ulink>. You have the choice of a checkerboard pattern, a transparent 1x1 GIF
+ image (aka <quote>blank</quote>), or a redirect to a custom image of your choice.
+ Note that this choice only has effect for images which are blocked as images, i.e.
+ whose URLs match both a <literal><ulink
+ url="../user-manual/actions-file.html#HANDLE-AS-IMAGE">handle-as-image</ulink></literal>
+ <emphasis>and</emphasis> <literal><ulink
+ url="../user-manual/actions-file.html#BLOCK">block</ulink></literal> action.
+</para>
+<para>
+ If you want to see nothing, then change the <ulink
+ url="../user-manual/actions-file.html#SET-IMAGE-BLOCKER"><literal>set-image-blocker</literal>
+ action</ulink> to <quote>blank</quote>. This can be done by editing the 
+ <filename>default.action</filename> file, or trough the <ulink
+ url="http://config.privoxy.org/show-status">web-based actions file editor</ulink>.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="whyseeum">Why would anybody want to see a checkerboard pattern?</title>
+<para>
+ Remember that <link linkend="whatsanad">telling which image is an ad and which
+ isn't</link>, is mostly guesswork. While we hope that the standard configuration
+ is rather smart, it can and will make errors. The checkerboard image is visually
+ decent, but it shows you that and where images were blocked, which can be very
+ helpful in case some navigation aid or otherwise innocent image was
+ erraneously blocked. Some people might also enjoy seeing how many banners
+ they <emphasis>don't</emphasis> have to see..
+</para>
+
+</sect2>
+
+<!-- This has changed with the adaptive "blocked" page
+
+<sect2 renderas="sect3">
+<title id="blockedisugly">I see large red banners on some pages that say 
+<quote>Blocked</quote>. Why and how do I get rid of this?</title>
+<para>
+ These are URLs that match something in one of 
+ <application>Privoxy's</application> block actions 
+ (<ulink
+ url="../user-manual/actions-file.html#BLOCK"><quote>+block</quote></ulink>).
+ It is meant to be a warning so that you know something has been blocked and
+ an easy way for you to see why. These are handled differently than what has
+ been defined explicitly as <quote>images</quote> (e.g. ads that are GIF image
+ files). Depending on the URL itself, it is sometimes hard for
+ <application>Privoxy</application> to really know whether there is indeed an
+ ad image there or not. And there are limitations as to what
+ <application>Privoxy</application> can do to <quote>fool</quote> the
+ browser.
+</para>
+
+<para>
+ For instance, if the ad is in a frame, then it is embedded in the separate
+ HTML page used for the frame. In this case, you cannot just substitute an
+ aribitrary image (like we would for a <quote>blank</quote> image), for an HTML
+ page. The browser is expecting an HTML page, and that is what it must have
+ for frames. Such situations can be a little trickier to deal with, and 
+ <application>Privoxy</application> may show the <quote>Blocked</quote> page,
+ despite your best efforts.
+</para>
+
+<para>
+ If you want these to be treated as if they were images, so that they can be
+ made invisible, you can try moving the offending URL from the
+ <quote>+block</quote> section to the <quote>+imageblock</quote> section of
+ your actions file. Just be forewarned, if any URL is made
+ <quote>invisible</quote>, you may not have any inkling that something has
+ been removed from that page, or why. If this approach does not work, then you are
+ probably dealing with a frame (or <quote>ilayer</quote>), and the only thing
+ that can go there is an HTML page of some sort.
+</para>
+<para>
+ To deal with this situation, you could modify the
+ <quote><filename>block</filename></quote> HTML template that is used by
+ <application>Privoxy</application> to display this, and make it something
+ more to your liking. Currently, there is no configuration option for this.
+ You will have to modify, or create your own page, and use this to replace
+ <filename>templates/blocked</filename>, which is what
+ <application>Privoxy</application> uses to display the <quote>Blocked</quote>
+ page.
+</para>
+<para>
+ Another way to deal with this is find why and where
+ <application>Privoxy</application> is blocking the frame, and 
+ diable this. Then let the <quote>+set-image-blocker</quote> action 
+ handle the ad that is embedded in the frame's HTML page. 
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="alliseeisred">
+<title>I cannot see all of the <quote>Blocked</quote> page banner. Help.</title>
+<para>
+ There is not enough available space to fit the entire Blocked page. Try right
+ clicking on the visible portion, and select <quote>Show Frame</quote>,
+ or equivalent. This will usually allow you to see the entire Privoxy
+ <quote>Blocked</quote> page, and from there you can see just what is being
+ blocked, and why.
+</para>
+<para>
+ As of Privoxy 2.9.14, the Blocked banner page is re-sizeable, and tries
+ to adjust to the allotted space. There may be occassions where there 
+ just isn't enough room to display much of anything useful though. 
+
+</para>
+</sect2>
+
+-->
+
+<sect2 renderas="sect3">
+<title id="blockedbytext">I see some images being replaced by a text
+instead of the checkerboard image. Why and how do I get rid of this?</title>
+<para>
+ This happens when the banners are not embedded in the HTML code of the
+ page itself, but in separate HTML (sub)documents that are loaded into (i)frames
+ or (i)layers, and these external HTML documents are blocked. Being non-images
+ they get replaced by a substitute HTML page rather than a substitute image,
+ which wouldn't work out technically, since the browser expects and accepts
+ only HTML when it has requested an HTML document. 
+</para>
+<para>
+ The substitute page adapts to the available space and shows itself as a
+ miniature two-liner if loaded into small frames, or full-blown with a
+ large red "BLOCKED" banner if space allows.
+</para>
+<para>
+ If you prefer the banners to be blocked by images, you must see to it that
+ the HTML documents in which they are embedded are not blocked. Clicking
+ the <quote>See why</quote> link offered in the substitute page will show
+ you which rule blocked the page. After changing the rule and un-blocking
+ the HTML documents, the browser will try to load the actual banner images
+ and the usual image blocking will (hopefully!) kick in.
+</para>
+</sect2>
+
+
+<sect2 renderas="sect3" id="srvany">
+<title>Can <application>Privoxy</application> run as a service 
+on Win2K/NT?</title>
+<para>
+ Yes, it can run as a system service using <command>srvany.exe</command>.
+ The only catch is that this will effectively disable the
+ <application>Privoxy</application> icon (and its menu!) in the taskbar. You can have 
+ one or the other, but not both at this time :( 
+</para>
+<para>
+ There is a pending feature request for this functionality. See the discussion
+ at <ulink
+ url="http://sourceforge.net/tracker/?func=detail&#38;atid=361118&#38;aid=485617&#38;group_id=11118">http://sourceforge.net/tracker/?func=detail&#38;atid=361118&#38;aid=485617&#38;group_id=11118</ulink>, 
+ for details, and a sample configuration.
+
+</para>
+</sect2>
+
+
+<sect2 renderas="sect3" id="otherproxy">
+<title>How can I make <application>Privoxy</application> work with other 
+proxies like <application>Squid</application>?</title>
+<para>
+ This can be done and is often useful to combine the benefits of
+ <application>Privoxy</application> with those of a caching proxy.
+ See the <ulink
+ url="../user-manual/config.html#FORWARDING">forwarding chapter</ulink>
+ in the <ulink url="../user-manual/index.html">user manual</ulink> which
+ describes how to do this.
+</para>
+</sect2>
+
+<sect2 renderas="sect3" id="transparent">
+<title>Can <application>Privoxy</application> run as a <quote>transparent
+</quote> proxy?</title>
+<para>
+ No, <application>Privoxy</application> currently does not have this ability, 
+ though it is planned for a future release. Transparent proxies require 
+ special handling of the request headers beyond what
+ <application>Privoxy</application> is now capable of.
+</para>
+
+<para>
+ Chaining <application>Privoxy</application> behind another proxy that has 
+ this ability should work though. 
+ See the <ulink
+ url="../user-manual/config.html#FORWARDING">forwarding chapter</ulink>
+ in the <ulink url="../user-manual/index.html">user manual</ulink>. As
+ a transparent proxy to be used for chaining we recommend Transproxy
+ (<ulink url="http://www.transproxy.nlc.net.au/">http://www.transproxy.nlc.net.au/</ulink>).
+</para>
+
+</sect2>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1 id="misc"><title>Miscellaneous</title>
+
+<sect2 renderas="sect3">
+<title id="slowsme">How much does <application>Privoxy</application> slow my browsing down? This 
+has to add extra time to browsing.</title>
+<para>
+ It should not slow you down any in real terms, and may actually help 
+ speed things up since ads, banners and other junk are not being displayed.
+ The actual processing time required by <application>Privoxy</application> 
+ itself for each page, is relatively small in the overall scheme of things,
+ and happens very quickly. This is typically more than offset by time saved
+ not downloading and rendering ad images.
+</para>
+
+<para>
+ <quote>Filtering</quote> content via the <literal><ulink
+ url="../user-manual/actions-file.html#FILTER">filter</ulink></literal> or
+ <literal><ulink
+ url="../user-manual/actions-file.html#DEANIMATE-GIFS">deanimate-gifs</ulink></literal>
+ actions may cause a perceived slowdown, since the entire document needs to be buffered
+ before displaying. See below.
+</para>
+
+</sect2>
+
+
+<sect2 renderas="sect3" id="loadingtimes"><title>I noticed considerable
+delays in page requests compared to the old Junkbuster. What's wrong?</title>
+<para>
+ If you use any <literal><ulink
+ url="../user-manual/actions-file.html#FILTER">filter</ulink></literal> action,
+ such as filtering banners by size, web-bugs etc, or the <literal><ulink
+ url="../user-manual/actions-file.html#DEANIMATE-GIFS">deanimate-gifs</ulink></literal>
+ action, the entire document must be loaded into memory in order for the filtering 
+ mechanism to work, and nothing is sent to the browser during this time.
+</para>
+<para>
+ The loading time does not really change in real numbers, but the feeling is
+ different, because most browsers are able to start rendering incomplete
+ content, giving the user a feeling of "it works". This effect is especially
+ noticeable on slow dialup connections.
+ </para>
+</sect2>
+
+
+<sect2 renderas="sect3" id="configurl"><title>What are "http://config.privoxy.org/" and
+"http://p.p/"?</title>
+<para>
+ <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink> is the
+ address of <application>Privoxy</application>'s built-in user interface, and 
+ <ulink url="http://p.p/">http://p.p/</ulink> is a shortcut for it.
+</para>
+<para>
+ Since <application>Privoxy</application> sits between your web browser and the Internet, 
+ it can simply intercept requests for these addresses and answer them with its built-in
+ <quote>web server</quote>.
+</para>
+<para>
+ This also makes for a good test for your browser configuration: If entering the
+ URL <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>
+ takes you to a page saying <quote>This is Privoxy..</quote>, everything is OK.
+ If you get a page saying <quote>Privoxy is not working</quote> instead, then
+ your browser didn't use <application>Privoxy</application> for the request,
+ hence it could not be intercepted, and you have accessed the <emphasis>real</emphasis>
+ web site at config.privoxy.org.
+</para>
+<para>
+ With recent versions of <application>Privoxy</application> (version 2.9.x and
+ later), the user interface features information on the run time status, the
+ configuration, and even a built-in editor for the <ulink
+ url="../user-manual/actions-file.html">actions files</ulink>.
+</para>
+
+<para>
+ Note that the built-in URLs from earlier versions of <application>Junkbuster</application>
+ / <application>Privoxy</application>, http://example.com/show-proxy-args and http://i.j.b/,
+ are no longer supported. If you still use such an old version, you should really consider
+ upgrading to &p-version;.
+</para>
+</sect2>
+
+<!--
+FIXME: commented out until we have data. HB 03/18/02.
+
+<sect2 renderas="sect3" id="badfiledesc"><title>I get the message 'Bad File Descriptor', why?</title>
+<para>
+   Fill me.
+</para>
+</sect2>
+
+-->
+
+<sect2 renderas="sect3" id="blocklist"><title>Do you still maintain the blocklists?</title>
+ <para>
+  No. The patterns for blocking now reside (among other things) in the <ulink
+  url="../user-manual/actions-file.html">actions files</ulink>, which are 
+  actively maintained instead. See next question ...
+</para>
+</sect2>
+
+<sect2 renderas="sect3" id="newads"><title>How can I submit new ads?</title>
+<para>
+Yes, absolutely! Please see the <link linkend="contact">Contact section</link> for
+how to do that. Please note that you (technically) need the latest
+<application>Privoxy</application> version for this to work.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="ip"><title>How can I hide my IP address?</title>
+<para>
+ If you run both the browser and the proxy locally, you cannot hide your IP
+ address with <application>Privoxy</application> or any other software. The
+ server needs to know your IP address to send the answers back to you. 
+</para>
+<para>
+ Fortunately there are many publicly usable anonymous proxies out there, which
+ solve the problem by providing a further level of indirection between you and
+ the web server, shared by many people, and thus letting your requests "drown"
+ in white noise of unrelated requests as far as user tracking is concerned.
+</para>
+<para>
+ Most of them will, however, log your IP address and make it available to the
+ authorities in case you abuse that anonymity for criminal purposes. In fact
+ you can't even rule out that some of them only exist to *collect* information
+ on (those suspicious) people with a more than average preference for privacy.
+</para>
+<para>
+ You can find a list of anonymous public proxies at <ulink
+ url="http://www.multiproxy.org/anon_list.htm">multiproxy.org</ulink> and many
+ more through Google. A particularly interesting project is the JAP service
+ offered by the Technical University of Dresden (<ulink
+ url="http://anon.inf.tu-dresden.de/index_en.html">http://anon.inf.tu-dresden.de/index_en.html</ulink>.
+</para>
+<para>
+ There is, however, even in the single-machine case the possibility to make the
+ server believe that your machine is in fact a shared proxy serving a whole big
+ LAN, and we are looking into that.
+</para>
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="anonforsure">Can <application>Privoxy</application> guarantee I am anonymous?</title>
+<para>
+ No. Your chances of remaining anonymous are greatly improved, but unless you
+ are an expert on Internet security it would be safest to assume that
+ everything you do on the Web can be traced back to you.
+</para>
+<para>
+ <application>Privoxy</application> can remove various information about you,
+ and allows <emphasis>you</emphasis> more freedom  to decide which sites 
+ you can trust, and what details you want to reveal. But it's still possible
+ that web sites can find out who you are. Here's one way this can happen.
+</para>
+<para>
+ A few browsers disclose the user's email address in certain situations, such
+ as when transferring a file by FTP. <application>Privoxy</application>
+ does not filter FTP. If you need this feature, or are concerned about the
+ mail handler of your browser disclosing your email address, you might
+ consider products such as <application>NSClean</application>.
+</para>
+<para>
+ Browsers available only as binaries could use non-standard headers to give
+ out any information they can have access to: see the manufacturer's license
+ agreement. It's impossible to anticipate and prevent every breach of privacy
+ that might occur. The professionally paranoid prefer browsers available as
+ source code, because anticipating their behavior is easier. Trust the source,
+ Luke!
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="sitebreak">Might some things break because header information or
+content is being altered?</title>
+
+<para>
+ Definitely. More and more sites use HTTP header content to decide what to
+ display and how to display it. There is many ways that this can be handled, 
+ so having hard and fast rules, is tricky.
+</para>
+
+<para>
+ <quote>User-Agent</quote> in particular is often used in this way to identify
+ the browser, and adjust content accordingly. Changing this now (at least not
+ further than removing the OS information) is not recommended, since so many
+ sites do look for it. You may get undesirable results by changing this.
+</para>
+
+<para>
+ For instance, different browsers use different encodings of Russian and Czech
+ characters, certain web servers convert pages on-the-fly according to the
+ User Agent header. Giving a <quote>User Agent</quote> with the wrong
+ operating system or browser manufacturer causes some sites in these languages
+ to be garbled; Surfers to Eastern European sites should change it to
+ something closer. And then some page access counters work by looking at the
+ <quote>Referer</quote> header; they may fail or break if unavailable. The
+ weather maps of Intellicast have been blocked by their server when no
+ <quote>Referer</quote> or cookie is provided, is another example. (But you
+ can forge both headers without giving information away). There are
+ many other ways things can go wrong when trying to fool a web server.
+</para>
+
+<para>
+ Similar thoughts apply to modifying JavaScript, and, to a lesser degree,
+ HTML elements.
+</para>
+
+<para>
+ If you have problems with a site, you will have to adjust your configuration 
+ accordingly. Cookies are probably the most likely adjustment that may 
+ be required, but by no means the only one.
+</para>
+
+</sect2>
+
+
+<sect2 renderas="sect3">
+<title id="caching">Can <application>Privoxy</application> act as a <quote>caching</quote> proxy to 
+speed up web browsing?</title>
+<para>
+ No, it does not have this ability at all. You want something like 
+ <ulink url="http://www.squid-cache.org/">Squid</ulink> for this. And, yes, 
+ before you ask, <application>Privoxy</application> can co-exist 
+ with other kinds of proxies like <application>Squid</application>.
+ See the <ulink url="../user-manual/config.html#FORWARDING">forwarding
+ chapter</ulink> in the <ulink url="../user-manual/index.html">user
+ manual</ulink> for details.
+</para>
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="firewall">What about as a firewall? Can <application>Privoxy</application> protect me?</title>
+<para>
+ Not in the way you mean, or in the way a true firewall can. 
+ <application>Privoxy</application> can help protect your privacy, but not
+ protect you from intrusion attempts. It is, of course, perfectly possible
+ and recommended to use <emphasis>both</emphasis>.
+</para>
+</sect2>
+
+<!-- No longer needed
+<sect2 renderas="sect3">
+<title id="logo">The <application>Privoxy</application> logo that replaces ads is very blocky 
+and ugly looking. Can't a better font be used?</title>
+
+<para>
+ This is not a font problem. The logo is an image that is created by 
+ <application>Privoxy</application> on the fly. So as to not waste 
+ memory, the image is rather small. The blockiness comes when the 
+ image is scaled to fill a largish area. There is not much to be done 
+ about this, other than to use one of the other
+ <quote>imageblock</quote> directives: <emphasis>pattern</emphasis>, 
+ <emphasis>blank</emphasis>, or a URL of your choosing.
+</para>
+<para>
+Given the above problem, we have decided to remove the logo option entirely 
+[as of v2.9.13].
+</para>
+</sect2>
+-->
+
+<sect2 renderas="sect3">
+<title id="wasted">I have large empty spaces / a checkerboard pattern now where
+ads used to be. Why?</title>
+<para>
+ It would be technically possible eliminate the banners in a way that frees
+ their screen estate in many cases, by doing all banner blocking with filters,
+ i.e. eliminating the whole image references from the HTML pages instead
+ of letting them stay in, and blocking the resulting requests for the
+ banners themselves.
+</para>
+<para>
+ But this would consume considerable CPU resources, would likely destroy
+ the layout of many web pages which rely on the banners consuming a certain
+ amount of screen space, and would fail in other cases, where the screen space
+ is reserved e.g. by tables anyway. Also, making the banners disappear without
+ a visual trace complicates troubleshooting.
+</para>
+<para>
+ So we won't support this in the default configuration, but you can of course
+ define appropriate filters yourself.
+</para>
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="ssl">How can <application>Privoxy</application> filter Secure (HTTPS) URLs?</title>
+<para>
+ Since secure HTTP connections are encrypted SSL sessions between your browser
+ and the secure site, and are meant to be reliably <emphasis>secure</emphasis>,
+ there is little that <application>Privoxy</application> can do but hand the raw
+ gibberish data though from one end to the other unprocessed.
+</para>
+<para>
+ The only exception to this is blocking by host patterns, as the client needs
+ to tell <application>Privoxy</application> the name of the remote server,
+ so that <application>Privoxy</application> can establish the connection.
+ If that name matches a host-only pattern, the connection will be blocked.
+</para>
+<para>
+ As far as ad blocking is concerned, this is less of a restriction than it may
+ seem, since ad sources are often identifiable by the host name, and often
+ the banners to be placed in an encrypted page come unencrypted nonetheless
+ for efficiency reasons, which exposes them to the full power of 
+ <application>Privoxy</application>'s ad blocking.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="secure"><application>Privoxy</application> runs as a <quote>server</quote>. How 
+secure is it? Do I need to take any special precautions?</title>
+<para>
+ There are no known exploits that might affect
+ <application>Privoxy</application>. On Unix-like systems, 
+ <application>Privoxy</application> can run as a non-privileged 
+ user, which is how we recommend it be run. Also, by default 
+ <application>Privoxy</application> only listens to requests 
+ from <quote>localhost</quote> only. The server aspect of
+ <application>Privoxy</application> is not itself directly exposed to the
+ Internet in this configuration. If you want to have
+ <application>Privoxy</application> serve as a LAN proxy, this will have to
+ be opened up to allow for LAN requests. In this case, we'd recommend
+ you specify only the LAN gateway address, e.g. 192.168.1.1, in the main 
+ <application>Privoxy</application> configuration file and check all <ulink
+ url="../user-manual/config.html#ACCESS-CONTROL">access control and security
+ options</ulink>. All LAN hosts can then use this as their proxy address
+ in the browser proxy configuration, but <application>Privoxy</application>
+ will not listen on any external interfaces. ACLs can be defined in addition,
+ and using a firewall is always good too. Better safe than sorry.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3" id="turnoff">
+<title>How can I temporarily disable <application>Privoxy</application>?</title>
+<para>
+ The easiest way is to access <application>Privoxy</application> with your 
+ browser by using the remote toggle URL: <ulink
+ url="http://config.privoxy.org/toggle">http://config.privoxy.org/toggle</ulink>.
+</para>
+</sect2>
+
+<sect2 renderas="sect3" id="seealso">
+<title>Where can I find more information about <application>Privoxy</application>
+and related issues?</title>
+<!-- Include seealso.sgml boilerplate: -->
+ &seealso;
+<!-- end boilerplate -->
+
+<!--
+<para>
+ Please see the 
+ <ulink url="../user-manual/seealso.html">user-manual</ulink> for 
+ others references.
+</para>
+-->
+</sect2>
+
+</sect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1 id="trouble">
+<title>Troubleshooting</title>
+
+<sect2 renderas="sect3">
+<title id="refused">I just upgraded and am getting <quote>connection refused</quote>
+with every web page?</title>
+<para>
+ Either <application>Privoxy</application> is not running, or your 
+ browser is configured for a different port than what
+ <application>Privoxy</application> is using.
+</para>
+
+<para>
+ The old <application>Privoxy</application> (and also
+ <application>Junkbuster</application>) used port 8000 by 
+ default. This has been changed to port 8118 now, due to a conflict 
+ with NAS (Network Audio Service), which uses port 8000. If you haven't, 
+ you need to change your browser to the new port number, or alternately 
+ change the <ulink
+ url="../user-manual/config.html#LISTEN-ADDRESS"><literal>listen-address</literal>
+ option</ulink> in <application>Privoxy's</application> <ulink
+ url="../user-manual/config.html">main configuration file</ulink>.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="flushit">I just added a new rule, but the steenkin ad is 
+still getting through. How?</title>
+<para>
+ If the ad had been displayed before you added its URL, it will probably be
+ held in the browser's cache for some time, so it will be displayed without
+ the need for any request to the server, and <application>Privoxy</application>
+ will not be in the picture. The best thing to do is try flushing the browser's
+ caches. And then try again.
+</para>
+
+<para>
+ If this doesn't help, you probably have an error in the rule you
+ applied. Try pasting the full URL of the offending ad into <ulink
+ url="http://config.privoxy.org/show-url-info">http://config.privoxy.org/show-url-info</ulink>
+ and see if it really matches your new rule.
+</para>
+
+</sect2>
+
+<sect2 renderas="sect3">
+<title id="badsite">One of my favorite sites does not work with <application>Privoxy</application>.
+What can I do?</title>
+
+<para>
+ First verify that it is indeed a <application>Privoxy</application> problem, 
+ by toggling off <application>Privoxy</application> through <ulink
+ url="http://config.privoxy.org/toggle">http://config.privoxy.org/toggle</ulink>,
+ and then shift-reloading the problem page (i.e. holding down the shift key
+ while clicking reload. Alternatively, flush your browser's disk and memory
+ caches).
+</para>
+
+<para>
+ If still a problem, go to <ulink
+ url="http://config.privoxy.org/show-url-info">http://config.privoxy.org/show-url-info</ulink>
+ and paste the full URL of the page in question into the prompt. See which actions
+ are being applied to the URL, and which matches in which actions files are
+ responsible for that. Now, armed with this information, go to <ulink
+ url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+ and select the appropriate actions files for editing.
+</para>
+<para>
+ You can now either look for a section which disables the actions that
+ you suspect to cause the problem and add a pattern for your site there,
+ or make up a completely new section for your site. In any case, the recommended
+ way is to disable only the prime suspect, reload the problem page, and only
+ if the problem persists, disable more and more actions until you have
+ identified the culprit. You may or may not want to turn the other actions
+ on again. Remember to flush your browser's caches in between any such changes!
+</para>
+<para>
+ Alternately, if you are comfortable with a text editor, you can accomplish 
+ the same thing by editing the appropriate actions file. Probably the easiest 
+ way to deal with such problems when editing by hand is to add your
+ site to a <literal>{ fragile }</literal> section in <filename>user.action</filename>,
+ which is an alias that turns off most <quote>dangerous</quote>
+ actions, but is also likely to turn off more actions then needed, and thus lower
+ your privacy and protection more than necessary, 
+</para>
+<para>
+ Troubleshooting actions is discussed in more detail in the <ulink
+ url="../user-manual/appendix.html#ACTIONSANAT">user-manual appendix</ulink>.
+ There is also an <ulink
+ url="../user-manual/actions-file.html#ACT-EXAMPLES">actions tutorial</ulink>.
+</para>
+
+</sect2>
+
+</sect1>
+<!--
+</sect1>
+-->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<!--
+FIXME: Commented out until we have something to put here. HB 03/18/02.
+<sect1 id="knownissues"><title>Known Issues</title>
+<para>
+   Fill me.
+</para>
+</sect1>
+-->
+
+  <!--   ~~~~~       New section      ~~~~~     -->
+  <sect1 id="contact"><title>Contacting the developers, Bug Reporting and Feature Requests</title>
+<!-- Include contacting.sgml  -->
+ &contacting;
+<!-- end contacting -->
+  </sect1>
+  
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="copyright"><title>Privoxy Copyright, License and History</title>
+
+ <!-- Include copyright.sgml -->
+  &copyright;
+ <!-- end -->
+  
+  <para>
+   Portions of this document are <quote>borrowed</quote> from the original
+   <application>Junkbuster</application> (tm) FAQ, and modified as 
+   appropriate for <application>Privoxy</application>.
+  </para>
+
+ <!--   ~~~~~       New section      ~~~~~     -->
+ <sect2><title>License</title>
+ <!-- Include copyright.sgml: -->
+  &license;
+ <!-- end copyright -->
+ </sect2>
+ <!--  ~  End section  ~  -->
+
+ <!--   ~~~~~       New section      ~~~~~     -->
+ <sect2><title>History</title>
+ <!-- Include history.sgml -->
+  &history;
+ <!-- end -->
+ </sect2>
+
+ </sect1>
+ <!--  ~  End section  ~  -->
+  
+<!--   ~~~~~       New section      ~~~~~     -->
+<!--
+<sect1 id="seealso"><title>See also</title>
+-->
+<!-- Include seealso.sgml -->
+<!--
+ &see;
+-->
+<!-- end  -->
+<!--
+</sect1>
+-->
+
+<!-- hhmts end -->
+ <!--
+ Tue 09/11/01 06:38:14 PM EST: Test SGML doc by Hal Burgiss.
+ Last modified: Mon Sep 10 19:22:09 CEST 2001
+ This program is free software; you can redistribute it 
+ and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A
+ PARTICULAR PURPOSE.  See the GNU General Public
+ License for more details.
+
+ The GNU General Public License should be included with
+ this file.  If not, you can view it at
+ http://www.gnu.org/copyleft/gpl.html
+ or write to the Free Software Foundation, Inc., 59
+ Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+$Log: faq.sgml,v $
+Revision 1.60  2002/05/22 17:17:48  oes
+Proofread & added more links into u-m
+
+Revision 1.59  2002/05/15 04:03:30  hal9
+Fix ulink -> link markup.
+
+Revision 1.58  2002/05/10 01:48:20  hal9
+This is mostly proposed copyright/licensing additions and changes. Docs
+are still GPL, but licensing and copyright are more visible. Also, copyright
+changed in doc header comments (eliminate references to JB except FAQ).
+
+Revision 1.57  2002/05/05 20:26:02  hal9
+Sorting out license vs copyright in these docs.
+
+Revision 1.56  2002/05/04 08:44:44  swa
+bumped version
+
+Revision 1.55  2002/05/04 00:41:56  hal9
+-Remove TOC/first page kludge in favor of proper handling via dsl file.
+
+Revision 1.54  2002/05/03 05:06:44  hal9
+Add brief Q/A on transparent proxies.
+
+Revision 1.53  2002/05/03 01:34:52  hal9
+Fix section numbering for new sections (due to TOC kludge).
+
+Revision 1.52  2002/04/29 03:08:43  hal9
+-Added new Q/A on new actions file set up (pointer to u-m)
+-Fixed a few broken links and converted old actions as a result of
+ recent changes.
+
+Revision 1.51  2002/04/26 17:24:31  swa
+bookmarks cleaned, changed structure of user manual, screen and programlisting cleanups, and numerous other changes that I forgot
+
+Revision 1.50  2002/04/26 05:25:23  hal9
+Mass commit to catch a few scattered fixes.
+
+Revision 1.49  2002/04/12 10:10:18  swa
+version update
+
+Revision 1.48  2002/04/10 18:45:15  swa
+generated
+
+Revision 1.47  2002/04/10 04:05:32  hal9
+More on BML, etc.
+
+Revision 1.45  2002/04/08 22:59:26  hal9
+Version update. Spell chkconfig correctly :)
+
+Revision 1.44  2002/04/07 21:24:29  hal9
+Touch up on name change.
+
+Revision 1.43  2002/04/04 21:59:53  hal9
+Added NT/W2K service/icon situation.
+
+Revision 1.42  2002/04/04 18:46:47  swa
+consistent look. reuse of copyright, history et. al.
+
+Revision 1.41  2002/04/04 06:48:37  hal9
+Structural changes to allow for conditional inclusion/exclusion of content
+based on entity toggles, e.g. 'entity % p-not-stable  "INCLUDE"'. And
+definition of internal entities, e.g. 'entity p-version "2.9.13"' that will
+eventually be set by Makefile.
+More boilerplate text for use across multiple docs.
+
+Revision 1.40  2002/04/03 04:22:03  hal9
+Fixed several typos.
+
+Revision 1.39  2002/04/03 03:53:03  hal9
+Revert some changes, and then make some news, to layout, and appearance.
+
+Revision 1.38  2002/04/02 03:49:10  hal9
+Major changes to doc structure and layout. Sections are not automatically
+numbered now. TOC is on page by itself.
+
+Revision 1.37  2002/04/01 16:24:07  hal9
+-Rework of supported Q/A.
+-Set up entities to include boilerplate text.
+
+Revision 1.36  2002/03/31 23:18:47  hal9
+More on dealing with BLOCKED.
+
+Revision 1.35  2002/03/30 04:14:19  hal9
+Fix privoxy.org/config links.
+
+Revision 1.34  2002/03/29 04:35:56  hal9
+Touch ups.
+
+Revision 1.33  2002/03/29 01:31:48  hal9
+Several new Q/A's and other touch ups.
+
+Revision 1.32  2002/03/27 00:57:03  hal9
+Touch ups for name change.
+
+Revision 1.31  2002/03/26 22:29:55  swa
+we have a new homepage!
+
+Revision 1.30  2002/03/25 16:39:22  hal9
+A few new sections. Made all links relative to user-manual.
+
+Revision 1.29  2002/03/25 05:23:57  hal9
+Moved section, and touch ups.
+
+Revision 1.28  2002/03/25 04:27:33  hal9
+New section related to name change.
+
+Revision 1.25  2002/03/24 16:08:08  swa
+we are too lazy to make a block-built
+privoxy logo. hence removed the option.
+
+Revision 1.24  2002/03/24 15:46:20  swa
+name change related issue.
+
+Revision 1.23  2002/03/24 12:33:01  swa
+more additions.
+
+Revision 1.22  2002/03/24 11:51:00  swa
+name change. changed filenames.
+
+Revision 1.21  2002/03/24 11:01:06  swa
+name change
+
+Revision 1.20  2002/03/23 15:13:11  swa
+renamed every reference to the old name with foobar.
+fixed "application foobar application" tag, fixed
+"the foobar" with "foobar". left junkbustser in cvs
+comments and remarks to history untouched.
+
+Revision 1.19  2002/03/21 17:01:54  hal9
+Some touch ups.
+
+Revision 1.18  2002/03/18 16:40:31  hal9
+More additions.
+
+Revision 1.17  2002/03/18 03:53:53  hal9
+Some new additions.
+
+Revision 1.16  2002/03/17 21:32:56  hal9
+A few more additions.
+
+Revision 1.15  2002/03/17 07:25:59  hal9
+Correcting some of my typos, and some additions.
+
+Revision 1.14  2002/03/17 02:39:13  hal9
+A little more added ...
+
+Revision 1.13  2002/03/17 00:22:20  hal9
+Adding new stuff, and trying to incorporate stuff from old faq.
+
+Revision 1.12  2002/03/11 20:13:21  swa
+typo
+
+Revision 1.11  2002/03/11 18:42:27  swa
+new section
+
+Revision 1.10  2002/03/11 13:13:27  swa
+correct feedback channels
+
+Revision 1.9  2002/03/10 23:34:04  swa
+more info on not hiding ip address
+
+Revision 1.8  2002/03/09 15:55:48  swa
+added default config section
+
+Revision 1.7  2002/03/07 18:16:55  swa
+looks better
+
+Revision 1.6  2002/03/07 13:16:31  oes
+Committing changes by Stefan
+
+Revision 1.5  2002/03/02 15:50:04  swa
+2.9.11 version. more input for docs.
+
+Revision 1.4  2002/02/24 14:34:24  jongfoster
+Formatting changes.  Now changing the doctype to DocBook XML 4.1
+will work - no other changes are needed.
+
+Revision 1.3  2001/09/23 10:13:48  swa
+upload process established. run make webserver and
+the documentation is moved to the webserver. documents
+are now linked correctly.
+
+Revision 1.2  2001/09/13 15:20:17  swa
+merged standards into developer manual
+
+Revision 1.1  2001/09/12 15:36:41  swa
+source files for junkbuster documentation
+
+Revision 1.3  2001/09/10 17:43:59  swa
+first proposal of a structure.
+
+Revision 1.2  2001/06/13 14:28:31  swa
+docs should have an author.
+
+Revision 1.1  2001/06/13 14:20:37  swa
+first import of project's documentation for the webserver.
+
+-->
+
+</article>
diff --git a/doc/source/history.sgml b/doc/source/history.sgml
new file mode 100644 (file)
index 0000000..057da5e
--- /dev/null
@@ -0,0 +1,72 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/history.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: history.sgml,v 1.5 2002/05/10 01:48:20 hal9 Exp $
+
+  Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+  See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  user-manual
+  developer-manual
+  faq
+  webserver/index.sgml
+
+-->
+
+<para>
+ In the beginning, there was the
+ <ulink url="http://www.junkbusters.com/ijb.html"><application>Internet Junkbuster</application></ulink>, 
+ by Anonymous Coders and <ulink url="http://www.junkbusters.com/">Junkbusters
+ Corporation</ulink>. It saved many users a lot of pain in the early days of
+ web advertising and user tracking.
+</para>
+
+<para>
+ But the web, its protocols and standards, and with it, the techniques for
+ forcing  users to consume ads, give up autonomy over their browsing, and
+ for spying on them, kept evolving. Unfortunately, the <application>Internet
+ Junkbuster</application> did not. Version 2.0.2, published in 1998, was 
+ (and is) the last official
+ <ulink url="http://www.junkbusters.com/ijbdist.html#release">release</ulink>
+ available from <ulink url="http://www.junkbusters.com">Junkbusters Corporation</ulink>.
+ Fortunately, it had been released under the GNU
+ <ulink url="http://www.gnu.org/licenses/gpl.html"> GPL</ulink>, which allowed further
+ development by others.
+</para>
+
+<para>
+ So Stefan Waldherr started maintaining an
+ <ulink url="http://www.waldherr.org/junkbuster/">improved version of the
+ software</ulink>, to which eventually a number of people contributed patches.
+ It could already replace banners with a transparent image, and had a first
+ version of pop-up killing, but it was still very closely based on the
+ original, with all its limitations, such as the lack of HTTP/1.1 support,
+ flexible per-site configuration, or content modification. The last release
+ from this effort was version 2.0.2-10, published in 2000.
+</para>
+
+<para>
+ Then, some
+ <ulink url="http://www.privoxy.org/user-manual/copyright.html#AUTHORS">developers</ulink>
+ picked up the thread, and started turning the software inside out, upside down,
+ and then reassembled it, adding many
+ <ulink url="http://www.privoxy.org/user-manual/introduction.html#FEATURES">new
+ features</ulink> along the way.
+</para>
+
+<para>
+ The result of this is <application>Privoxy</application>, whose first
+ stable release, 3.0, is due in May 2002.
+</para>
+
diff --git a/doc/source/ldp.dsl.in b/doc/source/ldp.dsl.in
new file mode 100644 (file)
index 0000000..67343f8
--- /dev/null
@@ -0,0 +1,416 @@
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [\r
+<!ENTITY % html "IGNORE">\r
+<![%html;[\r
+<!ENTITY % print "IGNORE">\r
+<!ENTITY docbook.dsl SYSTEM "@DKPREFIX@/html/docbook.dsl" CDATA dsssl>\r
+]]>\r
+<!ENTITY % print "INCLUDE">\r
+<![%print;[\r
+<!ENTITY docbook.dsl SYSTEM "@DKPREFIX@/print/docbook.dsl" CDATA dsssl>\r
+]]>\r
+]>\r
+\r
+<!--\r
+\r
+;; borrowed from the LDP stylesheet, with modifications, HB.\r
+;; Added support for css 03/20/02, and other mods.\r
+\r
+-->\r
+\r
+<style-sheet>\r
+\r
+<style-specification id="print" use="docbook">\r
+<style-specification-body> \r
+\r
+;; ==============================\r
+;; customize the print stylesheet\r
+;; ==============================\r
+;;\r
+;; see http://docbook.sourceforge.net/projects/dsssl/doc/print.html\r
+;;\r
+\r
+(define %indent-screen-lines%\r
+  ;; Indent lines in a 'Screen'?\r
+  #t)\r
+\r
+(define %callout-fancy-bug% \r
+  ;; Use fancy callout bugs?\r
+  #t)\r
+\r
+(define %chap-app-running-heads% \r
+  ;; Generate running headers and footers on chapter-level elements?\r
+  #t)\r
+\r
+(define %chap-app-running-head-autolabel% \r
+  ;; Put chapter labels in running heads?\r
+  #t)\r
+\r
+;; this is necessary because right now jadetex does not understand\r
+;; symbolic entities, whereas things work well with numeric entities.\r
+(declare-characteristic preserve-sdata?\r
+  "UNREGISTERED::James Clark//Characteristic::preserve-sdata?"\r
+  #f)\r
+\r
+;; put the legal notice in a separate file\r
+(define %generate-legalnotice-link%\r
+  #t)\r
+\r
+;; use graphics in admonitions, and have their path be "stylesheet-images"\r
+;; NO: they do not yet look very good\r
+(define %admon-graphics-path%\r
+  "./stylesheet-images/")\r
+\r
+(define %admon-graphics%\r
+  #f)\r
+\r
+(define %funcsynopsis-decoration%\r
+  ;; make funcsynopsis look pretty\r
+  #t)\r
+\r
+;;(define %shade-verbatim%\r
+;;  #t)\r
+\r
+(define %section-autolabel% #t)\r
+  ;; For enumerated sections (1.1, 1.1.1, 1.2, etc.)\r
+  \r
+;; HB changed TOC depth to 3 levels.\r
+(define (toc-depth nd)\r
+  3)\r
+\r
+;; HB added 03/20/02, see dbparam.dsl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
+\r
+(define %body-attr% \r
+  ;; REFENTRY body-attr\r
+  ;; PURP What attributes should be hung off of BODY?\r
+  ;; DESC\r
+  ;; A list of the the BODY attributes that should be generated.\r
+  ;; The format is a list of lists, each interior list contains the\r
+  ;; name and value of a BODY attribute.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  (list\r
+   (list "BGCOLOR" "#EEEEEE")\r
+   (list "TEXT" "#000000")\r
+   (list "LINK" "#0000FF")\r
+   (list "VLINK" "#840084")\r
+   (list "ALINK" "#0000FF")))\r
+\r
+(define %stylesheet%\r
+  ;; REFENTRY stylesheet\r
+  ;; PURP Name of the stylesheet to use\r
+  ;; DESC\r
+  ;; The name of the stylesheet to place in the HTML LINK TAG, or '#f' to\r
+  ;; suppress the stylesheet LINK.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  "../p_doc.css")\r
+\r
+(define %stylesheet-type%\r
+  ;; REFENTRY stylesheet-type\r
+  ;; PURP The type of the stylesheet to use\r
+  ;; DESC\r
+  ;; The type of the stylesheet to place in the HTML LINK TAG.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  "text/css")\r
+\r
+(define %css-liststyle-alist%\r
+  ;; REFENTRY css-liststyle-alist\r
+  ;; PURP Map DocBook OVERRIDE and MARK attributes to CSS\r
+  ;; DESC\r
+  ;; If '%css-decoration%' is turned on then the list-style-type property of\r
+  ;; list items will be set to reflect the list item style selected in the\r
+  ;; DocBook instance.  This associative list maps the style type names used\r
+  ;; in your instance to the appropriate CSS names.  If no mapping exists,\r
+  ;; the name from the instance will be used.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  '(("bullet" "disc")\r
+    ("box" "square")))\r
+\r
+(define %css-decoration%\r
+  ;; REFENTRY css-decoration\r
+  ;; PURP Enable CSS decoration of elements\r
+  ;; DESC\r
+  ;; If '%css-decoration%' is turned on then HTML elements produced by the\r
+  ;; stylesheet may be decorated with STYLE attributes.  For example, the\r
+  ;; LI tags produced for list items may include a fragment of CSS in the\r
+  ;; STYLE attribute which sets the CSS property "list-style-type".\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  #t)\r
+\r
+;; swa1\r
+\r
+(define %generate-part-toc%\r
+  #f)\r
+\r
+(define %generate-article-toc% \r
+  ;; Should a Table of Contents be produced for Articles?\r
+  ;; If true, a Table of Contents will be generated for each 'Article'.\r
+  #t)\r
+\r
+(define %generate-part-toc-on-titlepage%\r
+  ;; Should the Part TOC appear on the Part title page?\r
+  #f)\r
+\r
+;;Do you want a separate page for the title?\r
+(define %generate-article-titlepage-on-separate-page%\r
+ #t)\r
+\r
+;;Do you want the article toc on the titlepage or separate?\r
+(define %generate-article-toc-on-titlepage%\r
+ #f)\r
+\r
+;;Titlepage Separate?\r
+;; This is the one that makes TOC only on first page!! hal.\r
+(define (chunk-skip-first-element-list)\r
+ '())\r
+\r
+(define %body-start-indent%\r
+  ;; Default indent of body text\r
+  2pi)\r
+\r
+(define %para-indent-firstpara%\r
+  ;; First line start-indent for the first paragraph\r
+  0pt)\r
+\r
+;; swa2\r
+\r
+(define %para-indent%\r
+  ;; First line start-indent for paragraphs (other than the first)\r
+  0pt)\r
+\r
+(define %block-start-indent%\r
+  ;; Extra start-indent for block-elements\r
+  2pt)\r
+\r
+;;Define distance between paragraphs\r
+(define %para-sep% \r
+ (/ %bf-size% 2.0))\r
+\r
+;; with swa2 no effects\r
+\r
+;; swa3\r
+\r
+;;Define distance between block elements (figures, tables, etc.).\r
+(define %block-sep% \r
+ (* %para-sep% 1.0))\r
+;; (* %para-sep% 2.0))\r
+\r
+(define %hyphenation%\r
+  ;; Allow automatic hyphenation?\r
+  #t)\r
+\r
+(define %left-margin% 5pi)\r
+(define %right-margin% 5pi)\r
+(define %top-margin% 5pi)\r
+(define %bottom-margin% 5pi)\r
+(define %footer-margin% 2pi)\r
+(define %header-margin% 2pi)\r
+\r
+(define %line-spacing-factor% 1.3)\r
+  ;; Factor used to calculate leading\r
+  ;; The leading is calculated by multiplying the current font size by the \r
+  ;; '%line-spacing-factor%'. For example, if the font size is 10pt and\r
+  ;; the '%line-spacing-factor%' is 1.1, then the text will be\r
+  ;; printed "10-on-11".\r
+\r
+(define %head-before-factor% \r
+  ;; Factor used to calculate space above a title\r
+  ;; The space before a title is calculated by multiplying the font size\r
+  ;; used in the title by the '%head-before-factor%'.\r
+;;  0.75)\r
+  0.5)\r
+\r
+(define %head-after-factor% \r
+  ;; Factor used to calculate space below a title\r
+  ;; The space after a title is calculated by multiplying the font size used\r
+  ;; in the title by the '%head-after-factor%'.\r
+  0.5)\r
+\r
+(define %input-whitespace-treatment% 'collapse)\r
+\r
+(define ($generate-article-lot-list$)\r
+  ;; Which Lists of Titles should be produced for Articles?\r
+  (list ))\r
+\r
+\r
+</style-specification-body>\r
+</style-specification>\r
+\r
+\r
+<!--\r
+;; ===================================================\r
+;; customize the html stylesheet; borrowed from Cygnus\r
+;; at http://sourceware.cygnus.com/ (cygnus-both.dsl)\r
+;; ===================================================\r
+-->\r
+\r
+<style-specification id="html" use="docbook">\r
+<style-specification-body> \r
+\r
+;; this is necessary because right now jadetex does not understand\r
+;; symbolic entities, whereas things work well with numeric entities.\r
+(declare-characteristic preserve-sdata?\r
+  "UNREGISTERED::James Clark//Characteristic::preserve-sdata?"\r
+  #f)\r
+\r
+;; put the legal notice in a separate file\r
+(define %generate-legalnotice-link%\r
+  #t)\r
+\r
+;; use graphics in admonitions, and have their path be "stylesheet-images"\r
+;; NO: they do not yet look very good\r
+(define %admon-graphics-path%\r
+  "./stylesheet-images/")\r
+\r
+(define %admon-graphics%\r
+  #f)\r
+\r
+(define %funcsynopsis-decoration%\r
+  ;; make funcsynopsis look pretty\r
+  #t)\r
+\r
+(define %html-ext%\r
+  ".html")\r
+\r
+(define %generate-article-toc% \r
+  ;; Should a Table of Contents be produced for Articles?\r
+  ;; If true, a Table of Contents will be generated for each 'Article'.\r
+  #t)\r
+\r
+;; HB added next three statements 05/03/02.\r
+;;Do you want a separate page for the title?\r
+(define %generate-article-titlepage-on-separate-page%\r
+ #t)\r
+\r
+;;Do you want the article toc on the titlepage or separate?\r
+(define %generate-article-toc-on-titlepage%\r
+ #t)\r
+\r
+;;Titlepage Separate?\r
+;; This is the one that makes TOC only on first page!! hal.\r
+(define (chunk-skip-first-element-list)\r
+ '())\r
+\r
+(define %root-filename%\r
+  ;; The filename of the root HTML document (e.g, "index").\r
+  "index")\r
+\r
+(define %generate-part-toc%\r
+  #t)\r
+\r
+(define %shade-verbatim%\r
+  #t)\r
+\r
+(define %use-id-as-filename%\r
+  ;; Use ID attributes as name for component HTML files?\r
+  #t)\r
+\r
+(define %graphic-default-extension% \r
+  "gif")\r
+\r
+(define %section-autolabel% #t)\r
+  ;; For enumerated sections (1.1, 1.1.1, 1.2, etc.)\r
+  \r
+;; HB changed TOC depth to 3 levels.\r
+(define (toc-depth nd)\r
+  3)\r
+\r
+;; HB added 03/20/02, see dbparam.dsl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
+\r
+(define %body-attr% \r
+  ;; REFENTRY body-attr\r
+  ;; PURP What attributes should be hung off of BODY?\r
+  ;; DESC\r
+  ;; A list of the the BODY attributes that should be generated.\r
+  ;; The format is a list of lists, each interior list contains the\r
+  ;; name and value of a BODY attribute.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  (list\r
+   (list "BGCOLOR" "#EEEEEE")\r
+   (list "TEXT" "#000000")\r
+   (list "LINK" "#0000FF")\r
+   (list "VLINK" "#840084")\r
+   (list "ALINK" "#0000FF")))\r
+\r
+(define %stylesheet%\r
+  ;; REFENTRY stylesheet\r
+  ;; PURP Name of the stylesheet to use\r
+  ;; DESC\r
+  ;; The name of the stylesheet to place in the HTML LINK TAG, or '#f' to\r
+  ;; suppress the stylesheet LINK.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  "../p_doc.css")\r
+\r
+(define %stylesheet-type%\r
+  ;; REFENTRY stylesheet-type\r
+  ;; PURP The type of the stylesheet to use\r
+  ;; DESC\r
+  ;; The type of the stylesheet to place in the HTML LINK TAG.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  "text/css")\r
+\r
+(define %css-liststyle-alist%\r
+  ;; REFENTRY css-liststyle-alist\r
+  ;; PURP Map DocBook OVERRIDE and MARK attributes to CSS\r
+  ;; DESC\r
+  ;; If '%css-decoration%' is turned on then the list-style-type property of\r
+  ;; list items will be set to reflect the list item style selected in the\r
+  ;; DocBook instance.  This associative list maps the style type names used\r
+  ;; in your instance to the appropriate CSS names.  If no mapping exists,\r
+  ;; the name from the instance will be used.\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  '(("bullet" "disc")\r
+    ("box" "square")))\r
+\r
+(define %css-decoration%\r
+  ;; REFENTRY css-decoration\r
+  ;; PURP Enable CSS decoration of elements\r
+  ;; DESC\r
+  ;; If '%css-decoration%' is turned on then HTML elements produced by the\r
+  ;; stylesheet may be decorated with STYLE attributes.  For example, the\r
+  ;; LI tags produced for list items may include a fragment of CSS in the\r
+  ;; STYLE attribute which sets the CSS property "list-style-type".\r
+  ;; /DESC\r
+  ;; AUTHOR N/A\r
+  ;; /REFENTRY\r
+  #t)\r
+\r
+\r
+</style-specification-body>\r
+</style-specification>\r
+\r
+\r
+<style-specification id="html-notoc" use="html">\r
+<style-specification-body> \r
+\r
+;; ===================================================\r
+;; Vairant without TOC for the Homepage --oes 24/05/02\r
+;; ===================================================\r
+\r
+(define %generate-article-toc% \r
+  ;; Should a Table of Contents be produced for Articles?\r
+  ;; If true, a Table of Contents will be generated for each 'Article'.\r
+  #f)\r
+\r
+</style-specification-body>\r
+</style-specification>\r
+\r
+<external-specification id="docbook" document="docbook.dsl">\r
+\r
+</style-sheet>\r
diff --git a/doc/source/license.sgml b/doc/source/license.sgml
new file mode 100644 (file)
index 0000000..79df71c
--- /dev/null
@@ -0,0 +1,71 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/license.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: license.sgml,v 1.1 2002/05/05 20:20:00 hal9 Exp $
+
+  Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+  See LICENSE.
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  privoxy-man-page
+  user-manual
+  developer-manual
+  faq
+  webserver/index.sgml
+
+-->
+
+<para>
+ <application>Privoxy</application> is free software; you can
+ redistribute it and/or modify it under the terms of the 
+ <citetitle>GNU General Public
+<!--
+ <informalfigure pgwide="1" float="1">
+    <mediaobject>
+       <imageobject>
+          <imagedata scale="300" width="300" scalefit="1" fileref="../gnu.jpg" format="jpg">
+       </imageobject>
+       <textobject>
+          <phrase>GNU's Pet GNU</phrase>
+       </textobject>
+    </mediaobject>
+ </informalfigure>
+ or better:
+ <inlinegraphic depth="1" scale="300" align="left" fileref="../gnu.jpg"></inlinegraphic> 
+-->
+ License</citetitle>, version 2, as published by the Free Software Foundation.
+</para>
+
+<para>
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ <citetitle>GNU General Public License</citetitle> for
+<!--
+<figure pgwide="0"><title>The Pythagorean Theorum Illustrated</title>
+</figure>
+--> 
+ more details, which is available from the Free Software Foundation, Inc, 59
+ Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+</para>
+
+<para>
+ You should have received a copy of the <ulink
+ url="http://www.gnu.org/copyleft/gpl.html">
+ <citetitle>GNU General Public License</citetitle></ulink>
+ along with this program; if not, write to the <address> Free Software
+ Foundation, Inc. <street>59 Temple Place</street> - Suite 330
+ <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+ <country>USA</country> </address>
+</para>
+
diff --git a/doc/source/newfeatures.sgml b/doc/source/newfeatures.sgml
new file mode 100644 (file)
index 0000000..65a1e07
--- /dev/null
@@ -0,0 +1,130 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/newfeatures.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: newfeatures.sgml,v 1.9 2002/05/10 01:48:20 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  user-manual
+  faq
+
+-->
+<para>
+ <itemizedlist>
+
+<!--
+ <listitem>
+  <para>
+  FIXME: complete the list of features. change the order: most important
+  features to the top of the list. prefix new features with "NEW".
+  </para>
+ </listitem> 
+-->
+
+ <listitem>
+  <para>
+   Integrated browser based configuration and control utility at <ulink
+   url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>
+   (shortcut: <ulink url="http://p.p/">http://p.p/</ulink>). Browser-based
+   tracing of rule and filter effects. Remote toggling.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Web page content filtering (removes banners based on size,
+   invisible <quote>web-bugs</quote>, JavaScript and HTML annoyances, pop-up windows, etc.)
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Modularized configuration that allows for standard settings and
+   user settings to reside in separate files, so that installing updated
+   actions files won't overwrite individual user settings.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   HTTP/1.1 compliant (but not all optional 1.1 features are supported).
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Support for Perl Compatible Regular Expressions in the configuration files, and 
+   generally a more sophisticated and flexible configuration syntax over
+   previous versions.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Improved cookie management features (e.g. session based cookies).
+  </para>
+</listitem> 
+
+ <listitem>
+  <para>
+   GIF de-animation. 
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Bypass many click-tracking scripts (avoids script redirection).
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Multi-threaded (POSIX and native threads).
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   User-customizable HTML templates for all proxy-generated pages (e.g. "blocked" page).
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Auto-detection and re-reading of config file changes.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Improved signal handling, and a true daemon mode (Unix).
+  </para>
+</listitem> 
+
+ <listitem>
+  <para>
+   Every feature now controllable on a per-site or per-location basis, configuration
+   more powerful and versatile over-all.
+  </para>
+</listitem> 
+
+ <listitem>
+  <para>
+   Many smaller new features added, limitations and bugs removed, and security holes fixed.
+  </para>
+</listitem> 
+
+ </itemizedlist>
+</para>
diff --git a/doc/source/p-authors.sgml b/doc/source/p-authors.sgml
new file mode 100644 (file)
index 0000000..8d1c2d5
--- /dev/null
@@ -0,0 +1,88 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/p-authors.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: p-authors.sgml,v 1.7 2002/05/24 03:06:48 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  privoxy-man-page
+  AUTHORS
+
+-->
+<![%p-authors-formal;[
+<para>
+ Current Project Developers:
+</para>
+]]>
+
+<literallayout>
+ Jon Foster
+ Andreas Oesterhelt
+ Stefan Waldherr
+<![%p-authors-formal;[
+ ]]>
+ Thomas Steudten
+ Rodney Stromlund
+<![%p-authors-formal;[
+</literallayout>
+
+<para>
+ Current Project Contributors:
+</para>
+
+<literallayout>
+]]>
+ Rodrigo Barbosa (RPM specfiles)
+ Hal Burgiss (docs)
+ Alexander Lazic
+ Gábor Lipták
+ Guy
+ Haroon Rafique
+ David Schmidt (OS/2, Mac OSX ports)
+ Joerg Strohmayer
+ Sarantis Paskalis
+</literallayout>
+
+<![%p-authors-formal;[
+<para>
+ Originally developed by:
+</para>
+
+<literallayout>
+ Junkbusters Corp.
+ Anonymous Coders
+</literallayout>
+
+<para>
+ Thanks to the many people who have tested Privoxy, reported bugs, or made
+ suggestions. These include (in alphabetical order):
+</para>
+
+<literallayout>
+ Ken Arromdee
+ Reiner Buehl
+ Andrew J. Caines
+ Clifford Caoile
+ Peter E
+ Aaron Hamid
+ Magnus Holmgren
+ Paul Lieverse
+ Roberto Ragusa
+ Bart Schelstraete
+ Darren Wiebe
+ jwz
+ Michael T. Davis
+</literallayout>
+]]>
diff --git a/doc/source/privoxy-man-page.sgml b/doc/source/privoxy-man-page.sgml
new file mode 100644 (file)
index 0000000..026f511
--- /dev/null
@@ -0,0 +1,422 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/privoxy-man-page.sgml,v $
+
+ Purpose     :  Manual Page
+                This file belongs into
+                ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+                
+ $Id: privoxy-man-page.sgml,v 1.12 2002/05/10 01:48:20 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation. 
+ ========================================================================
+
+ Doc NOTES: This is some tricky markup! There are some quirks
+ to how this markup is handled. It is not always so co-operative.
+ Please don't change the markup unless you can verify the changes 
+ will improve finished output! 
+ literallayout tags are particularly sensitive to where they are placed.
+ The 'replaceable' and 'command' tags are used here somewhat unconventionally,
+ since it seems to generate the proper formatting (at least for me :).
+
+ Create man page: 'make man'
+
+ Requires docbook2man (short perl script), see CVS
+ http://sources.redhat.com/docbook-tools/. Also requires openjade and SGMLSpm
+ perl module. 
+ For man page references, see:
+ http://www.linuxdoc.org/HOWTO/mini/DocBook-Install/using.html
+ http://docbook.org/tdg/en/html/ch02.html#making-refentry
+
+-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN"[
+<!entity % dummy "IGNORE"> 
+<!entity p-intro SYSTEM "privoxy.sgml">
+<!entity seealso SYSTEM "seealso.sgml">
+<!entity copyright SYSTEM "copyright.sgml">
+<!entity license SYSTEM "license.sgml">
+<!entity authors SYSTEM "p-authors.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "IGNORE">           <!-- define we are not a text only doc -->
+<!entity % p-authors-formal "IGNORE"> <!-- exclude additional formating      -->
+<!entity my-copy "(C)">               <!-- db2man barfs on copyright symbol  -->
+]>
+
+<refentry id="privoxy">
+<refentryinfo>
+ <date>2002-05-14</date>
+</refentryinfo>
+<refmeta>
+ <refentrytitle>privoxy</refentrytitle> 
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>
+  Privoxy &p-version;<![%p-not-stable;[ &p-status;]]>
+ </refmiscinfo>
+</refmeta>
+
+<refnamediv>
+ <refname><application>privoxy</application></refname>
+ <refpurpose>Privacy Enhancing Proxy</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis> 
+  <command>privoxy</command>
+  <arg><option>--help</option></arg>
+  <arg><option>--version</option></arg>
+  <arg><option>--no-daemon</option></arg>
+  <arg><option>--pidfile </option><replaceable class="parameter">pidfile</replaceable></arg>  
+  <arg><option>--user </option><replaceable class="parameter">user[.group]</replaceable></arg> 
+  <arg><replaceable class="parameter">configfile</replaceable></arg>        
+  <command>(UNIX)</command>
+ </cmdsynopsis>
+
+ <cmdsynopsis> 
+  <command>privoxy.exe</command>              
+  <arg><replaceable class="parameter">configfile</replaceable></arg>
+  <command>(Windows)</command>
+ </cmdsynopsis>                                      
+</refsynopsisdiv>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Options</title>
+ <para>
+  <command>Privoxy</command> may be invoked with the following command line
+  options:
+ </para>
+
+ <variablelist>                                          
+  <varlistentry>
+    <term>--help</term>
+      <listitem>
+       <para>
+         Print brief usage info and exit.
+        </para>
+      </listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term>--version</term>
+      <listitem>
+       <para>
+         Print version info and exit.
+        </para>
+      </listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term>--no-daemon</term>
+     <listitem>
+      <para>
+        Don't  become  a daemon, i.e. don't fork and become process group
+        leader, don't detach from controlling tty, and do all logging there.
+      </para>
+    </listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term>--pidfile <replaceable class="parameter">pidfile</replaceable></term>
+     <listitem>
+      <para>
+        On startup, write the process ID to <replaceable class="parameter">pidfile</replaceable>.
+        Delete the <replaceable class="parameter">pidfile</replaceable> on exit.
+        Failiure to create or delete the <replaceable class="parameter">pidfile</replaceable>
+        is non-fatal. If no <command>--pidfile</command> option is given, no PID file will be used.
+      </para>
+    </listitem>
+  </varlistentry>
+
+  <varlistentry>
+    <term>--user <replaceable class="parameter">user[.group]</replaceable></term>
+     <listitem>
+      <para>
+       <!-- Note: replaceable is maybe the wrong tag, but generates  -->
+       <!-- correct looking man output.                              -->
+       After (optionally) writing the PID file, assume the user ID of
+       <replaceable class="parameter">user</replaceable> and the GID of
+       <replaceable class="parameter">group</replaceable>, or, if the optional
+       <replaceable class="parameter">group</replaceable> was not given, the default group of
+       <replaceable class="parameter">user</replaceable>. Exit if the privileges are not
+       sufficient to do so.
+     </para>
+    </listitem>
+  </varlistentry>
+ </variablelist>
+ <para>
+  If the <filename>configfile</filename> is not specified on  the  command  line,
+  <command>Privoxy</command>  will  look for a file named
+  <filename>config</filename> in the current directory (except on Win32 where
+  it will try <filename>config.txt</filename>). If no
+  <filename>configfile</filename> is found, <command>Privoxy</command> will 
+  fail to start.
+ </para>
+
+</refsect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Description</title>
+<!-- Include privoxy.sgml boilerplate: -->
+ &p-intro;
+<!-- end boilerplate -->
+</refsect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Installation and Usage</title>
+<para>
+ Browsers must be individually configured to use <command>Privoxy</command> as
+ a HTTP proxy.  The default setting is  for  localhost,  on port  8118
+ (configurable in the main config file).  To set the HTTP proxy in Netscape
+ and Mozilla, go through:  <command>Edit</command>;
+ <command>Preferences</command>;  <command>Advanced</command>;
+ <command>Proxies</command>;  <command>Manual Proxy Configuration</command>;
+ <command>View</command>. 
+</para>
+<para>
+ For Internet Explorer, go through: <command>Tools</command>; 
+ <command>Internet Properties</command>; <command>Connections</command>;
+ <command>LAN Settings</command>. 
+</para>
+<para>
+ The Secure (SSL) Proxy should also be set to the same values, otherwise
+ https: URLs will not be proxied. 
+</para>
+<para>
+ For other browsers, check the documentation.
+</para>
+</refsect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Configuration</title>
+<para>
+ <command>Privoxy</command> can be configured with the various configuration
+ files. The default configuration files are: <filename>config</filename>,
+ <filename>default.filter</filename>, and
+ <filename>default.action</filename>. <filename>user.action</filename> should 
+ be used for locally defined exceptions to the default rules of
+ <filename>default.action</filename> These are all well commented.  On Unix
+ and Unix-like systems, these are located in
+ <filename>/etc/privoxy/</filename> by default. On Windows, OS/2 and AmigaOS,
+ these files are in the same directory as the <command>Privoxy</command>
+ executable.
+</para>
+<para>
+ The name and number of configuration files has changed from previous
+ versions, and is subject to change as development progresses. In fact, the
+ configuration itself is changed  and  much more sophisticated. See the
+ <ulink url="http://www.privoxy.org/user-manual/">user-manual</ulink> for a
+ complete explanation of all configuration options and general usage.
+</para>
+<para>
+ The actions list (ad blocks, etc) can also be configured with your
+ web browser at <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>.
+ <command>Privoxy's</command> configuration parameters  can also  be viewed at
+ the same page. In addition, <command>Privoxy</command> can be toggled on/off.
+ This is an internal page.
+</para>
+</refsect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Sample Configuration</title>
+<para>
+ A brief example of what a simple <filename>default.action</filename>
+ configuration might look like:
+</para>
+
+<literallayout>
+ # Define a few useful custom aliases for later use
+ {{alias}}
+
+ # Useful aliases
+ +crunch-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+ -crunch-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ +imageblock      = +block +handle-as-image
+
+ # Fragile sites should have the minimum changes
+ fragile     = -block -deanimate-gifs -fast-redirects -filter \
+               -hide-referer -prevent-cookies -kill-popups
+
+ ## Turn some actions on ################################
+ { \
+ -add-header \
+ -block \
+ +deanimate-gifs{last} \
+ -downgrade-http-version \
+ -fast-redirects \
+ +filter{html-annoyances} \
+ +filter{js-annoyances} \
+ +filter{content-cookies} \
+ +filter{webbugs} \
+ +filter{banners-by-size} \
+ +hide-forwarded-for-headers \
+ +hide-from-header{block} \
+ +hide-referrer{forge} \
+ -hide-user-agent \
+ -handle-as-image \
+ +set-image-blocker{pattern} \
+ -limit-connect \
+ +prevent-compression \
+ +session-cookies-only \
+ -crunch-cookies \
+ -kill-popups \
+ }
+ /   # '/' Matches *all* URL patterns
+ # Block, and treat these URL patterns as if they were 'images'.
+ # We would expect these to be ads.
+ {+imageblock}
+  .ad.doubleclick.net
+  .a[0-9].yimg.com/(?:(?!/i/).)*$
+  ad.*.doubleclick.net
+
+ # Block any URLs that match these patterns
+ {+block}
+  ad*.
+  .*ads.
+  banner?.
+  /.*count(er)?\.(pl|cgi|exe|dll|asp|php[34]?)
+  .hitbox.com 
+
+ # Make exceptions for these harmless ones that would be 
+ # caught by our +block patterns just above.
+ {-block}
+  adsl.
+  advice.
+  .*downloads.
+
+</literallayout>
+
+<para>
+ Then for a <filename>user.action</filename>, we would put local,
+ narrowly defined exceptions:
+</para>
+
+<literallayout>
+ # Re-define aliases as needed here
+ {{alias}}
+
+ # Useful aliases
+ -crunch-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ # Set personal exceptions to the policies in default.action #######
+
+ # Sites where we want persistant cookies, so allow *all* cookies
+ {-crunch-cookies -session-cookies-only}
+  .redhat.com
+  .sun.com
+  .msdn.microsoft.com
+ # This site breaks easily.
+ {-block -fast-redirects}
+  .forbes.com
+
+</literallayout>
+
+<para>
+ See the comments in the configuration files themselves, or the 
+ <citetitle>user-manual</citetitle>
+ for explanations of the above syntax, and other <command>Privoxy</command>
+ configuration options.
+</para>
+
+</refsect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Files</title>
+<!-- this is a cheesy way to do this, but WTF. -->
+<literallayout> 
+ <filename>/usr/sbin/privoxy</filename>
+ <filename>/etc/privoxy/config</filename>
+ <filename>/etc/privoxy/default.action</filename>
+ <filename>/etc/privoxy/standard.action</filename>
+ <filename>/etc/privoxy/user.action</filename>
+ <filename>/etc/privoxy/default.filter</filename>
+ <filename>/etc/privoxy/trust</filename>
+ <filename>/etc/privoxy/templates/*</filename>
+ <filename>/var/log/privoxy/logfile</filename>
+</literallayout>
+
+<para>
+ Various other files should be included, but may vary depending on platform
+ and build configuration. More documentation should be included in the local
+ documentation directory.
+</para>
+
+</refsect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Signals</title>
+<para>
+ <!-- command tag is used here to get proper looking format  -->
+ <command>Privoxy</command> terminates on the <command>SIGINT</command>,
+ <command>SIGTERM</command> and <command>SIGABRT</command> signals. Log
+ rotation scripts may cause a re-opening of the logfile by sending a 
+ <command>SIGHUP</command> to <command>Privoxy</command>. Note that unlike
+ other daemons,  <command>Privoxy</command> does not need to be made aware of
+ config file changes by <command>SIGHUP</command> -- it will detect them
+ automatically. 
+</para>
+
+</refsect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Notes</title>
+<![%p-not-stable;[
+<para>
+ This is a &p-status; version of <command>Privoxy</command>. Not 
+ all features are well tested.
+</para>]]>
+<para>
+ Please see the <citetitle>user-manual</citetitle> on how to contact the
+ developers for feature requests, reporting problems, and other questions.
+</para>
+
+</refsect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>See Also</title>
+<!-- Include seealso.sgml boilerplate: -->
+ &seealso;
+<!-- end boilerplate -->
+</refsect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Development Team</title>
+<!-- Include p-authors.sgml boilerplate: -->
+ &authors;
+<!-- end boilerplate -->
+</refsect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<refsect1><title>Copyright and License</title>
+
+<refsect2><title>Copyright</title>
+<!-- Include copyright.sgml boilerplate: -->
+ &copyright;
+<!-- end boilerplate -->
+</refsect2>
+
+<refsect2><title>License</title>
+<!-- Include license.sgml boilerplate: -->
+ &license;
+<!-- end boilerplate -->
+</refsect2>
+</refsect1>
+
+</refentry>
diff --git a/doc/source/privoxy.sgml b/doc/source/privoxy.sgml
new file mode 100644 (file)
index 0000000..8ecbcc3
--- /dev/null
@@ -0,0 +1,42 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/privoxy.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: privoxy.sgml,v 1.6 2002/04/15 23:31:42 oes Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  privoxy-man-page
+  user-manual
+  faq
+  developer-manual
+  README
+  webserver/index.sgml
+
+-->
+
+<para>
+ <application>Privoxy</application> is a web proxy with advanced filtering
+ capabilities for protecting privacy, filtering web page content, managing
+ cookies, controlling access, and removing ads, banners, pop-ups and other
+ obnoxious Internet junk. <application>Privoxy</application> has a very
+ flexible configuration and can be customized to suit individual needs and
+ tastes. <application>Privoxy</application> has application for both
+ stand-alone systems and multi-user networks.
+</para>
+
+<para>
+ <application>Privoxy</application> is based on <application>Internet
+ Junkbuster</application> (tm).
+</para>
diff --git a/doc/source/readme.sgml b/doc/source/readme.sgml
new file mode 100644 (file)
index 0000000..0970d42
--- /dev/null
@@ -0,0 +1,244 @@
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!entity % dummy "IGNORE"> 
+<!entity supported SYSTEM "supported.sgml">
+<!entity p-intro SYSTEM "privoxy.sgml">
+<!entity contacting SYSTEM "contacting.sgml">
+<!entity buildsource SYSTEM "buildsource.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "INCLUDE">       <!-- define we are a text only doc    -->
+<!entity % p-doc "IGNORE">         <!-- and never a text doc             -->
+<!entity % p-readme "INCLUDE">     <!-- all your README belong to us     -->
+]>
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/readme.sgml,v $
+
+ Purpose     :  README for Privoxy
+                
+ $Id: readme.sgml,v 1.15 2002/05/05 17:35:32 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation. You have been warned!
+ Failure to abide by this rule will result in the revocation of your license 
+ to live a peaceful existence!
+ ========================================================================
+
+ ===================================================================
+ READ: Document Note: This file generates the README in the top level 
+ source directory. It is generated as only a plain text file. The 
+ current markup is not suitable for other formats. Build from 
+ Makefile with 'make dok-readme'.
+ ===================================================================
+
+ READ:
+
+ ======================================================================
+ NOTE: The left margin spacing is *important* when using 'literallayout'
+ WYSISWYG!!! Don't mess this up!!! Careful with linebreaks too, ie 
+ the para tag forces a linebreak. Tags need to be carefully placed as a result
+ to avoid extra blank lines, etc. 
+ ======================================================================
+
+ For stable releases, change 
+  entity % p-not-stable "INCLUDE" 
+ to 
+  entity % p-not-stable "IGNORE" 
+  
+ in the DTD at the top. This will toggle various text 'off'. BOTH
+ MUST be toggled in this case or you will get both text referencing 
+ stable and unstable versions. You only want one or the other!
+
+-->
+<article id="index">
+<artheader>
+<![%dummy;[
+ <para>
+ <comment>
+  This is here to keep vim syntax file from breaking :/
+  If I knew enough to fix it, I would.
+  PLEASE DO NOT REMOVE! HB: hal@foobox.net
+ </comment>
+ </para>
+]]>
+<abstract>
+<para>
+ <literal>
+  <msgtext>
+   <literallayout>
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/doc/source/readme.sgml,v $
+ *
+ * Purpose     :  README file to give a short intro.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *********************************************************************/
+</literallayout>
+</msgtext>
+</literal>
+</para>
+
+<para>
+ <!-- include some conditional text -->
+ This README is included with <![%p-not-stable;[ the development version of]]>
+ Privoxy &p-version;<![%p-not-stable;[, which will eventually become Privoxy v3.0 (and soon we
+ hope!)]]>. See http://www.privoxy.org/ for more information. The current code
+ level is &p-status;<![%p-not-stable;[, and seems stable to us :)]]>.
+</para>
+</abstract>
+</artheader>
+
+<!-- Include privoxy.sgml boilerplate: -->
+&p-intro;
+<!-- end boilerplate -->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="importantchanges" ><title>IMPORTANT CHANGES</title>
+<para>
+ NEWS! As of 03/24/02, the name of this project has been changed from
+ ijbswa/Junkbuster to Privoxy. This is reflected in many of the included
+ files. 
+</para>
+<para>
+ WARNING! If upgrading from earlier versions of this project via RPM packages,
+ the new package will delete any previously installed 'Junkbuster' packages.
+</para>
+<para>
+ IMPORTANT! READ! Configuration Change as of 17 Mar 2002: The default listening
+ port is now 8118 due to conflicts with port 8000 assignment. You will need to
+ change your browser if upgrading!!! And maybe firewall, etc.
+</para>
+</sect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="install" ><title>INSTALL</title>
+<!-- include buildsource.sgml boilerplate: -->
+ &buildsource;
+<!-- end boilderplate -->
+</sect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="run"><title>RUN</title>
+<para>
+ privoxy [&mdash;&mdash;help] [&mdash;&mdash;version]
+ [&mdash;&mdash;no-daemon] [&mdash;&mdash;pidfile PIDFILE] [&mdash;&mdash;user
+ USER[.GROUP]] [config_file]
+</para>
+<para>
+ See the man page or user-manual for a brief explanation of each option.
+</para>
+<para>
+ If no config_file is specified on the command line, Privoxy will look for a
+ file named 'config' in the current directory (except Win32 which will look
+ for 'config.txt'). If no config_file is found, Privoxy will fail to start.
+</para>
+<para>
+ Or for Red Hat: /etc/rc.d/init.d/privoxy start
+</para>
+<para>
+ Or for SuSE:   /etc/rc.d/privoxy start
+</para>
+</sect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="configuration"><title>CONFIGURATION</title>
+<para>
+ See: 'config', 'default.action', 'user.action', and 'default.filter'.
+ 'user.action' is for personal configuration. These are all well commented.
+ Most of the magic is in '*.action' files. 'user.action' should be 
+ used for any actions customizations. On Unix-like systems, these files
+ are installed in /etc/privoxy.  On Windows, then wherever the executable
+ itself is installed. There are many significant changes and advances since
+ Junkbuster v2.0.x. The user-manual has a run down of configuration options,
+ and examples: http://www.privoxy.org/user-manual/.
+</para>
+<para>
+ Be sure to set your browser(s) for HTTP/HTTPS Proxy at &lt;IP&gt;:&lt;Port&gt;, or
+ whatever you specify in the config file under 'listen-address'. DEFAULT is
+ localhost:8118.
+</para>
+<para>
+ The actions list can be configured via the web interface accessed via
+ http://p.p/, as well other options.
+</para>
+<![%p-not-stable;[
+<para>
+ All configuration files are subject to unannounced changes during the
+ development process.
+</para>
+]]>
+</sect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="documentation"><title>DOCUMENTATION</title>
+<para>
+ There should be documentation in the 'doc' subdirectory<![%p-not-stable;[, but it
+ is not completed at this point]]>. In particular, see the user-manual there,
+ the faq, and those interested in Privoxy development, should look at
+ developer-manual. 
+</para>
+<para>
+ <![%p-not-stable;[
+ The most up to date source of information on the current development version,
+ may still be either comments in the source code, or the included
+ configuration files. ]]>The source and configuration files are all well
+ commented. The main configuration files are: 'config', 'default.action', and
+ 'default.filter'<![%p-not-stable;[ in the toplevel source directory]]>. 
+</para>
+
+<para>
+ Included documentation may vary according to platform and packager.
+</para>
+</sect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="contact"><title>CONTACTING THE DEVELOPERS, BUG REPORTING AND FEATURE REQUESTS</title>
+<!-- Include contacting.sgml boilerplate: -->
+  &contacting;
+<!-- end boilerplate -->
+</sect1>
+
+<!-- <para> -->
+<!--  <LiteralLayout> -->
+<!--  ------------------------------------------------------------------------- -->
+<!--  ijbswa-developers@lists.sourceforge.net -->
+<!-- </LiteralLayout> -->
+<!-- </para> -->
+<!-- <para> -->
+<!--  $Id: readme.sgml,v 1.15 2002/05/05 17:35:32 hal9 Exp $ -->
+<!-- </para> -->
+
+</article>
diff --git a/doc/source/seealso.sgml b/doc/source/seealso.sgml
new file mode 100644 (file)
index 0000000..22dc127
--- /dev/null
@@ -0,0 +1,107 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa//current/doc/source/seealso.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: seealso.sgml,v 1.8 2002/05/17 13:49:30 oes Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  privoxy-man-page
+  user-manual
+  faq
+  developer-manual
+
+ NOTE: 04/05/02, HB Removed &nbsp; tags. They were causing docbook2man 
+ to barf.
+
+-->
+
+<para>
+ Other references and sites of interest to <application>Privoxy</application>
+ users:
+</para>
+
+<para>
+ <simplelist>
+  <member>
+   <ulink
+   url="http://www.privoxy.org/">http://www.privoxy.org/</ulink>, 
+   the <application>Privoxy</application> Home page. 
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink
+   url="http://www.privoxy.org/faq/">http://www.privoxy.org/faq/</ulink>, 
+   the <application>Privoxy</application> FAQ. 
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="http://sourceforge.net/projects/ijbswa/">http://sourceforge.net/projects/ijbswa/</ulink>, 
+   the Project Page for <application>Privoxy</application> on 
+   <ulink url="http://sourceforge.net">SourceForge</ulink>.
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>,
+   the web-based user interface. <application>Privoxy</application> must be
+   running for this to work. Shortcut: <ulink url="http://p.p/">http://p.p/</ulink>
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">http://www.privoxy.org/actions/</ulink>, to submit <quote>misses</quote> to the developers. 
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="http://www.junkbusters.com/ht/en/cookies.html">http://www.junkbusters.com/ht/en/cookies.html</ulink>,
+   an explanation how cookies are used to track web users.
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="http://www.junkbusters.com/ijb.html">http://www.junkbusters.com/ijb.html</ulink>,
+   the original Internet Junkbuster.
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="http://www.waldherr.org/junkbuster/">http://www.waldherr.org/junkbuster/</ulink>,
+   Stefan Waldherr's version of Junkbuster, from which <application>Privoxy</application> was
+   derived.
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="http://privacy.net/analyze/">http://privacy.net/analyze/</ulink>, a useful site
+   to check what information about you is leaked while you browse the web.
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink url="http://www.squid-cache.org/">http://www.squid-cache.org/</ulink>, a very popular
+   caching proxy, which is often used together with <application>Privoxy</application>.
+  </member>
+ </simplelist>
+ <simplelist>
+  <member>
+   <ulink
+   url="http://www.privoxy.org/developer-manual/">http://www.privoxy.org/developer-manual/</ulink>, 
+   the <application>Privoxy</application> developer manual. 
+  </member>
+ </simplelist>
+</para>
diff --git a/doc/source/supported.sgml b/doc/source/supported.sgml
new file mode 100644 (file)
index 0000000..072b815
--- /dev/null
@@ -0,0 +1,45 @@
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/supported.sgml,v $
+
+ Purpose     :  Entity included in other project documents.
+                
+ $Id: supported.sgml,v 1.9 2002/05/10 01:48:20 hal9 Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ======================================================================
+  This file used for inclusion with other documents only.
+ ======================================================================
+
+ If you make changes to this file, please verify the finished 
+ docs all display as intended.
+
+ This file is included into:
+
+  user-manual
+  faq
+  newfeatures
+
+-->
+<para>
+ At present, <application>Privoxy</application> is known to run on
+ Windows(95, 98, ME, 2000, XP), Linux (RedHat, Suse, Debian, Conectiva),
+ Mac OSX, OS/2, AmigaOS, BeOS, FreeBSD, NetBSD, Solaris,  and many more 
+ flavors of Unix.
+</para>
+
+<![%p-supp-userman;[
+<para>
+ But any operating system that runs TCP/IP, can conceivably take advantage of
+ <application>Privoxy</application> in a networked situation where
+ <application>Privoxy</application> would run as a server on a LAN gateway. 
+ Then only the <quote>gateway</quote> needs to be running one of the above
+ operating systems.
+</para>
+
+<para>
+ Source code is freely available, so porting to other operating systems 
+ is always a possibility.
+</para>
+]]>
diff --git a/doc/source/user-manual.sgml b/doc/source/user-manual.sgml
new file mode 100644 (file)
index 0000000..60ab281
--- /dev/null
@@ -0,0 +1,7581 @@
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!entity % dummy "IGNORE"> 
+<!entity supported SYSTEM "supported.sgml">
+<!entity newfeatures SYSTEM "newfeatures.sgml">
+<!entity p-intro SYSTEM "privoxy.sgml">
+<!entity seealso SYSTEM "seealso.sgml">
+<!entity buildsource SYSTEM "buildsource.sgml">
+<!entity contacting SYSTEM "contacting.sgml">
+<!entity history SYSTEM "history.sgml">
+<!entity copyright SYSTEM "copyright.sgml">
+<!entity license SYSTEM "license.sgml">
+<!entity p-authors SYSTEM "p-authors.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-authors-formal "INCLUDE"> <!-- include additional text, etc  -->
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "IGNORE">        <!-- define we are not a text only doc -->
+<!entity % p-doc "INCLUDE">        <!-- and we are a formal doc           -->
+<!entity % p-readme "IGNORE">
+<!entity % p-config "IGNORE">
+<!entity % p-supp-userman "IGNORE"> <!-- Omit some from supported.sgml    -->
+<!entity  my-copy "&copy;">         <!-- kludge for docbook2man           -->
+<!entity % draft "IGNORE">          <!-- WIP stuff    -->
+]>
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/user-manual.sgml,v $
+
+ Purpose     :  user manual
+                This file belongs into
+                ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+
+ $Id: user-manual.sgml,v 1.122 2002/05/24 13:24:08 oes Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation.
+ ========================================================================
+
+-->
+
+<article id="index">
+<artheader>
+
+<title>Privoxy User Manual</title>
+
+<pubdate>
+ <subscript>
+<!-- Completely the wrong markup, but very little is allowed  -->
+<!-- in this part of an article. FIXME -->
+ <link linkend="copyright">Copyright</link> &my-copy; 2001, 2002 by 
+ <ulink url="http://www.privoxy.org">Privoxy Developers</ulink>
+ </subscript>
+</pubdate>
+
+<pubdate>$Id: user-manual.sgml,v 1.122 2002/05/24 13:24:08 oes Exp $</pubdate>
+
+<!--
+
+Note: the following should generate a separate page, and a live link to it,
+all nicely done. But it doesn't for some mysterious reason. Please leave
+commented unless it can be fixed proper. For the time being, the
+copyright/license declarations will be in their own sgml.
+
+Hal.
+
+<copyright>
+  <year>2001</year>
+  <year>2002</year>
+  <holder>Privoxy Developers</holder>
+</copyright>
+
+<legalnotice id="legalnotice"> 
+ <para>
+  text goes here ........
+ </para>
+</legalnotice>
+
+-->
+
+
+<abstract>
+
+<![%dummy;[
+ <para>
+ <comment>
+  This is here to keep vim syntax file from breaking :/
+  If I knew enough to fix it, I would.
+  PLEASE DO NOT REMOVE! HB: hal@foobox.net
+ </comment>
+ </para>
+]]>
+
+ <para>
+  The <citetitle>User Manual</citetitle> gives users information on how to
+  install, configure and use <ulink
+  url="http://www.privoxy.org/"><application>Privoxy</application></ulink>.
+ </para>
+
+<!-- Include privoxy.sgml boilerplate: -->
+ &p-intro;
+<!-- end privoxy.sgml -->
+
+ <para>
+  You can find the latest version of the <citetitle>User Manual</citetitle> at  <ulink
+  url="http://www.privoxy.org/user-manual/">http://www.privoxy.org/user-manual/</ulink>.
+  Please see the <ulink url="contact.html">Contact section</ulink> on how to
+  contact the developers.
+ </para>
+
+<!--   <para> -->
+<!--    Feel free to send a note to the developers at <email>ijbswa-developers@lists.sourceforge.net</email>. -->
+<!--   </para> -->
+</abstract>
+
+</artheader>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 label="1" id="introduction"><title>Introduction</title>
+<para>
+ This documentation is included with the current &p-status; version of
+ <application>Privoxy</application>, v.&p-version;<![%p-not-stable;[, 
+ and is mostly complete at this point. The most up to date reference for the
+ time being is still the comments in the source files and in the individual
+ configuration files. Development of version 3.0 is currently nearing
+ completion, and includes many significant changes and enhancements over
+ earlier versions. The target release date for
+ stable v3.0 is <quote>soon</quote> ;-)]]>.
+</para>
+
+<!-- include only in non-stable versions -->
+<![%p-not-stable;[
+<para>
+ Since this is a &p-status; version, not all new features are well tested. This
+ documentation may be slightly out of sync as a result (especially with 
+ CVS sources). And there <emphasis>may be</emphasis> bugs, though hopefully
+ not many! 
+</para>
+]]>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="features"><title>Features</title>
+<para>
+ In addition to <application>Internet Junkbuster's</application> traditional
+ features of ad and banner blocking and cookie management,
+ <application>Privoxy</application> provides new features<![%p-not-stable;[,
+ some of them currently under development]]>:
+</para>
+<!-- Include newfeatures.sgml boilerplate here: -->
+ &newfeatures;
+<!-- end boilerplate -->
+</sect2>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="installation"><title>Installation</title>
+
+<para>
+ <application>Privoxy</application> is available both in convenient pre-compiled
+ packages for a wide range of operating systems, and as raw source code.
+ For most users, we recommend using the packages, which can be downloaded from our
+ <ulink url="http://sourceforge.net/projects/ijbswa/">Privoxy Project
+ Page</ulink>.
+</para>
+
+<para>
+ Note: If you have a previous <application>Junkbuster</application> or
+ <application>Privoxy</application> installation on your system, you
+ will need to remove it.  On some platforms, this may be done for you as part
+ of their installation procedure. (See below for your platform). In any case
+ <emphasis>be sure to backup your old configuration if it is valuable to
+ you.</emphasis> See the <link linkend="upgradersnote">note to
+ upgraders</link> section below.
+</para>
+
+<!--   ~~~~~       New section      ~~~~~     --> 
+<sect2 id="installation-packages"><title>Binary Packages</title>
+<para>
+How to install the binary packages depends on your operating system:
+</para>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="installation-pack-rpm"><title>Red Hat, SuSE and Conectiva RPMs</title>
+
+<para>
+ RPMs can be installed with <literal>rpm -Uvh privoxy-&p-version;-1.rpm</literal>,
+ and will use <filename>/etc/privoxy</filename> for the location 
+ of configuration files.
+</para>
+
+<para>
+ Note that on Red Hat, <application>Privoxy</application> will
+ <emphasis>not</emphasis> be automatically started on system boot. You will
+ need to enable that using <command>chkconfig</command>,
+ <command>ntsysv</command>, or similar methods. Note that SuSE will 
+automatically start Privoxy in the boot process.
+</para>
+
+<para>
+ If you have problems with failed dependencies, try rebuilding the SRC RPM: 
+ <literal>rpm --rebuild privoxy-&p-version;-1.src.rpm</literal>. This 
+ will use your locally installed libraries and RPM version. 
+</para>
+
+<para>
+ Also note that if you have a <application>Junkbuster</application> RPM installed
+ on your system, you need to remove it first, because the packages conflict.
+ Otherwise, RPM will try to remove <application>Junkbuster</application>
+ automatically, before installing <application>Privoxy</application>.
+</para>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="installation-deb"><title>Debian</title>
+<para>
+ DEBs can be installed with <literal>dpkg -i
+ privoxy_&p-version;-1.deb</literal>, and will use
+ <filename>/etc/privoxy</filename> for the location of configuration
+ files.
+</para>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="installation-pack-win"><title>Windows</title>
+
+<para>
+ Just double-click the installer, which will guide you through
+ the installation process. You will find the configuration files
+ in the same directory as you installed Privoxy in. We do not
+ use the registry of Windows. 
+</para>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="installation-pack-bintgz"><title>Solaris, NetBSD, FreeBSD, HP-UX</title>
+
+<para>
+ Create a new directory, <literal>cd</literal> to it, then unzip and
+ untar the archive. For the most part, you'll have to figure out where
+ things go. FIXME.
+</para>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="installation-os2"><title>OS/2</title>
+
+<para>
+ First, make sure that no previous installations of
+ <application>Junkbuster</application> and / or 
+ <application>Privoxy</application> are left on your
+ system. You can do this by 
+</para>
+
+<para>
+ Then, just double-click the WarpIN self-installing archive, which will
+ guide you through the installation process. A shadow of the
+ <application>Privoxy</application> executable will be placed in your
+ startup folder so it will start automatically whenever OS/2 starts.
+</para>
+
+<para>
+ The directory you choose to install <application>Privoxy</application>
+ into will contain all of the configuration files.
+</para>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="installation-mac"><title>Max OSX</title>
+<para>
+ Unzip the downloaded package (you can either double-click on the file
+ in the finder, or on the desktop if you downloaded it there).  Then,
+ double-click on the package installer icon and follow the installation
+ process.
+ <application>Privoxy</application> will be installed in the subdirectory
+ <literal>/Applications/Privoxy.app</literal>.
+ <application>Privoxy</application> will set itself up to start 
+ automatically on system bring-up via
+ <literal>/System/Library/StartupItems/Privoxy</literal>.
+</para>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="installation-amiga"><title>AmigaOS</title>
+<para>
+ Copy and then unpack the <filename>lha</filename> archive to a suitable location. 
+ All necessary files will be installed into <application>Privoxy</application>
+ directory, including all configuration and log files. To uninstall, just 
+ remove this directory.
+</para>
+<para>
+ Start <application>Privoxy</application> (with RUN &lt;&gt;NIL:) in your
+ <filename>startnet</filename> script (AmiTCP), in
+ <filename>s:user-startup</filename> (RoadShow), as startup program in your
+ startup script (Genesis), or as startup action (Miami and MiamiDx). 
+ <application>Privoxy</application> will automatically quit when you quit your
+ TCP/IP stack (just ignore the harmless warning your TCP/IP stack may display that
+ <application>Privoxy</application> is still running).
+</para>
+</sect3>
+</sect2>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="installation-source"><title>Building from Source</title>
+
+<para>
+ The most convenient way to obtain the <application>Privoxy</application> sources
+ is to download the source tarball from our <ulink url="http://sf.net/projects/ijbswa/">project
+ page</ulink>.
+</para>
+
+<para>
+ If you like to live on the bleeding edge and are not afraid of using
+ possibly unstable development versions, you can check out the up-to-the-minute
+ version directly from <ulink url="http://sourceforge.net/cvs/?group_id=11118">the
+ CVS repository</ulink> or simply download <ulink
+ url="http://cvs.sourceforge.net/cvstarballs/ijbswa-cvsroot.tar.gz">the nightly CVS
+ tarball.</ulink>
+</para>
+
+<!-- include buildsource.sgml boilerplate: -->
+&buildsource;
+<!-- end boilerplate -->
+
+</sect2>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="upgradersnote">
+<title>Note to Upgraders</title>
+<para>
+ There are very significant changes from earlier 
+ <application>Junkbuster</application> versions to the current
+ <application>Privoxy</application>. The number, names, syntax, and
+ purposes of configuration files have substantially  changed.
+ <application>Junkbuster 2.0.x</application> configuration
+ files will not migrate, <application>Junkbuster 2.9.x</application>
+ and <application>Privoxy</application> configurations will need to be
+ ported. The functionalities of the old <filename>blockfile</filename>,
+ <filename>cookiefile</filename> and <filename>imagelist</filename> 
+ are now combined into the <link linkend="actions-file"><quote>actions
+ files</quote></link>.  
+ <filename>default.action</filename>, is the main actions file. Local
+ exceptions should best be put into <filename>user.action</filename>.
+</para>
+<para>
+ A <link linkend="filter-file"><quote>filter file</quote></link> (typically
+ <filename>default.filter</filename>) is new as of <application>Privoxy
+ 2.9.x</application>, and provides some of the new sophistication (explained
+ below). <filename>config</filename> is much the same as before.
+</para>
+<para>
+ If upgrading from a 2.0.x version, you will have to use the new config 
+ files, and possibly adapt any personal rules from your older files.
+ When porting personal rules over from the old <filename>blockfile</filename>
+ to the new actions files, please note that even the pattern syntax has
+ changed. If upgrading from 2.9.x development versions, it is still
+ recommended to use the new configuration files.
+</para>
+<para>
+ A quick list of things to be aware of before upgrading: 
+</para>
+
+<para>
+ <itemizedlist>
+
+ <listitem>
+  <para>
+   The default listening port is now 8118 due to a conflict with another 
+   service (NAS).
+  </para>
+ </listitem>  
+ <listitem>
+  <para>  
+    Some installers may remove earlier versions completely. Save any 
+    important configuration files!
+  </para>
+ </listitem>
+ <listitem>
+  <para>
+   <application>Privoxy</application> is controllable with a web browser 
+   at the special URL: <ulink
+   url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>
+   (Shortcut: <ulink url="http://p.p/">http://p.p/</ulink>). Many
+   aspects of configuration can be done here, including temporarily disabling
+   <application>Privoxy</application>.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   The primary configuration files for cookie management, ad and banner 
+   blocking, and many other aspects of <application>Privoxy</application>
+   configuration are the <link linkend="actions-file">actions
+   files</link>. It is strongly recommended to become familiar with the new
+   actions concept below, before modifying these files. Locally defined rules 
+   should go into <filename>user.action</filename>.
+  </para>
+ </listitem> 
+  <listitem>
+  <para>
+<!-- I think it is best to keep this somewhat vague, in case  -->
+<!-- the situation changes under our feet. -->   
+   Some installers may not automatically start
+   <application>Privoxy</application> after installation.
+  </para>
+ </listitem> 
+
+ </itemizedlist>
+</para>
+</sect1>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="quickstart"><title>Quickstart to Using <application>Privoxy</application></title>
+<para>
+ <itemizedlist>
+
+ <listitem>
+  <para>
+   If upgrading, from versions before 2.9.16, please back up any configuration
+   files. See the <link linkend="upgradersnote">Note to Upgraders</link> Section.
+ </para>
+</listitem> 
+
+ <listitem>
+  <para>
+  Install <application>Privoxy</application>. See the <link
+  linkend="installation">Installation Section</link> below for platform specific
+  information. 
+ </para>
+ </listitem>  
+
+ <listitem>
+  <para>
+   Advanced users and those who want to offer <application>Privoxy</application>
+   service to more than just their local machine should check the <link
+   linkend="config">main config file</link>, especially the <link
+   linkend="access-control">security-relevant</link> options. These are 
+   off by default.
+  </para>
+ </listitem>  
+
+ <listitem>
+  <para>
+  Start <application>Privoxy</application>, if the installation program has
+  not done this already (may vary according to platform). See the section
+  <link linkend="startup">Starting <application>Privoxy</application></link>.
+  </para>
+ </listitem>
+
+ <listitem>
+  <para>
+   Set your browser to use <application>Privoxy</application> as HTTP and
+   HTTPS proxy by setting the proxy configuration for address of
+   <literal>127.0.0.1</literal> and port <literal>8118</literal>.
+   (<application>Junkbuster</application> and earlier versions of
+   <application>Privoxy</application> used port 8000.) See the section <link
+   linkend="startup">Starting <application>Privoxy</application></link> below
+   for more details on this.
+  </para>
+ </listitem>  
+
+ <listitem>
+  <para>
+    Flush your browser's disk and memory caches, to remove any cached ad images.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   A default installation should provide a reasonable starting point for 
+   most. There will undoubtedly be occasions where you will want to adjust the
+   configuration, but that can be dealt with as the need arises. Little 
+   to no initial configuration is required in most cases.
+  </para>
+  <para>
+   See the <link linkend="configuration">Configuration section</link> for more
+   configuration options, and how to customize your installation.
+ <![%draft;[  You might also want to look at the <link
+   linkend="quickstart-ad-blocking">next section</link> for a quick
+   introduction to how <application>Privoxy</application> blocks ads and
+   banners.]]>
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+    If you experience ads that slipped through, innocent images that are
+    blocked, or otherwise feel the need to fine-tune
+    <application>Privoxy's</application> behaviour, take a look at the <link
+    linkend="actions-file">actions files</link>. As a quick start, you might
+    find the <link linkend="act-examples">richly commented examples</link>
+    helpful. You can also view and edit the actions files through the <ulink
+    url="http://config.privoxy.org">web-based user interface</ulink>. The
+    Appendix <quote><link linkend="actionsanat">Anatomy of an
+    Action</link></quote> has hints how to debug actions that
+    <quote>misbehave</quote>.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Please see the section <link linkend="contact">Contacting the
+   Developers</link> on how to report bugs or problems with websites or to get
+   help. 
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   Now enjoy surfing with enhanced comfort and privacy!
+  </para>
+ </listitem> 
+ </itemizedlist>
+</para>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="quickstart-ad-blocking">
+<title>Quickstart to Ad Blocking</title>
+<!--
+ NOTE:  This section is deliberately redundant for those that don't 
+ want to read the whole thing (which is getting lengthy).
+-->
+<para>
+ Ad blocking is but one of <application>Privoxy's</application>
+ array of features. Many of these features are for the technically minded advanced 
+ user. But, ad and banner blocking is surely common ground for everybody.
+</para>
+<para> 
+ This section will provide a quick summary of ad blocking so 
+ you can get up to speed quickly without having to read the more extensive
+ information provided below, though this is highly recommended.
+</para>
+<para>
+ First a bit of a warning ... blocking ads is much like blocking SPAM: the
+ more aggressive you are about it, the more likely you are to block 
+ things that were not intended. So there is a trade off here. If you want
+ extreme ad free browsing, be prepared to deal with more
+ <quote>problem</quote> sites, and to spend more time adjusting the
+ configuration to solve these unintended consequences. In short, there is 
+ not an easy way to eliminate <emphasis>all</emphasis> ads. Either take 
+ the easy way and settle for <emphasis>most</emphasis> ads blocked with the
+ default configuration, or jump in and tweak it for your personal surfing
+ habits and preferences.
+</para>
+<para>
+ Secondly, a brief explanation of <application>Privoxy's </application>
+ <quote>actions</quote>. <quote>Actions</quote> in this context, are 
+ the directives we use to tell <application>Privoxy</application> to perform
+ some task relating to HTTP transactions (i.e. web browsing). We tell
+ <application>Privoxy</application> to take some <quote>action</quote>. Each
+ action has a unique name and function. While there are many potential
+ <application>actions</application> in <application>Privoxy's</application>
+ arsenal, only a few are used for ad blocking. <link
+ linkend="actions">Actions</link>, and <link linkend="actions-file">action
+ configuration files</link>, are explained in depth below.
+</para>
+<para>
+ Actions are specified in <application>Privoxy's</application> configuration,
+ followed by one or more URLs to which the action should apply. URLs 
+ can actually be URL type <link linkend="af-patterns">patterns</link> that use
+ wildcards so they can apply potentially to a range of similar URLs. The
+ actions, together with the URL patterns are called a section.
+</para>
+<para>
+ When you connect to a website, the full URL will either match one or more
+ of the sections as defined in <application>Privoxy's</application> configuration,
+ or not. If so, then <application>Privoxy</application> will perform the
+ respective actions. If not, then nothing special happens. Futhermore, web
+ pages may contain embedded, secondary URLs that your web browser will
+ use to load additional components of the page, as it parses the
+ original page's HTML content. An ad image for instance, is just an URL
+ embedded in the page somewhere. The image itself may be on the same server,
+ or a server somewhere else on the Internet. Complex web pages will have many
+ such embedded URLs.
+</para>
+
+<para>
+ The actions we need to know about for ad blocking are:  <literal><link
+ linkend="block">block</link></literal>, <literal><link
+ linkend="handle-as-image">handle-as-image</link></literal>, and
+ <literal><link linkend="set-image-blocker">set-image-blocker</link></literal>:
+</para>
+
+<para>
+ <itemizedlist>
+  
+ <listitem>
+  <para>
+   <literal><link linkend="block">block</link></literal> - this action stops
+   any contact between your browser and any URL patterns that match this
+   action's configuration. It can be used for blocking ads, but also anything
+   that is determined to be unwanted. By itself, it simply stops any
+   communication with the remote server and sends <application>Privoxy</application>'s
+   own built-in BLOCKED page instead to let you now what has happened.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   <literal><link linkend="handle-as-image">handle-as-image</link></literal> - 
+   tells <application>Privoxy</application> to treat this URL as an image.
+   <application>Privoxy</application>'s default configuration already does this
+   for all common image types (e.g. GIF), but there are many situations where this
+   is not so easy to determine. So we'll force it in these cases. This is particularly
+   important for ad blocking, since  only if we know that it's an image of
+   some kind, can we replace it with an image of our chosing, instead of the 
+   <application>Privoxy</application> BLOCKED page (which would only result in
+   a <quote>broken image</quote> icon). There are some limitations to this
+   though. For instance, you can't just brute-force an image substituion for
+   an entire HTML page in most situations.
+  </para>
+ </listitem> 
+
+ <listitem>
+  <para>
+   <literal><link
+   linkend="set-image-blocker">set-image-blocker</link></literal> - tells
+   <application>Privoxy</application> what to display in place of an ad image that
+   has hit a block rule. For this to come into play, the URL must match a
+   <literal><link linkend="block">block</link></literal> action somewhere in the
+   configuration, <emphasis>and</emphasis>, it must also match an
+   <literal><link linkend="handle-as-image">handle-as-image</link></literal> action.
+  </para>
+  <para>
+   The configuration options on what to display instead of the ad are:
+  </para>
+  <simplelist>
+   <member>
+    &nbsp;&nbsp;&nbsp;<emphasis>pattern</emphasis> - a checkboard pattern, so that an ad 
+    replacement is obvious. This is the default.
+   </member>
+  </simplelist>
+  <simplelist>
+   <member>
+    &nbsp;&nbsp;&nbsp;<emphasis>blank</emphasis> - A very small empty GIF image is displayed.
+    This is the so-called <quote>invisible</quote> configuration option.
+   </member>
+  </simplelist>
+  <simplelist>
+   <member>
+    &nbsp;&nbsp;&nbsp;<emphasis>http://&lt;URL&gt;</emphasis> - A redirect to any image anywhere
+    of the user's choosing (advanced usage).
+   </member>
+  </simplelist>
+  </listitem> 
+
+</itemizedlist>
+</para>
+
+<para>
+ The quickest way to adjust any of these settings is with your browser through
+ the special <application>Privoxy</application> editor at <ulink
+ url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+ (shortcut: <ulink url="http://p.p/">http://p.p/show-status</ulink>). This 
+ is an internal page, and does not require Internet access. Select the
+ appropriate <quote>actions</quote> file, and click
+ <quote><guibutton>Edit</guibutton></quote>. It is best to put personal or
+ local preferences in <filename>user.action</filename> since this is not
+ meant to be overwritten during upgrades, and will over-ride the settings in
+ other files. Here you can insert new <quote>actions</quote>, and URLs for ad
+ blocking or other purposes, and make other adjustments to the configuration.
+ <application>Privoxy</application> will detect these changes automatically.
+</para>
+
+<para>
+ A quick and simple step by step example:
+</para>
+
+<para>
+ <itemizedlist>
+
+  <listitem>
+   <para>
+     Right click on the ad image to be blocked, then select 
+     <quote><guimenuitem>Copy Link Location</guimenuitem></quote> from the
+     pop-up menu. 
+   </para>
+  </listitem> 
+  <listitem>
+   <para>
+    Set your browser to 
+    <ulink
+ url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+   </para>
+  </listitem> 
+  <listitem>
+   <para>
+    Find <filename>user.action</filename> in the top section, and click 
+    on <quote><guibutton>Edit</guibutton></quote>:
+   </para>
+
+ <!-- image of editor and actions files selections -->
+ <para>
+  <figure pgwide="0" float="0"><title>Actions Files in Use</title>
+   <mediaobject>
+     <imageobject>
+      <imagedata  fileref="../images/files-in-use.jpg" format="jpg">
+       </imageobject> 
+       <textobject>
+        <phrase>[ Screenshot of Actions Files in Use ]</phrase>
+      </textobject>
+   </mediaobject>
+  </figure>
+ </para>
+ </listitem> 
+ <listitem>
+  <para>
+   You should have a section with only
+   <literal><link linkend="block">block</link></literal> listed under 
+   <quote>Actions:</quote>.
+   If not, click a <quote><guibutton>Insert new section below</guibutton></quote>
+   button, and in the new section that just appeared, click the 
+   <guibutton>Edit</guibutton> button right under the word <quote>Actions:</quote>.
+   This will bring up a list of all actions. Find
+   <literal><link linkend="block">block</link></literal> near the top, and click
+   in the <quote>Enabled</quote> column, then <quote><guibutton>Submit</guibutton></quote>
+   just below the list.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Now, in the <literal><link linkend="block">block</link></literal> actions section,
+   click the <quote><guibutton>Add</guibutton></quote> button, and paste the URL the
+   browser got from <quote><guimenuitem>Copy Link Location</guimenuitem></quote>.
+   Remove the <literal>http://</literal> at the beginning of the URL. Then, click
+   <quote><guibutton>Submit</guibutton></quote> (or
+   <quote><guibutton>OK</guibutton></quote> if in a pop-up window).
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Now go back to the original page, and press <keycap>SHIFT-Reload</keycap>
+   (or flush all browser caches). The image should be gone now.
+  </para>
+ </listitem> 
+ </itemizedlist>
+</para>
+
+<para>
+ This is a very crude and simple example. There might be good reasons to use a 
+ wildcard pattern match to include potentially similar images from the same
+ site. For a more extensive explanation of <quote>patterns</quote>, and 
+ the entire actions concept, see <link linkend="actions-file">the Actions
+ section</link>.
+</para>
+
+<para>
+ For advanced users who want to hand edit their config files, you might want
+ to now go to the <link linkend="act-examples">Actions Files Tutorial</link>.
+ The ideas explained thererin also apply to the web-based editor.
+</para>
+
+</sect2>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="startup">
+<title>Starting <application>Privoxy</application></title>
+<para>
+ Before launching <application>Privoxy</application> for the first time, you
+ will want to configure your browser(s) to use
+ <application>Privoxy</application> as a HTTP and HTTPS proxy. The default is
+ 127.0.0.1 (or localhost) for the proxy address, and port 8118 (earlier versions
+ used port 8000). This is the one configuration step that must be done!
+</para>
+
+ <!-- image of Mozilla Proxy configuration -->
+ <para>
+  <figure pgwide="0" float="0"><title>Proxy Configuration (Mozilla)</title>
+   <mediaobject>
+     <imageobject>
+      <imagedata  fileref="../images/proxy_setup.jpg" format="jpg">
+       </imageobject> 
+       <textobject>
+        <phrase>[ Screenshot of Mozilla Proxy Configuration ]</phrase>
+      </textobject>
+   </mediaobject>
+  </figure>
+ </para>
+<para> 
+ With <application>Netscape</application> (and
+ <application>Mozilla</application>), this can be set under:
+</para>
+<literallayout>
+<!-- Mix ascii and gui art, something for everybody -->
+<!-- spacing on this is tricky -->
+ <guibutton>Edit</guibutton>
+   |_   
+         <guibutton>Preferences</guibutton>
+                |_       
+                        <guibutton>Advanced</guibutton>
+                              |_     
+                                    <guibutton>Proxies</guibutton>
+                                         |_       
+                                                <guibutton>HTTP Proxy</guibutton>
+</literallayout>
+
+<para>
+ For <application>Internet Explorer</application>: 
+</para>
+
+<literallayout>
+<!-- Mix ascii and gui art, something for everybody -->
+<!-- spacing on this is tricky -->
+ <guibutton>Tools</guibutton>
+     |_   
+         <guibutton>Internet Properties</guibutton>
+                            |_       
+                                      <guibutton>Connections</guibutton>
+                                               |_     
+                                                            <guibutton>LAN Settings</guibutton>
+</literallayout>
+
+<para>
+ Then, check <quote>Use Proxy</quote> and fill in the appropriate info
+ (Address: 127.0.0.1, Port: 8118). Include HTTPS (SSL), if you want HTTPS
+ proxy support too. 
+</para>
+
+<para>
+ After doing this, flush your browser's disk and memory caches to force a
+ re-reading of all pages and to get rid of any ads that may be cached. You 
+ are now ready to start enjoying the benefits of using
+ <application>Privoxy</application>!
+</para>
+
+<para>
+ <application>Privoxy</application> is typically started by specifying the
+ main configuration file to be used on the command line. If no configuration
+ file is specified on the command line, <application>Privoxy</application>
+ will look for a file named <filename>config</filename> in the current
+ directory. Except on Win32 where it will try <filename>config.txt</filename>.
+</para>
+
+<sect2 id="start-redhat">
+<title>RedHat and Conectiva</title>
+<para>
+ We use a script. Note that RedHat does not start Privoxy upon booting per
+ default. It will use the file <filename>/etc/privoxy/config</filename> as
+ its main configuration file.
+</para>
+<para>
+ <screen>
+ # /etc/rc.d/init.d/privoxy start
+</screen>
+</para>
+</sect2>
+
+<sect2 id="start-debian">
+<title>Debian</title>
+<para>
+ We use a script. Note that Debian starts Privoxy upon booting per
+ default.  It will use the file
+ <filename>/etc/privoxy/config</filename> as its main configuration
+ file.
+</para>
+<para>
+ <screen>
+ # /etc/init.d/privoxy start
+</screen>
+</para>
+</sect2>
+
+<sect2 id="start-suse">
+<title>SuSE</title>
+<para>
+We use a script. It will use the file <filename>/etc/privoxy/config</filename>
+as its main configuration file. Note that SuSE starts Privoxy upon booting
+your PC.
+</para>
+<para>
+ <screen>
+ # rcprivoxy start
+</screen>
+</para>
+</sect2>
+
+<sect2 id="start-windows">
+<title>Windows</title>
+<para>
+Click on the Privoxy Icon to start Privoxy. If no configuration file is
+ specified on the command line, <application>Privoxy</application> will look
+ for a file named <filename>config.txt</filename>. Note that Windows will
+ automatically start Privoxy upon booting you PC.
+</para>
+</sect2>
+
+<sect2 id="start-unices">
+<title>Solaris, NetBSD, FreeBSD, HP-UX and others</title>
+<para>
+Example Unix startup command:
+</para>
+<para>
+ <screen>
+ # /usr/sbin/privoxy /etc/privoxy/config
+</screen>
+</para>
+</sect2>
+
+<sect2 id="start-os2">
+<title>OS/2</title>
+<para>
+FIXME.
+</para>
+</sect2>
+
+<sect2 id="start-macosx">
+<title>MAX OSX</title>
+<para>
+FIXME.
+</para>
+</sect2>
+
+
+<sect2 id="start-amigaos">
+<title>AmigaOS</title>
+<para>
+FIXME.
+</para>
+</sect2>
+
+<!--
+
+<para>
+ See the section <link linkend="cmdoptions">Command line options</link> for
+ furher info.
+</para>
+
+must find a better place for this paragraph
+
+<para>
+ The included default configuration files should give a reasonable starting
+ point. Most of the per site configuration is done in the
+ <ulink url="actions-file.html"><quote>actions</quote></ulink> files. These are
+ where various cookie actions are defined, ad and banner blocking, and other
+ aspects of <application>Privoxy</application> configuration. There are several
+ such files included, with varying levels of aggressiveness. 
+</para>
+
+<para>
+ You will probably want to keep an eye out for sites for which you may prefer
+ persistent cookies, and add these to your actions configuration as needed. By
+ default, most of these will be accepted only during the current browser
+ session (aka <quote>session cookies</quote>), unless you add them to the
+ configuration. If you want the browser to handle this instead, you will need
+ to edit <filename>user.action</filename> (or through the web based interface)
+ and disable this feature. If you use more than one browser, it would make
+ more sense to let <application>Privoxy</application> handle this. In which
+ case, the browser(s) should be set to accept all cookies.
+</para>
+
+<para>
+ Another feature where you will probably want to define exceptions for trusted
+ sites is the popup-killing (through the <ulink
+ url="actions-file.html#KILL-POPUPS"><quote>+kill-popups</quote></ulink> and
+ <ulink
+ url="actions-file.html#FILTER-POPUPS"><quote>+filter{popups}</quote></ulink>
+ actions), because your favorite shopping, banking, or leisure site may need
+ popups (explained below). 
+</para>
+
+<para>
+ <application>Privoxy</application> is HTTP/1.1 compliant,  but not all of
+ the optional 1.1 features are as yet supported. In the unlikely event that
+ you experience inexplicable problems with browsers that use HTTP/1.1 per default
+ (like <application>Mozilla</application> or recent versions of I.E.), you might
+ try to force HTTP/1.0 compatibility. For Mozilla, look under <literal>Edit -&gt;
+ Preferences -&gt; Debug -&gt; Networking</literal>.
+ Alternatively, set the <quote>+downgrade-http-version</quote> config option in
+ <filename>default.action</filename> which will downgrade your browser's HTTP
+ requests from HTTP/1.1 to HTTP/1.0 before processing them.
+</para>
+
+<para>
+ After running <application>Privoxy</application> for a while, you can 
+ start to fine tune the configuration to suit your personal, or site, 
+ preferences and requirements. There are many, many aspects that can 
+ be customized. <quote>Actions</quote> 
+ can be adjusted by pointing your browser to 
+ <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>
+ (shortcut: <ulink url="http://p.p/">http://p.p/</ulink>), 
+ and then follow the link to <quote>View &#38; Change the Current Configuration</quote>. 
+ (This is an internal page and does not require Internet access.)
+</para>
+
+<para>
+ In fact, various aspects of <application>Privoxy</application>
+ configuration can be viewed from this page, including 
+ current configuration parameters, source code version numbers, 
+ the browser's request headers, and <quote>actions</quote> that apply 
+ to a given URL. In addition to the actions file 
+ editor mentioned above, <application>Privoxy</application> can also 
+ be turned <quote>on</quote> and <quote>off</quote> (toggled) from this page.
+</para>
+
+<para>
+ If you encounter problems, try loading the page without
+ <application>Privoxy</application>. If that helps, enter the URL where
+ you have the problems into <ulink url="http://p.p/show-url-info">the browser
+ based rule tracing utility</ulink>. See which rules apply and why, and
+ then try turning them off for that site one after the other, until the problem
+ is gone. When you have found the culprit, you might want to turn the rest on
+ again.
+</para>
+
+<para>
+ If the above paragraph sounds gibberish to you, you might want to <ulink
+ url="actions-file.html#ACTIONSFILE">read more about the actions concept</ulink>
+ or even dive deep into the <ulink url="appendix.html#ACTIONSANAT">Appendix
+ on actions</ulink>.
+</para>
+
+<para>
+ If you can't get rid of the problem at all, think you've found a bug in
+ Privoxy, want to propose a new feature or smarter rules, please see the 
+ section <ulink url="contact.html"><quote>Contacting the
+ Developers</quote></ulink> below. 
+</para>
+
+-->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="cmdoptions">
+<title>Command Line Options</title>
+<para>
+ <application>Privoxy</application> may be invoked with the following
+ command-line options:
+</para>
+
+<para>
+ <itemizedlist>
+
+ <listitem>
+  <para>
+    <emphasis>--version</emphasis>
+  </para>
+  <para>
+     Print version info and exit. Unix only.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+    <emphasis>--help</emphasis>
+  </para>
+  <para>
+   Print short usage info and exit. Unix only.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   <emphasis>--no-daemon</emphasis>
+  </para>
+  <para>
+   Don't become a daemon, i.e. don't fork and become process group
+   leader, and don't detach from controlling tty. Unix only.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   <emphasis>--pidfile FILE</emphasis>
+  
+  </para>
+  <para>
+   On startup, write the process ID to <emphasis>FILE</emphasis>. Delete the
+   <emphasis>FILE</emphasis> on exit. Failure to create or delete the
+   <emphasis>FILE</emphasis> is non-fatal. If no <emphasis>FILE</emphasis>
+   option is given, no PID file will be used. Unix only.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   <emphasis>--user USER[.GROUP]</emphasis>
+  
+  </para>
+  <para>
+   After (optionally) writing the PID file, assume the user  ID  of
+   <emphasis>USER</emphasis>, and if included the GID of GROUP.  Exit if the
+   privileges are not sufficient to do so. Unix only.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+    <emphasis>configfile</emphasis>
+  </para>
+  <para>
+    If no <emphasis>configfile</emphasis> is included on the command line, 
+    <application>Privoxy</application> will look for a file named 
+    <quote>config</quote> in the current directory (except on Win32 
+    where it will look for <quote>config.txt</quote> instead). Specify 
+    full path to avoid confusion. If no config file is found, 
+    <application>Privoxy</application> will fail to start.
+  </para>
+ </listitem> 
+
+ </itemizedlist>
+</para>
+
+</sect2>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="configuration"><title><application>Privoxy</application> Configuration</title>
+ <para>
+  All <application>Privoxy</application> configuration is stored  
+  in text files. These files can be edited with a text editor.
+  Many important aspects of <application>Privoxy</application> can 
+  also be controlled easily with a web browser.
+ </para>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2>
+<title>Controlling <application>Privoxy</application> with Your Web Browser</title>
+<para>
+ <application>Privoxy</application>'s user interface can be reached through the special 
+ URL <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>
+ (shortcut: <ulink url="http://p.p/">http://p.p/</ulink>), 
+ which is a built-in page and works without Internet access.
+ You will see the following section:
+
+</para>
+
+<!-- Needs to be put in a table and colorized  -->
+<screen>
+ <msgtext>
+ <bridgehead renderas="sect2">&nbsp;&nbsp;&nbsp;&nbsp;Privoxy Menu</bridgehead>
+
+ <simplelist>
+ <member>
+  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&squf;&nbsp;&nbsp;<ulink url="http://config.privoxy.org/show-status">View & change the current configuration</ulink>
+ </member>
+ <member>
+  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&squf;&nbsp;&nbsp;<ulink url="http://config.privoxy.org/show-version">View the source code version numbers</ulink>
+ </member>
+ <member>
+  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&squf;&nbsp;&nbsp;<ulink url="http://config.privoxy.org/show-request">View the request headers.</ulink>
+ </member>
+ <member>
+  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&squf;&nbsp;&nbsp;<ulink url="http://config.privoxy.org/show-url-info">Look up which actions apply to a URL and why</ulink>
+ </member>
+ <member>
+  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&squf;&nbsp;&nbsp;<ulink url="http://config.privoxy.org/toggle">Toggle Privoxy on or off</ulink>
+ </member>
+ </simplelist>
+ </msgtext>
+</screen>
+
+
+<para>
+ This should be self-explanatory. Note the first item leads to an editor for the
+ <link linkend="actions-file">actions files</link>, which is where the ad, banner,
+ cookie, and URL blocking magic is configured as well as other advanced features of
+ <application>Privoxy</application>. This is an easy way to adjust various
+ aspects of <application>Privoxy</application> configuration. The actions
+ file, and other configuration files, are explained in detail below. 
+</para>
+
+<para>
+ <quote>Toggle Privoxy On or Off</quote> is handy for sites that might 
+ have problems with your current actions and filters. You can in fact use
+ it as a test to see whether it is <application>Privoxy</application> 
+ causing the problem or not. <application>Privoxy</application> continues 
+ to run as a proxy in this case, but all manipulation is disabled, i.e.
+ <application>Privoxy</application> acts like a normal forwarding proxy. There
+ is even a toggle <link linkend="bookmarklets">Bookmarklet</link> offered, so
+ that you can toggle <application>Privoxy</application> with one click from
+ your browser.
+</para>
+
+</sect2>
+
+<!--  ~  End section  ~  -->
+
+
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="confoverview">
+<title>Configuration Files Overview</title>
+<para>
+ For Unix, *BSD and Linux, all configuration files are located in
+ <filename>/etc/privoxy/</filename> by default. For MS Windows, OS/2, and
+ AmigaOS these are all in the same directory as the 
+ <application>Privoxy</application> executable. <![%p-not-stable;[ The name
+ and number of configuration files has changed from previous versions, and is
+ subject to change as development progresses.]]>
+</para>
+
+<para>
+ The installed defaults provide a reasonable starting point, though 
+ some settings may be aggressive by some standards. For the time being, the
+ principle configuration files are:
+</para>
+
+<para>
+ <itemizedlist>
+
+  <listitem>
+   <para>
+     The <link linkend="config">main configuration file</link> is named <filename>config</filename>
+     on Linux, Unix, BSD, OS/2, and AmigaOS and <filename>config.txt</filename>
+     on Windows. This is a required file.
+   </para>
+  </listitem> 
+
+  <listitem>
+   <para>
+    <filename>default.action</filename> (the main <link linkend="actions-file">actions file</link>)
+    is used to define which <quote>actions</quote> relating to banner-blocking, images, pop-ups,
+    content modification, cookie handling etc should be applied by default. It also defines many
+    exceptions (both positive and negative) from this default set of actions that enable 
+    <application>Privoxy</application> to selectively eliminate the junk, and only the junk, on
+    as many websites as possible.
+   </para>
+   <para>
+    Multiple actions files may be defined in <filename>config</filename>. These 
+    are processed in the order they are defined. Local customizations and locally 
+    preferred exceptions to the default policies  as defined in
+    <filename>default.action</filename> (which you will most probably want
+    to define sooner or later) are probably best applied in
+    <filename>user.action</filename>, where you can preserve them across
+    upgrades. <filename>standard.action</filename> is for
+    <application>Privoxy's</application> internal use.
+   </para>
+   <para>    
+    There is also a web based editor that can be accessed from
+    <ulink
+    url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+    (Shortcut: <ulink
+    url="http://p.p/show-status">http://p.p/show-status</ulink>) for the
+    various actions files. 
+   </para>
+  </listitem> 
+
+  <listitem>
+   <para>
+    <filename>default.filter</filename> (the <link linkend="filter-file">filter
+    file</link>) can be used to re-write the raw page content, including
+    viewable text as well as embedded HTML and JavaScript, and whatever else
+    lurks on any given web page. The filtering jobs are only pre-defined here;
+    whether to apply them or not is up to the actions files.
+   </para>
+  </listitem> 
+
+ </itemizedlist>
+</para>
+
+<para>
+ All files use the <quote><literal>#</literal></quote> character to denote a
+ comment (the rest of the line will be ignored) and understand line continuation
+ through placing a backslash ("<literal>\</literal>") as the very last character
+ in a line. If the <literal>#</literal> is preceded by a backslash, it looses
+ its special function. Placing a <literal>#</literal> in front of an otherwise
+ valid configuration line to prevent it from being interpreted is called "commenting
+ out" that line.
+</para>
+
+<para>
+ The actions files and <filename>default.filter</filename> 
+ can use Perl style <link linkend="regex">regular expressions</link> for
+ maximum flexibility. 
+</para>
+
+<para>
+ After making any changes, there is no need to restart
+ <application>Privoxy</application> in order for the changes to take
+ effect. <application>Privoxy</application> detects such changes 
+ automatically. Note, however, that it may take one or two additional
+ requests for the change to take effect. When changing the listening address
+ of <application>Privoxy</application>, these <quote>wake up</quote> requests
+ must obviously be sent to the <emphasis>old</emphasis> listening address.
+</para>
+
+<![%p-not-stable;[
+<para>
+ While under development, the configuration content is subject to change. 
+ The below documentation may not be accurate by the time you read this. 
+ Also, what constitutes a <quote>default</quote> setting, may change, so 
+ please check all your configuration files on important issues.
+</para>
+]]>
+
+</sect2>
+</sect1>
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+
+<sect1 id="config">
+<title>The Main Configuration File</title>
+
+<para>
+ Again, the main configuration file is named <filename>config</filename> on
+ Linux/Unix/BSD and OS/2, and <filename>config.txt</filename> on Windows.
+ Configuration lines consist of an initial keyword followed by a list of
+ values, all separated by whitespace (any number of spaces or tabs). For
+ example:
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>confdir /etc/privoxy</emphasis></literallayout>
+  </msgtext>
+ </literal> 
+</para>
+
+<para>
+ Assigns the value <literal>/etc/privoxy</literal> to the option
+ <literal>confdir</literal> and thus indicates that the configuration
+ directory is named <quote>/etc/privoxy/</quote>.
+</para>
+
+<para>
+ All options in the config file except for <literal>confdir</literal> and
+ <literal>logdir</literal> are optional. Watch out in the below description
+ for what happens if you leave them unset.
+</para>
+
+<para>
+ The main config file controls all aspects of <application>Privoxy</application>'s
+ operation that are not location dependent (i.e. they apply universally, no matter
+ where you may be surfing).
+</para>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="conf-log-loc">
+<title>Configuration and Log File Locations</title>
+
+<para>
+ <application>Privoxy</application> can (and normally does) use a number of
+ other files for additional configuration, help and logging.
+ This section of the configuration file tells <application>Privoxy</application>
+ where to find those other files. 
+</para>
+
+<para>
+ The user running Privoxy, must have read permission for all 
+ configuration files, and write permission to any files that would 
+ be modified, such as log files.
+</para>
+
+<sect3 renderas="sect4" id="confdir"><title>confdir</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>The directory where the other configuration files are located</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>Path name</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>/etc/privoxy (Unix) <emphasis>or</emphasis> <application>Privoxy</application> installation dir (Windows) </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para><emphasis>Mandatory</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    No trailing <quote><literal>/</literal></quote>, please
+   </para>
+   <para>
+    When development goes modular and multi-user, the blocker, filter, and
+    per-user config will be stored in subdirectories of <quote>confdir</quote>.
+    For now, the configuration directory structure is flat, except for 
+    <filename>confdir/templates</filename>, where the HTML templates for CGI 
+    output reside (e.g. <application>Privoxy's</application> 404 error page). 
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<sect3 renderas="sect4" id="logdir"><title>logdir</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    The directory where all logging takes place (i.e. where <filename>logfile</filename> and 
+    <filename>jarfile</filename> are located) 
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>Path name</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>/var/log/privoxy (Unix) <emphasis>or</emphasis> <application>Privoxy</application> installation dir (Windows) </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para><emphasis>Mandatory</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    No trailing <quote><literal>/</literal></quote>, please
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="actionsfile"><title>
+actionsfile
+</title>
+<anchor id="default.action">
+<anchor id="standard.action">
+<anchor id="user.action">
+<!-- Note: slightly modified this section 04/28/02, hal. See NOTE. -->
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    The <link linkend="actions-file">actions file(s)</link> to use
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>File name, relative to <literal>confdir</literal>, without the <literal>.action</literal> suffix</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default values:</term>
+  <listitem>
+   <simplelist>
+    <member>
+     <msgtext><literallayout>  standard     # Internal purposes, no editing recommended</literallayout></msgtext>
+    </member>
+    <member>
+     <msgtext><literallayout>  default      # Main actions file</literallayout></msgtext>
+    </member>
+    <member>
+     <msgtext><literallayout>  user         # User customizations</literallayout></msgtext>
+    </member>
+   </simplelist>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    No actions are taken at all. Simple neutral proxying. 
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    Multiple <literal>actionsfile</literal> lines are permitted, and are in fact recommended!
+   </para>
+   <para> 
+    The default values include standard.action, which is used for internal
+    purposes and should be loaded, default.action, which is the
+    <quote>main</quote> actions file maintained by the developers, and
+    <filename>user.action</filename>, where you can make your personal additions.
+   </para>
+   <para> 
+    Actions files are where all the per site and per URL configuration is done for 
+    ad blocking, cookie management, privacy considerations, etc.
+    There is no point in using <application>Privoxy</application> without at 
+    least one actions file.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="filterfile"><title>filterfile</title>
+<anchor id="default.filter">
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    The <link linkend="filter-file">filter file</link> to use
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>File name, relative to <literal>confdir</literal></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>default.filter (Unix) <emphasis>or</emphasis> default.filter.txt (Windows)</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    No textual content filtering takes place, i.e. all
+    <literal>+<link linkend="filter">filter</link>{<replaceable class="parameter">name</replaceable>}</literal>
+    actions in the actions files are turned neutral.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The <link linkend="filter-file">filter file</link> contains content modification
+    rules that use <link linkend="regex">regular expressions</link>. These rules permit
+    powerful changes on the content of Web pages, e.g., you could disable your favorite
+    JavaScript annoyances, re-write the actual displayed text, or just have some
+    fun replacing <quote>Microsoft</quote> with <quote>MicroSuck</quote> wherever
+    it appears on a Web page.
+   </para>
+   <para>
+    The
+    <literal>+<link linkend="filter">filter</link>{<replaceable class="parameter">name</replaceable>}</literal>
+    actions rely on the relevant filter (<replaceable class="parameter">name</replaceable>)
+    to be defined in the filter file!
+   </para>
+   <para>
+    A pre-defined filter file called <filename>default.filter</filename> that contains
+    a bunch of handy filters for common problems is included in the distribution.
+    See the section on the <literal><link linkend="filter">filter</link></literal>
+    action for a list.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="logfile"><title>logfile</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    The log file to use
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>File name, relative to <literal>logdir</literal></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>logfile (Unix) <emphasis>or</emphasis> privoxy.log (Windows)</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    No log file is used, all log messages go to the console (<literal>stderr</literal>).
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The windows version will additionally log to the console.
+   </para>
+   <para>
+    The logfile is where all logging and error messages are written. The level
+    of detail and number of messages are set with the <literal>debug</literal>
+    option (see below). The logfile can be useful for tracking down a problem with
+    <application>Privoxy</application> (e.g., it's not blocking an ad you
+    think it should block) but in most cases you probably will never look at it.
+   </para>
+   <para>
+    Your logfile will grow indefinitely, and you will probably want to
+    periodically remove it.  On Unix systems, you can do this with a cron job
+    (see <quote>man cron</quote>). For Red Hat, a <command>logrotate</command> 
+    script has been included.
+   </para> 
+   <para>
+    On SuSE Linux systems, you can place a line like <quote>/var/log/privoxy.*
+    +1024k 644 nobody.nogroup</quote> in <filename>/etc/logfiles</filename>, with
+    the effect that cron.daily will automatically archive, gzip, and empty the
+    log, when it exceeds 1M size.
+   </para>
+   <para>
+    Any log files must be writable by whatever user <application>Privoxy</application>
+    is being run as (default on UNIX, user id is <quote>privoxy</quote>).
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="jarfile"><title>jarfile</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    The file to store intercepted cookies in
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>File name, relative to <literal>logdir</literal></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>jarfile (Unix) <emphasis>or</emphasis> privoxy.jar (Windows)</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Intercepted cookies are not stored at all.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The jarfile may grow to ridiculous sizes over time.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="trustfile"><title>trustfile</title>
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    The trust file to use
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>File name, relative to <literal>confdir</literal></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset (commented out)</emphasis>. When activated: trust (Unix) <emphasis>or</emphasis> trust.txt (Windows)</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    The whole trust mechanism is turned off.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The trust mechanism is an experimental feature for building white-lists and should
+    be used with care. It is <emphasis>NOT</emphasis> recommended for the casual user.
+   </para>
+   <para>
+    If you specify a trust file, <application>Privoxy</application> will only allow
+    access to sites that are named in the trustfile. 
+    You can also mark sites as trusted referrers (with <literal>+</literal>), with
+    the effect that access to untrusted sites will be granted, if a link from a
+    trusted referrer was used.
+    The link target will then be added to the <quote>trustfile</quote>.
+    Possible applications include limiting Internet access for children.
+   </para>
+   <para>
+    If you use <literal>+</literal> operator in the trust file, it may grow considerably over time.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+</sect2>
+
+<!--  ~  End section  ~  -->
+
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="local-set-up">
+<title>Local Set-up Documentation</title>
+
+  <para>
+    If you intend to operate <application>Privoxy</application> for more users
+    than just yourself, it might be a good idea to let them know how to reach
+    you, what you block and why you do that, your policies, etc.
+   </para>
+
+<sect3 renderas="sect4" id="user-manual"><title>user-manual</title>
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Location of the <application>Privoxy</application> User Manual.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>A fully qualified URI</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    <ulink url="http://www.privoxy.org/user-manual/">http://www.privoxy.org/<replaceable class="parameter">version</replaceable>/user-manual/</ulink>
+    will be used, where <replaceable class="parameter">version</replaceable> is the <application>Privoxy</application> version.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+    <para>
+    The User Manual URI is used for help links from some of the internal CGI pages. 
+    The manual itself is normally packaged with the binary distributions, so you probably want
+    to set this to a locally installed copy. For multi-user setups, you could provide a copy on
+    a local webserver for all your users and use the corresponding URL here.
+   </para>
+   <para>
+    Examples:
+   </para>
+  <para>
+   Unix, in local filesystem:
+  </para>
+  <para>
+   <screen>user-manual&nbsp;&nbsp;file:///usr/share/doc/privoxy-&p-version;/user-manual/</screen>
+  </para>
+  <para>
+   Any platform, on local webserver (called <quote>local-webserver</quote>):
+  </para>
+  <para>
+   <screen>user-manual&nbsp;&nbsp;http://local-webserver/privoxy-user-manual/</screen>
+  </para>
+  <warning>
+   <para>
+     If set, this option should be <emphasis>the first option in the config file</emphasis>, because
+     it is used while the config file is being read.
+   </para>
+  </warning>     
+ </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="trust-info-url"><title>trust-info-url</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    A URL to be displayed in the error page that users will see if access to an untrusted page is denied.    
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>URL</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>Two example URL are provided</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    No links are displayed on the "untrusted" error page.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The value of this option only matters if the experimental trust mechanism has been
+    activated. (See <link linkend="trustfile"><emphasis>trustfile</emphasis></link> above.)
+   </para>
+   <para>
+    If you use the trust mechanism, it is a good idea to write up some on-line
+    documentation about your trust policy and to specify the URL(s) here.
+    Use multiple times for multiple URLs.
+   </para>
+   <para>
+    The URL(s) should be added to the trustfile as well, so users don't end up
+    locked out from the information on why they were locked out in the first place!
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="admin-address"><title>admin-address</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    An email address to reach the proxy administrator.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>Email address</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    No email address is displayed on error pages and the CGI user interface.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+    <para>
+    If both <literal>admin-address</literal> and <literal>proxy-info-url</literal>
+    are unset, the whole "Local Privoxy Support" box on all generated pages will
+    not be shown.
+   </para>  
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="proxy-info-url"><title>proxy-info-url</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    A URL to documentation about the local <application>Privoxy</application> setup,
+    configuration or policies.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>URL</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    No link to local documentation is displayed on error pages and the CGI user interface.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    If both <literal>admin-address</literal> and <literal>proxy-info-url</literal>
+    are unset, the whole "Local Privoxy Support" box on all generated pages will
+    not be shown.
+   </para>  
+   <para>
+    This URL shouldn't be blocked ;-)
+   </para> 
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+</sect2>
+<!--  ~  End section  ~  -->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="debugging">
+<title>Debugging</title>
+
+ <para>
+  These options are mainly useful when tracing a problem.
+  Note that you might also want to invoke
+  <application>Privoxy</application> with the <literal>--no-daemon</literal>
+  command line option when debugging.
+ </para>
+
+<sect3 renderas="sect4" id="debug"><title>debug</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Key values that determine what information gets logged to the 
+    <link linkend="logfile"><emphasis>logfile</emphasis></link>.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>Integer values</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>12289 (i.e.: URLs plus informational and warning messages)</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Nothing gets logged.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The available debug levels are:
+   </para>
+   <para>
+    <programlisting>
+  debug         1 # show each GET/POST/CONNECT request
+  debug         2 # show each connection status
+  debug         4 # show I/O status
+  debug         8 # show header parsing
+  debug        16 # log all data into the logfile
+  debug        32 # debug force feature
+  debug        64 # debug regular expression filter 
+  debug       128 # debug fast redirects
+  debug       256 # debug GIF de-animation
+  debug       512 # Common Log Format
+  debug      1024 # debug kill pop-ups
+  debug      4096 # Startup banner and warnings.
+  debug      8192 # Non-fatal errors
+</programlisting>
+   </para>
+   <para>
+    To select multiple debug levels, you can either add them or use
+    multiple <literal>debug</literal> lines.
+   </para>
+   <para>
+    A debug level of 1 is informative because it will show you each request
+    as it happens. <emphasis>1, 4096 and 8192 are highly recommended</emphasis>
+    so that you will notice when things go wrong. The other levels are probably
+    only of interest if you are hunting down a specific problem. They can produce
+    a hell of an output (especially 16).
+    <!-- LOL -->
+   </para>
+   <para>
+    The reporting of <emphasis>fatal</emphasis> errors (i.e. ones which crash 
+    <application>Privoxy</application>) is always on and cannot be disabled.
+   </para>
+   <para>
+    If you want to use CLF (Common Log Format), you should set <quote>debug
+    512</quote> <emphasis>ONLY</emphasis> and not enable anything else.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="single-threaded"><title>single-threaded</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Whether to run only one server thread
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para><emphasis>None</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Multi-threaded (or, where unavailable: forked) operation, i.e. the ability to
+    serve multiple requests simultaneously.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This option is only there for debug purposes and you should never
+    need to use it. <emphasis>It will drastically reduce performance.</emphasis>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+</sect2>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="access-control">
+<title>Access Control and Security</title>
+
+ <para>
+  This section of the config file controls the security-relevant aspects
+  of <application>Privoxy</application>'s configuration.
+ </para>
+
+<sect3 renderas="sect4" id="listen-address"><title>listen-address</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    The IP address and TCP port on which <application>Privoxy</application> will
+    listen for client requests.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>[<replaceable class="parameter">IP-Address</replaceable>]:<replaceable class="parameter">Port</replaceable></para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>127.0.0.1:8118</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Bind to 127.0.0.1 (localhost), port 8118. This is suitable and recommended for
+    home users who run <application>Privoxy</application> on the same machine as
+    their browser.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    You will need to configure your browser(s) to this proxy address and port.
+   </para>
+   <para>
+    If you already have another service running on port 8118, or if you want to
+    serve requests from other machines (e.g. on your local network) as well, you
+    will need to override the default.
+   </para>
+   <para>
+    If you leave out the IP address, <application>Privoxy</application> will
+    bind to all interfaces (addresses) on your machine and may become reachable
+    from the Internet. In that case, consider using <link
+    linkend="acls">access control lists</link> (ACL's, see below), and/or
+    a firewall.
+   </para>
+   <para>
+    If you open <application>Privoxy</application> to untrusted users, you will
+    also want to turn off the <literal><link
+    linkend="enable-edit-actions">enable-edit-actions</link></literal> and
+    <literal><link linkend="enable-remote-toggle">enable-remote-toggle</link></literal>
+    options!
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Example:</term>
+  <listitem>
+   <para>
+     Suppose you are running <application>Privoxy</application> on
+     a machine which has the address 192.168.0.1 on your local private network
+     (192.168.0.0) and has another outside connection with a different address.
+     You want it to serve requests from inside only:
+   </para>
+   <para>
+    <programlisting>
+  listen-address  192.168.0.1:8118
+</programlisting>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="toggle"><title>toggle</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Initial state of "toggle" status
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>1 or 0</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>1</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Act as if toggled on
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    If set to 0, <application>Privoxy</application> will start in
+    <quote>toggled off</quote> mode, i.e. behave like a normal, content-neutral
+    proxy where all ad blocking, filtering, etc are disabled. See
+    <literal>enable-remote-toggle</literal> below. This is not really useful
+    anymore, since toggling is much easier via <ulink
+    url="http://config.privoxy.org/toggle">the web interface</ulink> than via
+    editing the <filename>conf</filename> file.
+   </para>
+   <para>
+    The windows version will only display the toggle icon in the system tray
+    if this option is present.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<sect3 renderas="sect4" id="enable-remote-toggle"><title>enable-remote-toggle</title>
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Whether or not the <ulink url="http://config.privoxy.org/toggle">web-based toggle
+    feature</ulink> may be used
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>0 or 1</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>1</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    The web-based toggle feature is disabled.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    When toggled off, <application>Privoxy</application> acts like a normal,
+    content-neutral proxy, i.e. it acts as if none of the actions applied to
+    any URL.
+   </para>
+   <para>
+    For the time being, access to the toggle feature can <emphasis>not</emphasis> be
+    controlled separately by <quote>ACLs</quote> or HTTP authentication,
+    so that everybody who can access <application>Privoxy</application> (see
+    <quote>ACLs</quote> and <literal>listen-address</literal> above) can
+    toggle it for all users. So this option is <emphasis>not recommended</emphasis>
+    for multi-user environments with untrusted users.
+   </para>
+   <para>
+    Note that you must have compiled <application>Privoxy</application> with
+    support for this feature, otherwise this option has no effect. 
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<sect3 renderas="sect4" id="enable-edit-actions"><title>enable-edit-actions</title>
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Whether or not the <ulink url="http://config.privoxy.org/show-status">web-based actions
+    file editor</ulink> may be used
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>0 or 1</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>1</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    The web-based actions file editor is disabled.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    For the time being, access to the editor can <emphasis>not</emphasis> be
+    controlled separately by <quote>ACLs</quote> or HTTP authentication,
+    so that everybody who can access <application>Privoxy</application> (see
+    <quote>ACLs</quote> and <literal>listen-address</literal> above) can
+    modify its configuration for all users. So this option is <emphasis>not
+    recommended</emphasis> for multi-user environments with untrusted users.
+   </para>
+   <para>
+    Note that you must have compiled <application>Privoxy</application> with
+    support for this feature, otherwise this option has no effect. 
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="acls"><title>
+ACLs: permit-access and deny-access</title>
+<anchor id="permit-access">
+<anchor id="deny-access">
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Who can access what.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>
+    <replaceable class="parameter">src_addr</replaceable>[/<replaceable class="parameter">src_masklen</replaceable>]
+    [<replaceable class="parameter">dst_addr</replaceable>[/<replaceable class="parameter">dst_masklen</replaceable>]]
+   </para>
+   <para>
+    Where <replaceable class="parameter">src_addr</replaceable> and 
+   <replaceable class="parameter">dst_addr</replaceable> are IP addresses in dotted decimal notation or valid
+    DNS names, and <replaceable class="parameter">src_masklen</replaceable> and
+    <replaceable class="parameter">dst_masklen</replaceable> are subnet masks in CIDR notation, i.e. integer
+    values from 2 to 30 representing the length (in bits) of the network address. The masks and the whole
+    destination part are optional.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Don't restrict access further than implied by <literal>listen-address</literal>
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    Access controls are included at the request of ISPs and systems
+    administrators, and <emphasis>are not usually needed by individual users</emphasis>.
+    For a typical home user, it will normally suffice to ensure that 
+    <application>Privoxy</application> only listens on the localhost
+    (127.0.0.1) or internal (home) network address by means of the
+    <link linkend="listen-address"><emphasis>listen-address</emphasis></link>
+    option. 
+   </para>
+   <para>
+    Please see the warnings in the FAQ that this proxy is not intended to be a substitute
+    for a firewall or to encourage anyone to defer addressing basic security
+    weaknesses.
+   </para>
+   <para>
+    Multiple ACL lines are OK.
+    If any ACLs are specified, then the <application>Privoxy</application>
+    talks only to IP addresses that match at least one <literal>permit-access</literal> line
+    and don't match any subsequent <literal>deny-access</literal> line. In other words, the
+    last match wins, with the default being <literal>deny-access</literal>.
+   </para>
+   <para>
+    If <application>Privoxy</application> is using a forwarder (see <literal>forward</literal> below)
+    for a particular destination URL, the <replaceable class="parameter">dst_addr</replaceable>
+    that is examined is the address of the forwarder and <emphasis>NOT</emphasis> the address
+    of the ultimate target. This is necessary because it may be impossible for the local
+    <application>Privoxy</application> to determine the IP address of the
+    ultimate target (that's often what gateways are used for).
+   </para>
+   <para>
+    You should prefer using IP addresses over DNS names, because the address lookups take
+    time. All DNS names must resolve! You can <emphasis>not</emphasis> use domain patterns
+    like <quote>*.org</quote> or partial domain names. If a DNS name resolves to multiple
+    IP addresses, only the first one is used.
+   </para>
+   <para>
+    Denying access to particular sites by ACL may have undesired side effects
+    if the site in question is hosted on a machine which also hosts other sites.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Examples:</term>
+  <listitem>
+   <para>
+    Explicitly define the default behavior if no ACL and
+    <literal>listen-address</literal> are set: <quote>localhost</quote>
+    is OK. The absence of a <replaceable class="parameter">dst_addr</replaceable> implies that
+    <emphasis>all</emphasis> destination addresses are OK:
+   </para>
+   <para>
+    <screen>
+  permit-access  localhost
+</screen>
+   </para>
+   <para>
+    Allow any host on the same class C subnet as www.privoxy.org access to
+    nothing but www.example.com:
+   </para>
+   <para>
+    <screen>
+  permit-access  www.privoxy.org/24 www.example.com/32
+</screen>
+   </para>
+   <para>
+    Allow access from any host on the 26-bit subnet 192.168.45.64 to anywhere,
+    with the exception that 192.168.45.73 may not access www.dirty-stuff.example.com:
+   </para>
+   <para>
+    <screen>
+  permit-access  192.168.45.64/26
+  deny-access    192.168.45.73    www.dirty-stuff.example.com
+</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="buffer-limit"><title>buffer-limit</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Maximum size of the buffer for content filtering.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>Size in Kbytes</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para>4096</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Use a 4MB (4096 KB) limit.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    For content filtering, i.e. the <literal>+filter</literal> and
+    <literal>+deanimate-gif</literal> actions, it is necessary that 
+    <application>Privoxy</application> buffers the entire document body.
+    This can be potentially dangerous, since a server could just keep sending
+    data indefinitely and wait for your RAM to exhaust -- with nasty consequences.
+    Hence this option.
+   </para>
+   <para>
+    When a document buffer size reaches the <literal>buffer-limit</literal>, it is
+    flushed to the client unfiltered and no further attempt to
+    filter the rest of the document is made. Remember that there may be multiple threads
+    running, which might require up to <literal>buffer-limit</literal> Kbytes
+    <emphasis>each</emphasis>, unless you have enabled <quote>single-threaded</quote>
+    above.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+</sect2>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="forwarding">
+<title>Forwarding</title>
+
+<para>
+ This feature allows routing of HTTP requests through a chain of
+ multiple proxies.
+ It can be used to better protect privacy and confidentiality when
+ accessing specific domains by routing requests to those domains
+ through an anonymous public proxy (see e.g. <ulink
+ url="http://www.multiproxy.org/anon_list.htm">http://www.multiproxy.org/anon_list.htm</ulink>)
+ Or to use a caching proxy to speed up browsing. Or chaining to a parent
+ proxy may be necessary because the machine that <application>Privoxy</application>
+ runs on has no direct Internet access.
+</para>
+
+<para>
+ Also specified here are SOCKS proxies. <application>Privoxy</application>
+ supports the SOCKS 4 and SOCKS 4A protocols.
+</para>
+
+<sect3 renderas="sect4" id="forward"><title>forward</title>
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    To which parent HTTP proxy specific requests should be routed.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>
+    <replaceable class="parameter">target_domain</replaceable>[:<replaceable class="parameter">port</replaceable>]
+    <replaceable class="parameter">http_parent</replaceable>[/<replaceable class="parameter">port</replaceable>]
+   </para>
+   <para>
+    Where <replaceable class="parameter">target_domain</replaceable> is a domain name pattern (see the
+    chapter on domain matching in the <filename>default.action</filename> file),
+    <replaceable class="parameter">http_parent</replaceable> is the address of the parent HTTP proxy
+    as an IP addresses in dotted decimal notation or as a valid DNS name (or <quote>.</quote> to denote
+    <quote>no forwarding</quote>, and the optional 
+    <replaceable class="parameter">port</replaceable> parameters are TCP ports, i.e. integer
+    values from 1 to 64535
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Don't use parent HTTP proxies.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    If <replaceable class="parameter">http_parent</replaceable> is <quote>.</quote>, then requests are not
+    forwarded to another HTTP proxy but are made directly to the web servers.
+   </para>
+   <para>
+    Multiple lines are OK, they are checked in sequence, and the last match wins.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Examples:</term>
+  <listitem>
+   <para>
+    Everything goes to an example anonymizing proxy, except SSL on port 443 (which it doesn't handle):
+   </para>
+   <para>
+    <screen>
+  forward   .*     anon-proxy.example.org:8080
+  forward   :443   .
+</screen>
+   </para>
+   <para>
+    Everything goes to our example ISP's caching proxy, except for requests
+    to that ISP's sites:
+   </para>
+   <para>
+    <screen>
+  forward   .*.                caching-proxy.example-isp.net:8000
+  forward   .example-isp.net   .
+</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="socks"><title>
+forward-socks4 and forward-socks4a</title>
+<anchor id="forward-socks4">
+<anchor id="forward-socks4a">
+
+<variablelist>
+ <varlistentry>
+  <term>Specifies:</term>
+  <listitem>
+   <para>
+    Through which SOCKS proxy (and to which parent HTTP proxy) specific requests should be routed.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Type of value:</term>
+  <listitem>
+   <para>
+    <replaceable class="parameter">target_domain</replaceable>[:<replaceable class="parameter">port</replaceable>]
+    <replaceable class="parameter">socks_proxy</replaceable>[/<replaceable class="parameter">port</replaceable>]
+    <replaceable class="parameter">http_parent</replaceable>[/<replaceable class="parameter">port</replaceable>]
+   </para>
+   <para>
+    Where <replaceable class="parameter">target_domain</replaceable> is a domain name pattern (see the
+    chapter on domain matching in the <filename>default.action</filename> file),
+    <replaceable class="parameter">http_parent</replaceable> and <replaceable class="parameter">socks_proxy</replaceable>
+    are IP addresses in dotted decimal notation or valid DNS names (<replaceable class="parameter">http_parent</replaceable>
+    may be <quote>.</quote> to denote <quote>no HTTP forwarding</quote>), and the optional 
+    <replaceable class="parameter">port</replaceable> parameters are TCP ports, i.e. integer values from 1 to 64535
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Default value:</term>
+  <listitem>
+   <para><emphasis>Unset</emphasis></para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Effect if unset:</term>
+  <listitem>
+   <para>
+    Don't use SOCKS proxies.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    Multiple lines are OK, they are checked in sequence, and the last match wins.
+   </para>
+   <para>
+    The difference between <literal>forward-socks4</literal> and <literal>forward-socks4a</literal>
+    is that in the SOCKS 4A protocol, the DNS resolution of the target hostname happens on the SOCKS
+    server, while in SOCKS 4 it happens locally.
+   </para>
+   <para>
+    If <replaceable class="parameter">http_parent</replaceable> is <quote>.</quote>, then requests are not
+    forwarded to another HTTP proxy but are made (HTTP-wise) directly to the web servers, albeit through
+    a SOCKS proxy.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Examples:</term>
+  <listitem>
+   <para>
+     From the company example.com, direct connections are made to all
+     <quote>internal</quote> domains, but everything outbound goes through
+     their ISP's proxy by way of example.com's corporate SOCKS 4A gateway to
+     the Internet.
+   </para>
+   <para>
+    <screen>
+  forward-socks4a   .*.            socks-gw.example.com:1080  www-cache.example-isp.net:8080
+  forward           .example.com   .
+</screen>
+   </para>
+   <para>
+    A rule that uses a SOCKS 4 gateway for all destinations but no HTTP parent looks like this:
+   </para>
+   <para>
+    <screen>
+  forward-socks4   .*.            socks-gw.example.com:1080  .
+</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<sect3 renderas="sect4" id="advanced-forwarding-examples"><title>Advanced Forwarding Examples</title>
+
+<para>
+ If you have links to multiple ISPs that provide various special content 
+ only to their subscribers, you can configure multiple <application>Privoxies</application>
+ which have connections to the respective ISPs to act as forwarders to each other, so that
+ <emphasis>your</emphasis> users can see the internal content of all ISPs.
+</para>
+
+<para>
+ Assume that host-a has a PPP connection to isp-a.net. And host-b has a PPP connection to
+ isp-b.net. Both run <application>Privoxy</application>. Their forwarding
+ configuration can look like this:
+</para>
+
+<para>
+ host-a:
+</para>
+
+<para>
+ <screen>
+  forward    .*.         .
+  forward    .isp-b.net  host-b:8118
+</screen>
+</para>
+
+<para>
+ host-b:
+</para>
+
+<para>
+ <screen>
+  forward    .*.         .
+  forward    .isp-a.net  host-a:8118
+</screen>
+</para>
+
+<para>
+ Now, your users can set their browser's proxy to use either
+ host-a or host-b and be able to browse the internal content
+ of both isp-a and isp-b.
+</para>
+
+<para>
+ If you intend to chain <application>Privoxy</application> and 
+ <application>squid</application> locally, then chain as 
+ <literal>browser -> squid -> privoxy</literal> is the recommended way. 
+</para>
+
+<para>
+ Assuming that <application>Privoxy</application> and <application>squid</application>
+ run on the same box, your squid configuration could then look like this:
+</para>
+
+<para>
+ <screen>
+  # Define Privoxy as parent proxy (without ICP) 
+  cache_peer 127.0.0.1 parent 8118 7 no-query 
+
+  # Define ACL for protocol FTP 
+  acl ftp proto FTP 
+
+  # Do not forward FTP requests to Privoxy
+  always_direct allow ftp 
+
+  # Forward all the rest to Privoxy
+  never_direct allow all</screen>
+</para>
+
+<para>
+ You would then need to change your browser's proxy settings to <application>squid</application>'s address and port.
+ Squid normally uses port 3128. If unsure consult <literal>http_port</literal> in <filename>squid.conf</filename>.
+</para>
+
+</sect3>
+
+</sect2>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="windows-gui">
+<title>Windows GUI Options</title>
+<para>
+ <application>Privoxy</application> has a number of options specific to the
+ Windows GUI interface:
+</para>
+
+<anchor id="activity-animation">
+<para>
+ If <quote>activity-animation</quote> is set to 1, the
+ <application>Privoxy</application> icon will animate when
+ <quote>Privoxy</quote> is active. To turn off, set to 0.
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>activity-animation   1</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="log-messages">
+<para>
+ If <quote>log-messages</quote> is set to 1,
+ <application>Privoxy</application> will log messages to the console
+ window:
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>log-messages       1</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="log-buffer-size">
+<para> 
+ If <quote>log-buffer-size</quote> is set to 1, the size of the log buffer,
+ i.e. the amount of memory used for the log messages displayed in the
+ console window, will be limited to <quote>log-max-lines</quote> (see below).
+</para>
+
+<para>
+ Warning: Setting this to 0 will result in the buffer to grow infinitely and
+ eat up all your memory!
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>log-buffer-size      1</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="log-max-lines">
+<para>
+ <application>log-max-lines</application> is the maximum number of lines held
+ in the log buffer. See above.
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>log-max-lines      200</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="log-highlight-messages">
+<para>
+ If <quote>log-highlight-messages</quote> is set to 1,
+ <application>Privoxy</application> will highlight portions of the log
+ messages with a bold-faced font:
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>log-highlight-messages   1</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="log-font-name">
+<para>
+ The font used in the console window:
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>log-font-name        Comic Sans MS</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="log-font-size">
+<para>
+ Font size used in the console window:
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>log-font-size        8</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="show-on-task-bar">
+<para>  
+ <quote>show-on-task-bar</quote> controls whether or not
+ <application>Privoxy</application> will appear as a button on the Task bar
+ when minimized:
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>show-on-task-bar     0</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="close-button-minimizes">
+<para>
+ If <quote>close-button-minimizes</quote> is set to 1, the Windows close
+ button will minimize <application>Privoxy</application> instead of closing
+ the program (close with the exit option on the File menu).
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  <emphasis>close-button-minimizes  1</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+<anchor id="hide-console">
+<para>
+ The <quote>hide-console</quote> option is specific to the MS-Win console
+ version of <application>Privoxy</application>. If this option is used,
+ <application>Privoxy</application> will disconnect from and hide  the
+ command console.
+</para>
+
+<para>
+ <literal>
+  <msgtext> 
+   <literallayout>
+  #<emphasis>hide-console</emphasis>
+   </literallayout>
+  </msgtext> 
+ </literal>
+</para>
+
+</sect2>
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+
+<sect1 id="actions-file"><title>Actions Files</title>
+
+<para>
+ The actions files are used to define what actions
+ <application>Privoxy</application> takes for which URLs, and thus determine
+ how ad images, cookies and various other aspects of HTTP content and
+ transactions are handled, and on which sites (or even parts thereof). There 
+ are three such files included with <application>Privoxy</application> (as of 
+ version 2.9.15), with differing purposes:
+ </para>
+ <para>
+  <itemizedlist>
+   <listitem>
+    <para>
+     <filename>default.action</filename> - is the primary action file 
+     that sets the initial values for all actions. It is intended to 
+     provide a base level of functionality for
+     <application>Privoxy's</application> array of features. So it is 
+     a set of broad rules that should work reasonably well for users everywhere.
+     This is the file that the developers are keeping updated, and making 
+     available to users.
+    </para>
+   </listitem> 
+   <listitem>
+    <para>
+     <filename>user.action</filename> - is intended to be for local site 
+     preferences and exceptions. As an example, if your ISP or your bank
+     has specific requirements, and need special handling, this kind of 
+     thing should go here. This file will not be upgraded.
+    </para>
+  </listitem> 
+   <listitem>
+    <para>
+     <filename>standard.action</filename> - is used by the web based editor, 
+     to set various pre-defined sets of rules for the default actions section
+     in <filename>default.action</filename>. These have increasing levels of
+     aggressiveness <emphasis>and have no influence on your browsing unless
+     you select them explicitly in the editor</emphasis>. It is not recommend
+     to edit this file.
+    </para>
+   </listitem> 
+  </itemizedlist>
+ </para> 
+
+<para>
+ The list of actions files to be used are defined in the main configuration 
+ file, and are processed in the order they are defined. The content of these
+ can all be viewed and edited from <ulink
+ url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>.
+</para>
+
+<para>
+ An actions file typically has multiple sections. If you want to use
+ <quote>aliases</quote> in an actions file, you have to place the (optional)
+ <link linkend="aliases">alias section</link> at the top of that file.
+ Then comes the default set of rules which will apply universally to all
+ sites and pages (be <emphasis>very careful</emphasis> with using such a
+ universal set in <filename>user.action</filename> or any other actions file after 
+ <filename>default.action</filename>, because it will override the result
+ from consulting any previous file). And then below that,
+ exceptions to the defined universal policies. You can regard
+ <filename>user.action</filename> as an appendix to <filename>default.action</filename>,
+ with the advantage that is a separate file, which makes preserving your
+ personal settings across <application>Privoxy</application> upgrades easier.
+</para>
+
+<para> 
+ Actions can be used to block anything you want, including ads, banners, or
+ just some obnoxious URL that you would rather not see. Cookies can be accepted
+ or rejected, or accepted only during the current browser session (i.e. not
+ written to disk), content can be modified, JavaScripts tamed, user-tracking
+ fooled, and much more. See below for a <link linkend="actions">complete list
+ of actions</link>.
+</para>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2>
+<title>Finding the Right Mix</title>
+<para>
+ Note that some <link linkend="actions">actions</link>, like cookie suppression
+ or script disabling, may render some sites unusable that rely on these
+ techniques to work properly. Finding the right mix of actions is not always easy and
+ certainly a matter of personal taste. In general, it can be said that the more
+ <quote>aggressive</quote> your default settings (in the top section of the
+ actions file) are, the more exceptions for <quote>trusted</quote> sites you
+ will have to make later. If, for example, you want to kill popup windows per
+ default, you'll have to make exceptions from that rule for sites that you
+ regularly use and that require popups for actually useful content, like maybe
+ your bank, favorite shop, or newspaper.
+</para>
+
+<para>
+ We have tried to provide you with reasonable rules to start from in the
+ distribution actions files. But there is no general rule of thumb on these
+ things. There just are too many variables, and sites are constantly changing.
+ Sooner or later you will want to change the rules (and read this chapter again :).
+</para>
+</sect2>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2>
+<title>How to Edit</title>
+<para>
+ The easiest way to edit the actions files is with a browser by
+ using our browser-based editor, which can be reached from <ulink
+ url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>.
+ The editor allows both fine-grained control over every single feature on a
+ per-URL basis, and easy choosing from wholesale sets of defaults like
+ <quote>Cautious</quote>, <quote>Medium</quote> or <quote>Advanced</quote>.
+</para>
+
+<para>
+ If you prefer plain text editing to GUIs, you can of course also directly edit the
+ the actions files. Look at <filename>default.action</filename> which is richly
+ commented.
+</para>
+</sect2>
+
+
+<sect2 id="actions-apply">
+<title>How Actions are Applied to URLs</title>
+<para>
+ Actions files are divided into sections. There are special sections,
+ like the <quote><link linkend="aliases">alias</link></quote> sections which will
+ be discussed later. For now let's concentrate on regular sections: They have a
+ heading line (often split up to multiple lines for readability) which consist
+ of a list of actions, separated by whitespace and enclosed in curly braces.
+ Below that, there is a list of URL patterns, each on a separate line.
+</para>
+
+<para>
+ To determine which actions apply to a request, the URL of the request is
+ compared to all patterns in each action file file. Every time it matches, the list of
+ applicable actions for the URL is incrementally updated, using the heading
+ of the section in which the pattern is located. If multiple matches for
+ the same URL set the same action differently, the last match wins. If not, 
+ the effects are aggregated. E.g. a URL might match a regular section with 
+ a heading line of <literal>{ 
+ +<ulink url="actions-file.html#HANDLE-AS-IMAGE">handle-as-image</ulink> }</literal>,
+ then later another one with just <literal>{
+ +<ulink url="actions-file.html#BLOCK">block</ulink> }</literal>, resulting
+ in <emphasis>both</emphasis> actions to apply.
+</para>
+
+<para>
+ You can trace this process for any given URL by visiting <ulink
+ url="http://config.privoxy.org/show-url-info">http://config.privoxy.org/show-url-info</ulink>.
+</para>
+
+<para>
+ More detail on this is provided in the Appendix, <link linkend="ACTIONSANAT">
+ Anatomy of an Action</link>.
+</para>
+</sect2>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="af-patterns">
+<title>Patterns</title>
+<para>
+ Generally, a pattern has the form <literal>&lt;domain&gt;/&lt;path&gt;</literal>,
+ where both the <literal>&lt;domain&gt;</literal> and <literal>&lt;path&gt;</literal>
+ are optional. (This is why the pattern <literal>/</literal> matches all URLs).
+</para>
+
+<variablelist>
+ <varlistentry>
+  <term><literal>www.example.com/</literal></term>
+  <listitem>
+   <para>
+    is a domain-only pattern and will match any request to <literal>www.example.com</literal>,
+    regardless of which document on that server is requested.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>www.example.com</literal></term>
+  <listitem>
+   <para>
+    means exactly the same. For domain-only patterns, the trailing <literal>/</literal> may
+    be omitted.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>www.example.com/index.html</literal></term>
+  <listitem>
+   <para>
+    matches only the single document <literal>/index.html</literal>
+    on <literal>www.example.com</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>/index.html</literal></term>
+  <listitem>
+   <para>
+    matches the document <literal>/index.html</literal>, regardless of the domain,
+    i.e. on <emphasis>any</emphasis> web server.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>index.html</literal></term>
+  <listitem>
+   <para>
+    matches nothing, since it would be  interpreted as a domain name and
+    there is no top-level domain called <literal>.html</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3><title>The Domain Pattern</title>
+
+<para>
+ The matching of the domain part offers some flexible options: if the
+ domain starts or ends with a dot, it becomes unanchored at that end. 
+ For example:
+</para>
+
+<variablelist>
+ <varlistentry>
+  <term><literal>.example.com</literal></term>
+  <listitem>
+   <para>
+    matches any domain that <emphasis>ENDS</emphasis> in
+    <literal>.example.com</literal>
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>www.</literal></term>
+  <listitem>
+   <para>
+    matches any domain that <emphasis>STARTS</emphasis> with
+    <literal>www.</literal>
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>.example.</literal></term>
+  <listitem>
+   <para>
+    matches any domain that <emphasis>CONTAINS</emphasis> <literal>.example.</literal>
+    (Correctly speaking: It matches any FQDN that contains <literal>example</literal> as a domain.)
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+ Additionally, there are wild-cards that you can use in the domain names
+ themselves. They work pretty similar to shell wild-cards: <quote>*</quote>
+ stands for zero or more arbitrary characters, <quote>?</quote> stands for
+ any single character, you can define character classes in square
+ brackets and all of that can be freely mixed:
+</para>
+
+<variablelist>
+ <varlistentry>
+  <term><literal>ad*.example.com</literal></term>
+  <listitem>
+   <para>
+    matches <quote>adserver.example.com</quote>, 
+    <quote>ads.example.com</quote>, etc but not <quote>sfads.example.com</quote>
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>*ad*.example.com</literal></term>
+  <listitem>
+   <para>
+    matches all of the above, and then some.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>.?pix.com</literal></term>
+  <listitem>
+   <para>
+    matches <literal>www.ipix.com</literal>,
+    <literal>pictures.epix.com</literal>, <literal>a.b.c.d.e.upix.com</literal> etc. 
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term><literal>www[1-9a-ez].example.c*</literal></term>
+  <listitem>
+   <para>
+     matches <literal>www1.example.com</literal>, 
+     <literal>www4.example.cc</literal>, <literal>wwwd.example.cy</literal>, 
+     <literal>wwwz.example.com</literal> etc., but <emphasis>not</emphasis> 
+     <literal>wwww.example.com</literal>.
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+
+</sect3>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3><title>The Path Pattern</title>
+
+<para>
+ <application>Privoxy</application> uses Perl compatible regular expressions
+ (through the <ulink url="http://www.pcre.org/">PCRE</ulink> library) for
+ matching the path.
+</para>
+
+<para>
+ There is an <link linkend="regex">Appendix</link> with a brief quick-start into regular
+ expressions, and full (very technical) documentation on PCRE regex syntax is available on-line
+ at <ulink url="http://www.pcre.org/man.txt">http://www.pcre.org/man.txt</ulink>.
+ You might also find the Perl man page on regular expressions (<literal>man perlre</literal>)
+ useful, which is available on-line at <ulink
+ url="http://www.perldoc.com/perl5.6/pod/perlre.html">http://www.perldoc.com/perl5.6/pod/perlre.html</ulink>.
+</para>
+
+<para>
+ Note that the path pattern is automatically left-anchored at the <quote>/</quote>,
+ i.e. it matches as if it would start with a <quote>^</quote> (regular expression speak 
+ for the beginning of a line).
+</para>
+
+<para>
+ Please also note that matching in the path is <emphasis>CASE INSENSITIVE</emphasis>
+ by default, but you can switch to case sensitive at any point in the pattern by using the 
+ <quote>(?-i)</quote> switch: <literal>www.example.com/(?-i)PaTtErN.*</literal> will match
+ only documents whose path starts with <literal>PaTtErN</literal> in
+ <emphasis>exactly</emphasis> this capitalization.
+</para>
+</sect3>
+
+</sect2>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="actions">
+<title>Actions</title>
+<para>
+ All actions are disabled by default, until they are explicitly enabled
+ somewhere in an actions file. Actions are turned on if preceded with a
+ <quote>+</quote>, and turned off if preceded with a <quote>-</quote>. So a
+ <literal>+action</literal> means <quote>do that action</quote>, e.g.
+ <literal>+block</literal> means <quote>please block URLs that match the
+ following patterns</quote>, and <literal>-block</literal> means <quote>don't
+ block URLs that match the following patterns, even if <literal>+block</literal>
+ previously applied.</quote>
+
+</para>
+
+<para> 
+ Again, actions are invoked by placing them on a line, enclosed in curly braces and
+ separated by whitespace, like in 
+ <literal>{+some-action -some-other-action{some-parameter}}</literal>,
+ followed by a list of URL patterns, one per line, to which they apply.
+ Together, the actions line and the following pattern lines make up a section
+ of the actions file. 
+</para>
+
+<para> 
+ There are three classes of actions:
+</para>
+
+<para>
+ <itemizedlist>
+ <listitem>
+  <para>  
+   Boolean, i.e the action can only be <quote>enabled</quote> or
+   <quote>disabled</quote>. Syntax:
+  </para>
+  <para>
+   <screen>
+  +<replaceable class="function">name</replaceable>        # enable action <replaceable class="parameter">name</replaceable>
+  -<replaceable class="function">name</replaceable>        # disable action <replaceable class="parameter">name</replaceable></screen>
+  </para>
+  <para>  
+   Example: <literal>+block</literal>
+  </para>
+ </listitem>
+
+
+ <listitem>
+  <para>  
+   Parameterized, where some value is required in order to enable this type of action.
+   Syntax:
+  </para>
+  <para>
+   <screen>
+  +<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}  # enable action and set parameter to <replaceable class="parameter">param</replaceable>,
+               # overwriting parameter from previous match if necessary
+  -<replaceable class="function">name</replaceable>         # disable action. The parameter can be omitted</screen>
+  </para>
+  <para>
+   Note that if the URL matches multiple positive forms of a parameterized action,
+   the last match wins, i.e. the params from earlier matches are simply ignored.
+  </para>
+  <para>  
+   Example: <literal>+hide-user-agent{ Mozilla 1.0 }</literal>
+  </para>
+ </listitem>
+ <listitem>
+  <para>  
+   Multi-value. These look exactly like parameterized actions,
+   but they behave differently: If the action applies multiple times to the
+   same URL, but with different parameters, <emphasis>all</emphasis> the parameters
+   from <emphasis>all</emphasis> matches are remembered. This is used for actions
+   that can be executed for the same request repeatedly, like adding multiple
+   headers, or filtering through multiple filters. Syntax:
+  </para>
+  <para>
+   <screen>
+  +<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}   # enable action and add <replaceable class="parameter">param</replaceable> to the list of parameters
+  -<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}   # remove the parameter <replaceable class="parameter">param</replaceable> from the list of parameters
+                # If it was the last one left, disable the action.
+  <replaceable class="parameter">-name</replaceable>          # disable this action completely and remove all parameters from the list</screen>
+  </para>
+  <para>  
+   Examples: <literal>+add-header{X-Fun-Header: Some text}</literal> and
+   <literal>+filter{html-annoyances}</literal>
+  </para>
+ </listitem>
+
+ </itemizedlist>
+</para>
+
+<para>
+ If nothing is specified in any actions file, no <quote>actions</quote> are
+ taken. So in this case <application>Privoxy</application> would just be a
+ normal, non-blocking, non-anonymizing proxy. You must specifically enable the
+ privacy and blocking features you need (although the provided default actions
+ files will give a good starting point).
+</para>
+
+<para>
+ Later defined actions always over-ride earlier ones.  So exceptions 
+ to any rules you make, should come in the latter part of the file (or 
+ in a file that is processed later when using multiple actions files). For
+ multi-valued actions, the actions are applied in the order they are specified.
+ Actions files are processed in the order they are defined in
+ <filename>config</filename> (the default installation has three actions
+ files). It also quite possible for any given URL pattern to match more than
+ one pattern and thus more than one set of actions!
+</para>
+
+<!-- start actions listing -->
+<para>
+ The list of valid <application>Privoxy</application> actions are:
+</para>
+
+
+<!-- ********************************************************** -->
+<!-- Please note the below defined actions use id's that are    -->
+<!-- probably linked from other places, so please don't change. -->
+<!--                                                            -->
+<!-- ********************************************************** -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect3 renderas="sect4" id="add-header">
+<title>add-header</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Confuse log analysis, custom applications</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Sends a user defined HTTP header to the web server.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Multi-value.</para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    Any string value is possible. Validity of the defined HTTP headers is not checked.
+    It is recommended that you use the <quote><literal>X-</literal></quote> prefix
+    for custom headers.
+   </para>
+  </listitem>
+ </varlistentry>
+<varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This action may be specified multiple times, in order to define multiple 
+    headers. This is rarely needed for the typical user. If you don't know what 
+    <quote>HTTP headers</quote> are, you definitely don't need to worry about this 
+    one.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+    <para>
+     <screen>+add-header{X-User-Tracking: sucks}</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="block">
+<title>block</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Block ads or other obnoxious content</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Requests for URLs to which this action applies are blocked, i.e. the requests are not
+    forwarded to the remote server, but answered locally with a substitute page or image,
+    as determined by the <literal><link linkend="handle-as-image">handle-as-image</link></literal>
+    and <literal><link linkend="set-image-blocker">set-image-blocker</link></literal> actions.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>N/A</para>
+  </listitem>
+ </varlistentry>
+<varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    <application>Privoxy</application> sends a special <quote>BLOCKED</quote> page
+    for requests to blocked pages. This page contains links to find out why the request
+    was blocked, and a click-through to the blocked content (the latter only if compiled with the
+    force feature enabled). The <quote>BLOCKED</quote> page adapts to the available
+    screen space -- it displays full-blown if space allows, or miniaturized and text-only
+    if loaded into a small frame or window. If you are using <application>Privoxy</application>
+    right now, you can take a look at the 
+    <ulink url="http://ads.bannerserver.example.com/nasty-ads/sponsor.html"><quote>BLOCKED</quote>
+    page</ulink>.
+   </para>
+   <para> 
+    A very important exception occurs if <emphasis>both</emphasis> 
+    <literal>block</literal> and <literal><link linkend="handle-as-image">handle-as-image</link></literal>,
+    apply to the same request: it will then be replaced by an image. If 
+    <literal><link linkend="set-image-blocker">set-image-blocker</link></literal>
+    (see below) also applies, the type of image will be determined by its parameter,
+    if not, the standard checkerboard pattern is sent.
+   </para>
+   <para>
+    It is important to understand this process, in order 
+    to understand how <application>Privoxy</application> deals with 
+    ads and other unwanted content.
+   </para>
+   <para>
+    The <literal><link linkend="filter">filter</link></literal>
+    action can perform a very similar task, by <quote>blocking</quote>
+    banner images and other content through rewriting the relevant URLs in the
+    document's HTML source, so they don't get requested in the first place.
+    Note that this is a totally different technique, and it's easy to confuse the two.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (section):</term>
+  <listitem>
+    <para>
+     <screen>{+block}      # Block and replace with "blocked" page
+.nasty-stuff.example.com
+
+{+block +handle-as-image} # Block and replace with image
+.ad.doubleclick.net
+.ads.r.us</screen>
+    </para>
+  </listitem>
+ </varlistentry>
+
+
+</variablelist>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="crunch-incoming-cookies">
+<title>crunch-incoming-cookies</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+    Prevent the web server from setting any cookies on your system
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Deletes any <quote>Set-Cookie:</quote> HTTP headers from server replies.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This action is only concerned with <emphasis>incoming</emphasis> cookies. For
+    <emphasis>outgoing</emphasis> cookies, use
+    <literal><link linkend="crunch-outgoing-cookies">crunch-outgoing-cookies</link></literal>.
+    Use <emphasis>both</emphasis> to disable cookies completely.
+   </para>
+   <para>
+    It makes <emphasis>no sense at all</emphasis> to use this action in conjunction
+    with the <literal><link linkend="session-cookies-only">session-cookies-only</link></literal> action,
+    since it would prevent the session cookies from being set.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+    <screen>+crunch-incoming-cookies</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="crunch-outgoing-cookies">
+<title>crunch-outgoing-cookies</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+    Prevent the web server from reading any cookies from your system
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Deletes any <quote>Cookie:</quote> HTTP headers from client requests.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This action is only concerned with <emphasis>outgoing</emphasis> cookies. For
+    <emphasis>incoming</emphasis> cookies, use
+    <literal><link linkend="crunch-incoming-cookies">crunch-incoming-cookies</link></literal>.
+    Use <emphasis>both</emphasis> to disable cookies completely.
+   </para>
+   <para>
+    It makes <emphasis>no sense at all</emphasis> to use this action in conjunction
+    with the <literal><link linkend="session-cookies-only">session-cookies-only</link></literal> action,
+    since it would prevent the session cookies from being read.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+    <screen>+crunch-outgoing-cookies</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="deanimate-gifs">
+<title>deanimate-gifs</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Stop those annoying, distracting animated GIF images.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    De-animate GIF animations, i.e. reduce them to their first or last image.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Parameterized.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    <quote>last</quote> or <quote>first</quote>
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This will also shrink the images considerably (in bytes, not pixels!). If
+    the option <quote>first</quote> is given, the first frame of the animation
+    is used as the replacement. If <quote>last</quote> is given, the last
+    frame of the animation is used instead, which probably makes more sense for
+    most banner animations, but also has the risk of not showing the entire
+    last frame (if it is only a delta to an earlier frame).
+   </para>
+   <para>
+    You can safely use this action with patterns that will also match non-GIF
+    objects, because no attempt will be made at anything that doesn't look like
+    a GIF.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+    <para>
+      <screen>+deanimate-gifs{last}</screen>
+    </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="downgrade-http-version">
+<title>downgrade-http-version</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Work around (very rare) problems with HTTP/1.1</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Downgrades HTTP/1.1 client requests and server replies to HTTP/1.0.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+<varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This is a left-over from the time when <application>Privoxy</application>
+    didn't support important HTTP/1.1 features well. It is left here for the
+    unlikely case that you experience HTTP/1.1 related problems with some server
+    out there. Not all (optional) HTTP/1.1 features are supported yet, so there
+    is a chance you might need this action.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (section):</term>
+  <listitem>
+    <para>
+     <screen>{+downgrade-http-version}
+problem-host.example.com</screen>
+    </para>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="fast-redirects">
+<title>fast-redirects</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Fool some click-tracking scripts and speed up indirect links</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Cut off all but the last valid URL from requests.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>  
+    Many sites, like yahoo.com, don't just link to other sites. Instead, they
+    will link to some script on their own servers, giving the destination as a
+    parameter, which will then redirect you to the final target. URLs
+    resulting from this scheme typically look like:
+    <emphasis>http://some.place/click-tracker.cgi?target=http://some.where.else</emphasis>.
+  </para>
+   <para>
+    Sometimes, there are even multiple consecutive redirects encoded in the
+    URL. These redirections via scripts make your web browsing more traceable,
+    since the server from which you follow such a link can see where you go
+    to. Apart from that, valuable bandwidth and time is wasted, while your
+    browser ask the server for one redirect after the other. Plus, it feeds
+    the advertisers.
+   </para>
+   <para>
+    This feature is currently not very smart and is scheduled for improvement.
+    It is likely to break some sites. You should expect to need possibly 
+    many exceptions to this action, if it is enabled by default in
+    <filename>default.action</filename>. Some sites just don't work without 
+    it.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+    <para>
+     <screen>{+fast-redirects}</screen>
+    </para>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="filter">
+<title>filter</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Get rid of HTML and JavaScript annoyances, banner advertisements (by size), do fun text replacements, etc.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Text documents, including HTML and JavaScript, to which this action applies, are filtered on-the-fly
+    through the specified regular expression based substitutions.    
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Parameterized.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    The name of a filter, as defined in the <link linkend="filter-file">filter file</link>
+    (typically <filename>default.filter</filename>, set by the
+    <literal><link linkend="filterfile">filterfile</link></literal>
+    option in the <link linkend="config">config file</link>)
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    For your convenience, there are a bunch of pre-defined filters available 
+    in the distribution filter file that you can use. See the example below for
+    a list.
+   </para>
+   <para>
+    This is potentially a very powerful feature!  But <quote>rolling your own</quote>
+    filters requires a knowledge of regular expressions and HTML.
+   </para>
+   <para>
+    Filtering requires buffering the page content, which may appear to
+    slow down page rendering since nothing is displayed until all content has
+    passed the filters. (It does not really take longer, but seems that way
+    since the page is not incrementally displayed.) This effect will be more
+    noticeable on slower connections.
+   </para>
+   <para>
+    At this time, <application>Privoxy</application> cannot (yet!) uncompress compressed
+    documents. If you want filtering to work on all documents, even those that
+    would normally be sent compressed, use the
+    <literal><link linkend="prevent-compression">prevent-compression</link></literal>
+    action in conjunction with <literal>filter</literal>.
+   </para>
+   <para>
+    Filtering can achieve some of the effects as the 
+    <literal><link linkend="block">block</link></literal>
+    action, i.e. it can be used to block ads and banners. 
+   </para>
+   <para>
+    <link linkend="contact">Feedback</link> with suggestions for new or improved filters is particularly
+    welcome!
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (with filters from the distribution <filename>default.filter</filename> file):</term>
+  <listitem>
+   <para>
+    <anchor id="filter-html-annoyances">
+    <screen>+filter{html-annoyances}     # Get rid of particularly annoying HTML abuse.</screen>
+   </para>
+   <para>
+    <anchor id="filter-js-annoyances">
+    <screen>+filter{js-annoyances}       # Get rid of particularly annoying JavaScript abuse</screen>
+   </para>
+   <para>
+    <anchor id="filter-banners-by-size">
+    <screen>+filter{banners-by-size}     # Kill banners by size (<emphasis>very</emphasis> efficient!)</screen>
+   </para>
+   <para>
+    <anchor id="filter-content-cookies">
+    <screen>+filter{content-cookies}     # Kill cookies that come sneaking in the HTML or JS content</screen>
+   </para>
+   <para>
+    <anchor id="filter-popups">
+    <screen>+filter{popups}              # Kill all popups in JS and HTML</screen>
+   </para>
+   <para>
+    <anchor id="filter-webbugs">
+    <screen>+filter{webbugs}             # Squish WebBugs (1x1 invisible GIFs used for user tracking)</screen>
+   </para>
+   <para>
+    <anchor id="filter-fun">
+    <screen>+filter{fun}                 # Text replacements for subversive browsing fun!</screen>
+   </para>
+   <para>
+    <anchor id="filter-frameset-borders">
+    <screen>+filter{frameset-borders}    # Give frames a border and make them resizeable</screen> 
+   </para>
+   <para>
+    <anchor id="filter-refresh-tags">
+    <screen>+filter{refresh-tags}        # Kill automatic refresh tags (for dial-on-demand setups)</screen>
+   </para>
+   <para>
+    <anchor id="filter-nimda">
+    <screen>+filter{nimda}               # Remove Nimda (virus) code.</screen>
+   </para>
+   <para>
+    <anchor id="filter-shockwave-flash">
+    <screen>+filter{shockwave-flash}     # Kill embedded Shockwave Flash objects</screen>
+   </para>
+   <para>
+    <anchor id="filter-crude-parental">
+    <screen>+filter{crude-parental}      # Kill all web pages that contain the words "sex" or "warez"</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="handle-as-image">
+<title>handle-as-image</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Mark URLs as belonging to images (so they'll be replaced by images <emphasis>if they get blocked</emphasis>)</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    This action alone doesn't do anything noticeable. It just marks URLs as images.
+    If the <literal><link linkend="block">block</link></literal> action <emphasis>also applies</emphasis>,
+    the presence or absence of this mark decides whether an HTML <quote>blocked</quote>
+    page, or a replacement image (as determined by the <literal><link
+    linkend="set-image-blocker">set-image-blocker</link></literal> action) will be sent to the
+    client as a substitute for the blocked content.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The below generic example section is actually part of <filename>default.action</filename>.
+    It marks all URLs with well-known image file name extensions as images and should
+    be left intact. 
+   </para>
+   <para>
+    Users will probably only want to use the handle-as-image action in conjunction with
+    <literal><link linkend="block">block</link></literal>, to block sources of banners, whose URLs don't
+    reflect the file type, like in the second example section.
+   </para>
+   <para>
+    Note that you cannot treat HTML pages as images in most cases. For instance, (inline) ad
+    frames require an HTML page to be sent, or they won't display properly.
+    Forcing <literal>handle-as-image</literal> in this situation will not replace the
+    ad frame with an image, but lead to error messages.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (sections):</term>
+  <listitem>
+   <para>
+     <screen># Generic image extensions:
+#
+{+handle-as-image}
+/.*\.(gif|jpg|jpeg|png|bmp|ico)$
+
+# These don't look like images, but they're banners and should be
+# blocked as images:
+#
+{+block +handle-as-image}
+some.nasty-banner-server.com/junk.cgi?output=trash
+
+# Banner source! Who cares if they also have non-image content?
+ad.doubleclick.net 
+</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="hide-forwarded-for-headers">
+<title>hide-forwarded-for-headers</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Improve privacy by hiding the true source of the request</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Deletes any existing <quote>X-Forwarded-for:</quote> HTTP header from client requests,
+    and prevents adding a new one.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    It is fairly safe to leave this on.
+   </para>
+   <para>
+    This action is scheduled for improvement: It should be able to generate forged 
+    <quote>X-Forwarded-for:</quote> headers using random IP addresses from a specified network,
+    to make successive requests from the same client look like requests from a pool of different
+    users sharing the same proxy.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+    <para>
+     <screen>+hide-forwarded-for-headers</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="hide-from-header">
+<title>hide-from-header</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Keep your (old and ill) browser from telling web servers your email address</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Deletes any existing <quote>From:</quote> HTTP header, or replaces it with the
+    specified string.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Parameterized.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    Keyword: <quote>block</quote>, or any user defined value.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The keyword <quote>block</quote> will completely remove the header 
+    (not to be confused with the <literal><link linkend="block">block</link></literal>
+    action).
+   </para>
+   <para>
+    Alternately, you can specify any value you prefer to be sent to the web
+    server. If you do, it is a matter of fairness not to use any address that
+    is actually used by a real person.
+   </para>
+   <para>
+    This action is rarely needed, as modern web browsers don't send
+    <quote>From:</quote> headers anymore.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+    <screen>+hide-from-header{block}</screen> or
+    <screen>+hide-from-header{spam-me-senseless@sittingduck.example.com}</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="hide-referrer">
+<title>hide-referrer</title>
+<anchor id="hide-referer">
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Conceal which link you followed to get to a particular site</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Deletes the <quote>Referer:</quote> (sic) HTTP header from the client request,
+    or replaces it with a forged one.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Parameterized.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <itemizedlist>
+    <listitem>
+     <para><quote>block</quote> to delete the header completely.</para>
+    </listitem>
+    <listitem>
+     <para><quote>forge</quote> to pretend to be coming from the homepage of the server we are talking to.</para>
+    </listitem>
+    <listitem>
+     <para>Any other string to set a user defined referrer.</para>
+    </listitem>
+   </itemizedlist>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    <quote>forge</quote> is the preferred option here, since some servers will
+    not send images back otherwise, in an attempt to prevent their valuable
+    content from being embedded elsewhere (and hence, without being surrounded
+    by <emphasis>their</emphasis> banners).
+   </para>
+  <para>  
+   <literal>hide-referer</literal> is an alternate spelling of
+   <literal>hide-referrer</literal> and the two can be can be freely
+   substituted with each other. (<quote>referrer</quote> is the
+   correct English spelling, however the HTTP specification has a bug - it
+   requires it to be spelled as <quote>referer</quote>.) 
+  </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+     <screen>+hide-referrer{forge}</screen> or
+     <screen>+hide-referrer{http://www.yahoo.com/}</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="hide-user-agent">
+<title>hide-user-agent</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Conceal your type of browser and client operating system</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Replaces the value of the <quote>User-Agent:</quote> HTTP header
+    in client requests with the specified value.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Parameterized.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    Any user-defined string.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <warning> 
+    <para>
+     This breaks many web sites that depend on looking at this header in order
+     to customize their content for different browsers (which, by the
+     way, is <emphasis>NOT</emphasis> a <ulink
+     url="http://www.javascriptkit.com/javaindex.shtml">smart way to do
+     that</ulink>!).
+    </para>
+   </warning>
+   <para>
+    Using this action in multi-user setups or wherever different types of
+    browsers will access the same <application>Privoxy</application> is
+    <emphasis>not recommended</emphasis>. In single-user, single-browser
+    setups, you might use it to delete your OS version information from
+    the headers, because it is an invitation to exploit known bugs for your
+    OS. It is also occasionally useful to forge this in order to access 
+    sites that won't let you in otherwise (though there may be a good 
+    reason in some cases). Example of this: some MSN sites will not 
+    let <application>Mozilla</application> enter, yet forging to a 
+    <application>Netscape 6.1</application> user-agent works just fine.
+    (Must be just a silly MS goof, I'm sure :-).
+   </para>
+   <para>
+    This action is scheduled for improvement.
+   </para>
+   </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+     <screen>+hide-user-agent{Netscape 6.1 (X11; I; Linux 2.4.18 i686)}</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="kill-popups">
+<title>kill-popups<anchor id="kill-popup"></title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Eliminate those annoying pop-up windows</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    While loading the document, replace JavaScript code that opens
+    pop-up windows with (syntactically neutral) dummy code on the fly.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This action is easily confused with the built-in, hardwired <literal><link linkend="filter">filter</link></literal>
+    action, but there are important differences: For <literal>kill-popups</literal>,
+    the document need not be buffered, so it can be incrementally rendered while
+    downloading. But <literal>kill-popups</literal> doesn't catch as many pop-ups as
+    <literal><link
+    linkend="filter">filter</link>{<replaceable>popups</replaceable>}</literal>
+    does. 
+   </para>
+   <para>
+    Think of it as a fast and efficient replacement for a filter that you
+    can use if you don't want any filtering at all. Note that it doesn't make
+    sense to combine it with any <literal><link linkend="filter">filter</link></literal> action,
+    since as soon as one <literal><link linkend="filter">filter</link></literal> applies,
+    the whole document needs to be buffered anyway, which destroys the advantage of
+    the <literal>kill-popups</literal> action over its filter equivalent.
+   </para>
+   <para>
+    Killing all pop-ups is a dangerous business. Many shops and banks rely on
+    pop-ups to display forms, shopping carts etc, and killing only the unwanted pop-ups 
+    would require artificial intelligence in <application>Privoxy</application>.
+    If the only kind of pop-ups that you want to kill are exit consoles (those
+    <emphasis>really nasty</emphasis> windows that appear when you close an other
+    one), you might want to use
+    <literal><link
+    linkend="filter">filter</link>{<replaceable>js-annoyances</replaceable>}</literal>
+    instead. 
+   </para>
+
+  <!-- 
+   <para>
+    An alternate spelling is <literal>+kill-popup</literal>, which is 
+    interchangeable.
+   </para>
+ --> 
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para><screen>+kill-popups</screen></para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="limit-connect">
+<title>limit-connect</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Prevent abuse of <application>Privoxy</application> as a TCP proxy relay</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Specifies to which ports HTTP CONNECT requests are allowable.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Parameterized.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    A comma-separated list of ports or port ranges (the latter using dashes, with the minimum
+    defaulting to 0 and the maximum to 65K).
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    By default, i.e. if no <literal>limit-connect</literal> action applies,
+    <application>Privoxy</application> only allows HTTP CONNECT
+    requests to port 443 (the standard, secure HTTPS port). Use 
+    <literal>limit-connect</literal> if more fine-grained control is desired
+    for some or all destinations.
+   </para>
+   <para>
+    The CONNECT methods exists in HTTP to allow access to secure websites
+    (<quote>https://</quote> URLs) through proxies. It works very simply:
+    the proxy connects to the server on the specified port, and then
+    short-circuits its connections to the client and to the remote server.
+    This can be a big security hole, since CONNECT-enabled proxies can be
+    abused as TCP relays very easily.
+  </para>
+  <para>
+   If you don't know what any of this means, there probably is no reason to 
+   change this one, since the default is already very restrictive.
+  </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usages:</term>
+  <listitem>
+   <!-- I had trouble getting the spacing to look right in my browser -->
+   <!-- I probably have the wrong font setup, bollocks. -->
+   <!-- Apparently the emphasis tag uses a proportional font no matter what -->
+    <para>
+     <screen>+limit-connect{443}                   # This is the default and need not be specified.
++limit-connect{80,443}                # Ports 80 and 443 are OK.
++limit-connect{-3, 7, 20-100, 500-}   # Ports less than 3, 7, 20 to 100 and above 500 are OK.
++limit-connect{-}                     # All ports are OK (gaping security hole!)</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="prevent-compression">
+<title>prevent-compression</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+    Ensure that servers send the content uncompressed, so it can be
+    passed through <literal><link linkend="filter">filter</link></literal>s
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Adds a header to the request that asks for uncompressed transfer.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    More and more websites send their content compressed by default, which
+    is generally a good idea and saves bandwidth. But for the <literal><link
+    linkend="filter">filter</link></literal>, <literal><link linkend="deanimate-gifs">deanimate-gifs</link></literal>
+    and <literal><link linkend="kill-popups">kill-popups</link></literal> actions to work,
+    <application>Privoxy</application> needs access to the  uncompressed data.
+    Unfortunately, <application>Privoxy</application> can't yet(!)  uncompress, filter, and
+    re-compress the content on the fly. So if you want to ensure that all websites, including
+    those that normally compress, can be filtered, you need to use this action.
+   </para>
+   <para>
+    This will slow down transfers from those websites, though. If you use any of the above-mentioned
+    actions, you will typically want to use <literal>prevent-compression</literal> in conjunction
+    with them.
+   </para>
+   <para>
+    Note that some (rare) ill-configured sites don't handle requests for uncompressed
+    documents correctly (they send an empty document body). If you use <literal>prevent-compression</literal>
+    per default, you'll have to add exceptions for those sites. See the example for how to do that.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (sections):</term>
+  <listitem>
+   <para>
+    <screen># Set default:
+#
+{+prevent-compression}
+/ # Match all sites
+
+# Make exceptions for ill sites:
+#
+{-prevent-compression}
+www.debianhelp.org
+www.pclinuxonline.com</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="send-vanilla-wafer">
+<title>send-vanilla-wafer</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+    Feed log analysis scripts with useless data.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Sends a cookie with each request stating that you do not accept any copyright
+    on cookies sent to you, and asking the site operator not to track you.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The vanilla wafer is a (relatively) unique header and could conceivably be used to track you.
+   </para>
+   <para>
+    This action is rarely used and not enabled in the default configuration.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+     <screen>+send-vanilla-wafer</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="send-wafer">
+<title>send-wafer</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+    Send custom cookies or feed log analysis scripts with even more useless data.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Sends a custom, user-defined cookie with each request.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Multi-value.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    A string of the form <quote><replaceable class="option">name</replaceable>=<replaceable
+    class="parameter">value</replaceable></quote>.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    Being multi-valued, multiple instances of this action can apply to the same request,
+    resulting in multiple cookies being sent.
+   </para>
+   <para>
+    This action is rarely used and not enabled in the default configuration.
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Example usage (section):</term>
+  <listitem>
+   <para>
+    <screen>{+send-wafer{UsingPrivoxy=true}}
+my-internal-testing-server.void</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="session-cookies-only">
+<title>session-cookies-only</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+    Allow only temporary <quote>session</quote> cookies (for the current browser session <emphasis>only</emphasis>).
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Deletes the <quote>expires</quote> field from <quote>Set-Cookie:</quote> server headers.
+    Most browsers will not store such cookies permanently and forget them in between sessions.
+   </para>
+  </listitem>
+ </varlistentry>
+
+<varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Boolean.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    N/A
+   </para>
+  </listitem>
+ </varlistentry>
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    This is less strict than <literal><link linkend="crunch-incoming-cookies">crunch-incoming-cookies</link></literal> / 
+    <literal><link linkend="crunch-outgoing-cookies">crunch-outgoing-cookies</link></literal> and allows you to browse
+    websites that insist or rely on setting cookies, without compromising your privacy too badly.
+   </para>
+   <para>
+    Most browsers will not permanently store cookies that have been processed by
+    <literal>session-cookies-only</literal> and will forget about them between sessions.
+    This makes profiling cookies useless, but won't break sites which require cookies so
+    that you can log in for transactions. This is generally turned on for all 
+    sites, and is the recommended setting.
+   </para>
+   <para>
+    It makes <emphasis>no sense at all</emphasis> to use <literal>session-cookies-only</literal>
+    together with <literal><link linkend="crunch-incoming-cookies">crunch-incoming-cookies</link></literal> or
+    <literal><link linkend="crunch-outgoing-cookies">crunch-outgoing-cookies</link></literal>. If you do, cookies
+    will be plainly killed.
+   </para>
+   <para>
+    Note that it is up to the browser how it handles such cookies without an <quote>expires</quote>
+    field. If you use an exotic browser, you might want to try it out to be sure.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+     <screen>+session-cookies-only</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="set-image-blocker">
+<title>set-image-blocker</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Choose the replacement for blocked images</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+     This action alone doesn't do anything noticeable. If <emphasis>both</emphasis>
+     <literal><link linkend="block">block</link></literal> <emphasis>and</emphasis> <literal><link
+     linkend="handle-as-image">handle-as-image</link></literal> <emphasis>also</emphasis>
+     apply, i.e. if the request is to be blocked as an image,
+     <emphasis>then</emphasis> the parameter of this action decides what will be
+     sent as a replacement.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- Boolean, Parameterized, Multi-value -->
+  <listitem>
+   <para>Parameterized.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <itemizedlist>
+    <listitem>
+     <para>
+      <quote>pattern</quote> to send a built-in checkerboard pattern image. The image is visually
+      decent, scales very well, and makes it obvious where banners were busted.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      <quote>blank</quote> to send a built-in transparent image. This makes banners disappear
+      completely, but makes it hard to detect where <application>Privoxy</application> has blocked
+      images on a given page and complicates troubleshooting if <application>Privoxy</application>
+      has blocked innocent images, like navigation icons.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      <quote><replaceable class="parameter">target-url</replaceable></quote> to
+      send a redirect to <replaceable class="parameter">target-url</replaceable>. You can redirect
+      to any image anywhere, even in your local filesystem (via <quote>file:///</quote> URL).
+     </para>
+     <para>
+      A good application of redirects is to use special <application>Privoxy</application>-built-in
+      URLs, which send the built-in images, as <replaceable class="parameter">target-url</replaceable>.
+      This has the same visual effect as specifying <quote>blank</quote> or <quote>pattern</quote> in
+      the first place, but enables your browser to cache the replacement image, instead of requesting
+      it over and over again.
+     </para>
+    </listitem>
+   </itemizedlist>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    The URLs for the built-in images are <quote>http://config.privoxy.org/send-banner?type=<replaceable
+    class="parameter">type</replaceable></quote>, where <replaceable class="parameter">type</replaceable> is
+    either <quote>blank</quote> or <quote>pattern</quote>.
+   </para>
+   <para>
+    There is a third (advanced) type, called <quote>auto</quote>. It is <emphasis>NOT</emphasis> to be
+    used in <literal>set-image-blocker</literal>, but meant for use from <link linkend="filter-file">filters</link>.
+    Auto will select the type of image that would have applied to the referring page, had it been an image.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+    Built-in pattern:
+   </para>
+   <para>
+    <screen>+set-image-blocker{pattern}</screen>
+   </para>
+   <para>
+    Redirect to the BSD devil:
+   </para>
+   <para>
+    <screen>+set-image-blocker{http://www.freebsd.org/gifs/dae_up3.gif}</screen>
+   </para>
+   <para>
+    Redirect to the built-in pattern for better caching:
+   </para>
+   <para>
+    <screen>+set-image-blocker{http://config.privoxy.org/send-banner?type=pattern}</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3>
+<title>Summary</title>
+<para>
+ Note that many of these actions have the potential to cause a page to
+ misbehave, possibly even not to display at all. There are many ways 
+ a site designer may choose to design his site, and what HTTP header 
+ content, and other criteria, he may depend on. There is no way to have hard
+ and fast rules for all sites. See the <link
+ linkend="ACTIONSANAT">Appendix</link> for a brief example on troubleshooting
+ actions.
+</para>
+</sect3>
+</sect2>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="aliases">
+<title>Aliases</title>
+<para>
+ Custom <quote>actions</quote>, known to <application>Privoxy</application>
+ as <quote>aliases</quote>, can be defined by combining other actions.
+ These can in turn be invoked just like the built-in actions.
+ Currently, an alias name can contain any character except space, tab,
+ <quote>=</quote>,
+ <quote>{</quote> and <quote>}</quote>, but we <emphasis>strongly 
+ recommend</emphasis> that you only use <quote>a</quote> to <quote>z</quote>,
+ <quote>0</quote> to <quote>9</quote>, <quote>+</quote>, and <quote>-</quote>.
+ Alias names are not case sensitive, and are not required to start with a
+ <quote>+</quote> or <quote>-</quote> sign, since they are merely textually
+ expanded.
+</para>
+<para>
+ Aliases can be used throughout the actions file, but they <emphasis>must be
+ defined in a special section at the top of the file!</emphasis>
+ And there can only be one such section per actions file. Each actions file may
+ have its own alias section, and the aliases defined in it are only visible
+ within that file.
+</para>
+<para>
+ There are two main reasons to use aliases: One is to save typing for frequently
+ used combinations of actions, the other one is a gain in flexibility: If you
+ decide once how you want to handle shops by defining an alias called
+ <quote>shop</quote>, you can later change your policy on shops in
+ <emphasis>one</emphasis> place, and your changes will take effect everywhere
+ in the actions file where the <quote>shop</quote> alias is used. Calling aliases
+ by their purpose also makes your actions files more readable.
+</para>
+<para>
+ Currently, there is one big drawback to using aliases, though:
+ <application>Privoxy</application>'s built-in web-based action file
+ editor honors aliases when reading the actions files, but it expands
+ them before writing. So the effects of your aliases are of course preserved,
+ but the aliases themselves are lost when you edit sections that use aliases
+ with it.
+ This is likely to change in future versions of <application>Privoxy</application>.
+</para>
+
+<para>
+ Now let's define some aliases...
+</para>
+
+<para>
+ <screen>
+ # Useful custom aliases we can use later.
+ #
+ # Note the (required!) section header line and that this section
+ # must be at the top of the actions file!
+ #
+ {{alias}}
+
+ # These aliases just save typing later:
+ # (Note that some already use other aliases!)
+ #
+ +crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+ -crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ block-as-image      = +block +handle-as-image
+ mercy-for-cookies   = -crunch-all-cookies -session-cookies-only
+
+ # These aliases define combinations of actions
+ # that are useful for certain types of sites:
+ #
+ fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups
+ shop        = -crunch-all-cookies -filter{popups} -kill-popups
+
+ # Short names for other aliases, for really lazy people ;-)
+ #
+ c0 = +crunch-all-cookies
+ c1 = -crunch-all-cookies</screen>
+</para>
+
+<para>
+ ...and put them to use. These sections would appear in the lower part of an 
+ actions file and define exceptions to the default actions (as specified further
+ up for the <quote>/</quote> pattern):
+</para>
+
+<para>
+ <screen>
+ # These sites are either very complex or very keen on
+ # user data and require minimal interference to work:
+ #
+ {fragile}
+ .office.microsoft.com
+ .windowsupdate.microsoft.com
+ .nytimes.com
+
+ # Shopping sites:
+ # Allow cookies (for setting and retrieving your customer data)
+ #           
+ {shop}
+ .quietpc.com
+ .worldpay.com   # for quietpc.com
+ .scan.co.uk
+
+ # These shops require pop-ups:
+ #
+ {shop -kill-popups -filter{popups}}
+  .dabs.com
+  .overclockers.co.uk</screen>
+</para>
+
+<para>
+ Aliases like <quote>shop</quote> and <quote>fragile</quote> are often used for 
+ <quote>problem</quote> sites that require some actions to be disabled 
+ in order to function properly.
+</para>
+</sect2>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="act-examples">
+<title>Actions Files Tutorial</title>
+<para>
+ The above chapters have shown <link linkend="actions-file">which actions files
+ there are and how they are organized</link>, how actions are <link
+ linkend="actions">specified</link> and <link linkend="actions-apply">applied
+ to URLs</link>, how <link linkend="af-patterns">patterns</link> work, and how to
+ define and use <link linkend="aliases">aliases</link>. Now, let's look at an
+ example <filename>default.action</filename> and <filename>user.action</filename>
+ file and see how all these pieces come together:
+</para>
+
+<sect3><title>default.action</title>
+
+<para>
+Every config file should start with a short comment stating its purpose:
+</para>
+
+<para>
+ <screen># Sample default.action file &lt;developers@privoxy.org&gt;</screen>
+</para>
+
+<para>
+Then, since this is the <filename>default.action</filename> file, the
+first section is a special section for internal use that you needn't
+change or worry about:
+</para>
+
+<para>
+ <screen>
+##########################################################################
+# Settings -- Don't change! For internal Privoxy use ONLY.
+##########################################################################
+
+{{settings}}
+for-privoxy-version=3.0</screen>
+</para>
+
+<para>
+After that comes the (optional) alias section. We'll use the example
+section from the above <link linkend="aliases">chapter on aliases</link>,
+that also explains why and how aliases are used:
+</para>
+
+<para>
+ <screen>
+##########################################################################
+# Aliases
+##########################################################################
+{{alias}}
+
+# These aliases just save typing later:
+# (Note that some already use other aliases!)
+#
++crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+block-as-image      = +block +handle-as-image
+mercy-for-cookies   = -crunch-all-cookies -session-cookies-only
+
+# These aliases define combinations of actions
+# that are useful for certain types of sites:
+#
+fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups
+shop        = mercy-for-cookies -filter{popups} -kill-popups</screen>
+</para>
+
+<para>
+ Now come the regular sections, i.e. sets of actions, accompanied
+ by URL patterns to which they apply. Remember <emphasis>all actions
+ are disabled when matching starts</emphasis>, so we have to explicitly
+ enable the ones we want.
+</para>
+
+<para>
+ The first regular section is probably the most important. It has only
+ one pattern, <quote><literal>/</literal></quote>, but this pattern
+ <link linkend="af-patterns">matches all URLs</link>. Therefore, the
+ set of actions used in this <quote>default</quote> section <emphasis>will
+ be applied to all requests as a start</emphasis>. It can  be partly or
+ wholly overridden by later matches further down this file, or in user.action,
+ but it will still be largely responsible for your overall browsing
+ experience.
+</para>
+
+<para>
+ Again, at the start of matching, all actions are disabled, so there is
+ no real need to disable any actions here, but we will do that nonetheless,
+ to have a complete listing for your reference. (Remember: a <quote>+</quote>
+ preceding the action name enables the action, a <quote>-</quote> disables!).
+ Also note how this long line has been made more readable by splitting it into
+ multiple lines with line continuation.
+</para> 
+
+<para>
+ <screen>
+##########################################################################
+# "Defaults" section:
+##########################################################################
+ { \
+ -<link linkend="ADD-HEADER">add-header</link> \
+ -<link linkend="BLOCK">block</link> \
+ -<link linkend="CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</link> \
+ -<link linkend="CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</link> \
+ +<link linkend="DEANIMATE-GIFS">deanimate-gifs</link> \
+ -<link linkend="DOWNGRADE-HTTP-VERSION">downgrade-http-version</link> \
+ +<link linkend="FAST-REDIRECTS">fast-redirects</link> \
+ +<link linkend="FILTER-HTML-ANNOYANCES">filter{html-annoyances}</link> \
+ +<link linkend="FILTER-JS-ANNOYANCES">filter{js-annoyances}</link> \
+ -<link linkend="FILTER-CONTENT-COOKIES">filter{content-cookies}</link> \
+ +<link linkend="FILTER-POPUPS">filter{popups}</link> \
+ +<link linkend="FILTER-WEBBUGS">filter{webbugs}</link> \
+ -<link linkend="FILTER-REFRESH-TAGS">filter{refresh-tags}</link> \
+ -<link linkend="FILTER-FUN">filter{fun}</link> \
+ +<link linkend="FILTER-NIMDA">filter{nimda}</link> \
+ +<link linkend="FILTER-BANNERS-BY-SIZE">filter{banners-by-size}</link> \
+ -<link linkend="FILTER-SHOCKWAVE-FLASH">filter{shockwave-flash}</link> \
+ -<link linkend="FILTER-CRUDE-PARENTAL">filter{crude-parental}</link> \
+ -<link linkend="HANDLE-AS-IMAGE">handle-as-image</link> \
+ +<link linkend="HIDE-FORWARDED-FOR-HEADERS">hide-forwarded-for-headers</link> \
+ +<link linkend="HIDE-FROM-HEADER">hide-from-header{block}</link> \
+ +<link linkend="HIDE-REFERER">hide-referrer{forge}</link> \
+ -<link linkend="HIDE-USER-AGENT">hide-user-agent</link> \
+ -<link linkend="KILL-POPUPS">kill-popups</link> \
+ -<link linkend="LIMIT-CONNECT">limit-connect</link> \
+ +<link linkend="PREVENT-COMPRESSION">prevent-compression</link> \
+ -<link linkend="SEND-VANILLA-WAFER">send-vanilla-wafer</link> \
+ -<link linkend="SEND-WAFER">send-wafer</link> \
+ +<link linkend="SESSION-COOKIES-ONLY">session-cookies-only</link> \
+ +<link linkend="SET-IMAGE-BLOCKER">set-image-blocker{pattern}</link> \
+ }
+ / # forward slash will match *all* potential URL patterns.</screen>
+</para>
+
+<para>
+ The default behavior is now set. Note that some actions, like not hiding
+ the user agent, are part of a <quote>general policy</quote> that applies
+ universally and won't get any exceptions defined later. Other choices,
+ like not blocking (which is <emphasis>understandably</emphasis> the
+ default!) need exceptions, i.e. we need to specify explicitly what we
+ want to block in later sections.
+ We will also want to make exceptions from our general pop-up-killing,
+ and use our defined aliases for that.
+</para>
+
+<para>
+ The first of our specialized sections is concerned with <quote>fragile</quote>
+ sites, i.e. sites that require minimum interference, because they are either
+ very complex or very keen on tracking you (and have mechanisms in place that
+ make them unusable for people who avoid being tracked). We will simply use
+ our pre-defined <literal>fragile</literal> alias instead of stating the list
+ of actions explicitly:
+</para>
+
+<para>
+ <screen>
+##########################################################################
+# Exceptions for sites that'll break under the default action set:
+##########################################################################
+
+# "Fragile" Use a minimum set of actions for these sites (see alias above):
+#
+{ fragile }
+.office.microsoft.com           # surprise, surprise!
+.windowsupdate.microsoft.com</screen>
+</para>
+
+<para>
+ Shopping sites are not as fragile, but they typically
+ require cookies to log in, and pop-up windows for shopping
+ carts or item details. Again, we'll use a pre-defined alias:
+</para>
+<para>
+ <screen>
+# Shopping sites:
+#
+{ shop }
+.quietpc.com 
+.worldpay.com   # for quietpc.com
+.jungle.com
+.scan.co.uk</screen>
+</para>
+
+<para>
+ Then, there are sites which rely on pop-up windows (yuck!) to work.
+ Since we made pop-up-killing our default above, we need to make exceptions
+ now. <ulink url="http://www.mozilla.org/">Mozilla</ulink> users, who
+ can turn on smart handling of unwanted pop-ups in their browsers, can
+ safely choose
+ -<literal><link linkend="FILTER-POPUPS">filter{popups}</link></literal> (and
+ -<literal><link linkend="KILL-POPUPS">kill-popups</link></literal>) above
+ and hence don't need this section. Anyway, disabling an already disabled
+ action doesn't hurt, so we'll define our exceptions regardless of what was
+ chosen in the defaults section:
+</para>
+
+<para>
+ <screen>
+# These sites require pop-ups too :( 
+#
+{ -<link linkend="KILL-POPUPS">kill-popups</link> -<link linkend="FILTER-POPUPS">filter{popups}</link> }
+.dabs.com
+.overclockers.co.uk
+.deutsche-bank-24.de</screen>
+</para>
+
+<para>
+ The <literal><link linkend="FAST-REDIRECTS">fast-redirects</link></literal>
+ action, which we enabled per default above,  breaks some sites. So disable
+ it for popular sites where we know it misbehaves:
+</para>
+
+<para>
+ <screen>
+{ -<link linkend="FAST-REDIRECTS">fast-redirects</link> }
+login.yahoo.com
+edit.*.yahoo.com
+.google.com
+.altavista.com/.*(like|url|link):http
+.altavista.com/trans.*urltext=http
+.nytimes.com</screen>
+</para>
+
+<para>
+ It is important that <application>Privoxy</application> knows which
+ URLs belong to images, so that <emphasis>if</emphasis> they are to
+ be blocked, a substitute image can be sent, rather than an HTML page.
+ Contacting the remote site to find out is not an option, since it
+ would destroy the loading time advantage of banner blocking, and it
+ would feed the advertisers (in terms of money <emphasis>and</emphasis>
+ information). We can mark any URL as an image with the <literal><link
+ linkend="handle-as-image">handle-as-image</link></literal> action,
+ and marking all URLs that end in a known image file extension is a
+ good start:
+</para>
+
+<para>
+ <screen>
+##########################################################################
+# Images:
+##########################################################################
+
+# Define which file types will be treated as images, in case they get
+# blocked further down this file:
+#
+{ +<link linkend="HANDLE-AS-IMAGE">handle-as-image</link> }
+/.*\.(gif|jpe?g|png|bmp|ico)$</screen>
+</para>
+
+<para>
+ And then there are known banner sources. They often use scripts to
+ generate the banners, so it won't be visible from the URL that the
+ request is for an image. Hence we block them <emphasis>and</emphasis>
+ mark them as images in one go, with the help of our
+ <literal>block-as-image</literal> alias defined above. (We could of
+ course just as well use <literal>+<link linkend="block">block</link>
+ +<link linkend="handle-as-image">handle-as-image</link></literal> here.)
+ Remember that the type of the replacement image is chosen by the
+ <literal><link linkend="set-image-blocker">set-image-blocker</link></literal>
+ action. Since all URLs have matched the default section with its
+ <literal>+<link linkend="set-image-blocker">set-image-blocker</link>{pattern}</literal>
+ action before, it still applies and needn't be repeated:
+</para>
+
+<para>
+ <screen>
+# Known ad generators:
+#
+{ block-as-image }
+ar.atwola.com 
+.ad.doubleclick.net
+.ad.*.doubleclick.net
+.a.yimg.com/(?:(?!/i/).)*$
+.a[0-9].yimg.com/(?:(?!/i/).)*$
+bs*.gsanet.com
+bs*.einets.com
+.qkimg.net</screen>
+</para>
+
+<para>
+ One of the most important jobs of <application>Privoxy</application>
+ is to block banners. A huge bunch of them are already <quote>blocked</quote>
+ by the <literal><link linkend="filter">filter</link>{banners-by-size}</literal>
+ action, which we enabled above, and which deletes the references to banner
+ images from the pages while they are loaded, so the browser doesn't request
+ them anymore, and hence they don't need to be blocked here. But this naturally
+ doesn't catch all banners, and some people choose not to use filters, so we
+ need a comprehensive list of patterns for banner URLs here, and apply the
+ <literal><link linkend="block">block</link></literal> action to them.
+</para>
+<para>
+ First comes a bunch of generic patterns, which do most of the work, by
+ matching typical domain and path name components of banners. Then comes
+ a list of individual patterns for specific sites, which is omitted here
+ to keep the example short:
+</para>
+
+<para>
+ <screen>
+##########################################################################
+# Block these fine banners:
+##########################################################################
+{ <link linkend="BLOCK">+block</link> }
+
+# Generic patterns:
+# 
+ad*.
+.*ads.
+banner?.
+count*.
+/.*count(er)?\.(pl|cgi|exe|dll|asp|php[34]?)
+/(?:.*/)?(publicite|werbung|rekla(ma|me|am)|annonse|maino(kset|nta|s)?)/
+
+# Site-specific patterns (abbreviated):
+#
+.hitbox.com</screen>
+</para>
+
+<para>
+ You wouldn't believe how many advertisers actually call their banner
+ servers ads.<replaceable>company</replaceable>.com, or call the directory
+ in which the banners are stored simply <quote>banners</quote>. So the above
+ generic patterns are surprisingly effective.
+</para>
+<para>
+ But being very generic, they necessarily also catch URLs that we don't want
+ to block. The pattern <literal>.*ads.</literal> e.g. catches 
+ <quote>nasty-<emphasis>ads</emphasis>.nasty-corp.com</quote> as intended,
+ but also <quote>downlo<emphasis>ads</emphasis>.sourcefroge.net</quote> or
+ <quote><emphasis>ads</emphasis>l.some-provider.net.</quote> So here come some
+ well-known exceptions to the <literal>+<link linkend="BLOCK">block</link></literal>
+ section above.
+</para>
+<para>
+ Note that these are exceptions to exceptions from the default! Consider the URL
+ <quote>downloads.sourcefroge.net</quote>: Initially, all actions are deactivated,
+ so it wouldn't get blocked. Then comes the defaults section, which matches the
+ URL, but just deactivates the <literal><link linkend="BLOCK">block</link></literal>
+ action once again. Then it matches <literal>.*ads.</literal>, an exception to the
+ general non-blocking policy, and suddenly
+ <literal><link linkend="BLOCK">+block</link></literal> applies. And now, it'll match
+ <literal>.*loads.</literal>, where <literal><link linkend="BLOCK">-block</link></literal>
+ applies, so (unless it matches <emphasis>again</emphasis> further down) it ends up
+ with no <literal><link linkend="BLOCK">block</link></literal> action applying.
+</para>
+
+<para>
+ <screen>
+##########################################################################
+# Save some innocent victims of the above generic block patterns:
+##########################################################################
+
+# By domain:
+# 
+{ -<link linkend="BLOCK">block</link> }
+adv[io]*.  # (for advogato.org and advice.*)
+adsl.      # (has nothing to do with ads)
+ad[ud]*.   # (adult.* and add.*)
+.edu       # (universities don't host banners (yet!))
+.*loads.   # (downloads, uploads etc)
+
+# By path:
+#
+/.*loads/
+
+# Site-specific:
+#
+www.globalintersec.com/adv # (adv = advanced)
+www.ugu.com/sui/ugu/adv</screen>
+</para>
+
+<para>
+ Filtering source code can have nasty side effects,
+ so make an exception for our friends at sourceforge.net,
+ and all paths with <quote>cvs</quote> in them. Note that
+ <literal>-<link linkend="FILTER">filter</link></literal>
+ disables <emphasis>all</emphasis> filters in one fell swoop!
+</para>
+
+<para>
+ <screen>
+# Don't filter code!
+#
+{ -<link linkend="FILTER">filter</link> }
+/.*cvs
+.sourceforge.net</screen>
+</para>
+
+<para>
+ The actual <filename>default.action</filename> is of course more
+ comprehensive, but we hope this example made clear how it works.
+</para>
+
+</sect3>
+
+<sect3><title>user.action</title>
+
+<para>
+ So far we are painting with a broad brush by setting general policies,
+ which would be a reasonable starting point for many people. Now, 
+ you might want to be more specific and have customized rules that
+ are more suitable to your personal habits and preferences. These would
+ be for narrowly defined situations like your ISP or your bank, and should
+ be placed in <filename>user.action</filename>, which is parsed after all other 
+ actions files and hence has the last word, over-riding any previously
+ defined actions. <filename>user.action</filename> is also a 
+ <emphasis>safe</emphasis> place for your personal settings, since
+ <filename>default.action</filename> is actively maintained by the
+ <application>Privoxy</application> developers and you'll probably want
+ to install updated versions from time to time.
+</para>
+
+<para>
+ So let's look at a few examples of things that one might typically do in
+ <filename>user.action</filename>: 
+</para>
+
+
+<!-- brief sample user.action here -->
+
+<para>
+ <screen>
+# My user.action file. &lt;fred@foobar.com&gt;</screen>
+</para>
+
+<para>
+ As <link linkend="aliases">aliases</link> are local to the actions
+ file that they are defined in, you can't use the ones from
+ <filename>default.action</filename>, unless you repeat them here:
+</para>
+
+<para>
+ <screen>
+# (Re-)define aliases for this file:
+#
+{{alias}}
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+mercy-for-cookies   = -crunch-all-cookies -session-cookies-only
+fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups
+shop        = mercy-for-cookies -filter{popups} -kill-popups
+allow-ads   = -block -filter{banners-by-size} # (see below)</screen>
+</para>
+
+<para>
+ Say you have accounts on some sites that you visit regularly, and
+ you don't want to have to log in manually each time. So you'd like
+ to allow persistent cookies for these sites. The
+ <literal>mercy-for-cookies</literal> alias defined above does exactly
+ that, i.e. it disables crunching of cookies in any direction, and
+ processing of cookies to make them temporary.
+</para>
+
+<para>
+ <screen>
+{ mercy-for-cookies }
+sunsolve.sun.com
+slashdot.org
+.yahoo.com
+.msdn.microsoft.com
+.redhat.com</screen>
+</para>
+
+<para>
+ Your bank needs popups and is allergic to some filter, but you don't
+ know which, so you disable them all:
+</para>
+
+<para>
+ <screen>
+{ -<link linkend="FILTER">filter</link> -<link linkend="KILL-POPUPS">kill-popups</link> }
+.your-home-banking-site.com</screen>
+</para>
+
+<para>
+ While browsing the web with <application>Privoxy</application> you
+ noticed some ads that sneaked through, but you were too lazy to
+ report them through our fine and easy <link linkend="contact">feedback</link>
+ system, so you have added them here:
+</para>
+
+<para>
+ <screen>
+{ +<link linkend="BLOCK">block</link> }
+www.a-popular-site.com/some/unobvious/path
+another.popular.site.net/more/junk/here/</screen>
+</para>
+
+<para>
+ Note that, assuming the banners in the above example have regular image
+ extensions (most do),
+ <literal>+<link linkend="HANDLE-AS-IMAGE">handle-as-image</link></literal>
+ need not be specified, since all URLs ending in these extensions will
+ already have been tagged as images in the relevant section of 
+ <filename>default.action</filename> by now.
+</para>
+
+<para>
+ Then you noticed that the default configuration breaks Forbes Magazine,
+ but you were too lazy to find out which action is the culprit, and you
+ were again too lazy to give <link linkend="contact">feedback</link>, so
+ you just used the <literal>fragile</literal> alias on the site, and
+ -- whoa! -- it worked:
+</para>
+
+<para>
+<screen>
+{ fragile }
+.forbes.com</screen>
+</para>
+
+<para>
+ You like the <quote>fun</quote> text replacements in <filename>default.filter</filename>,
+ but it is disabled in the distributed actions file. (My colleagues on the team just
+ don't have a sense of humour, that's why! ;-). So you'd like to turn it on in your private,
+ update-safe config, once and for all:
+</para>
+
+<para>
+<screen>
+{ +<link linkend="filter-fun">filter{fun}</link> }
+/ # For ALL sites!</screen>
+</para>
+
+<para>
+ Note that the above is not really a good idea: There are exceptions
+ to the filters in <filename>default.action</filename> for things that
+ really shouldn't be filtered, like code on CVS->Web interfaces. Since
+ <filename>user.action</filename> has the last word, these exceptions
+ won't be valid for the <quote>fun</quote> filtering specified here.
+</para>
+
+<para>
+ Finally, you might think about how your favourite free websites are
+ funded, and find that they rely on displaying banner advertisements
+ to survive. So you might want to specifically allow banners for those
+ sites that you feel provide value to you:
+</para>
+
+<para>
+<screen>
+{ allow-ads }
+.sourceforge.net
+.slashdot.org
+.osdn.net</screen>   
+</para>
+
+<para>
+ Note that <literal>allow-ads</literal> has been aliased to 
+ <literal>-<link linkend="block">block</link></literal>
+ <literal>-<link linkend="filter-banners-by-size">filter{banners-by-size}</link></literal>
+ above.
+</para>
+</sect3>
+</sect2>
+
+<!--  ~  End section  ~  -->
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+
+<sect1 id="filter-file">
+<title>The Filter File</title>
+
+<para>
+ All text substitutions that can be invoked through the
+ <literal><link linkend="filter">filter</link></literal> action
+ must first be defined in the filter file, which is typically
+ called <filename>default.filter</filename> and which can be
+ selected through the <literal>
+ <link linkend="filterfile">filterfile</link></literal> config
+ option.
+</para>
+
+<para>
+ Typical reasons for doing such substitutions are to eliminate
+ common annoyances in HTML and JavaScript, such as pop-up windows,
+ exit consoles, crippled windows without navigation tools, the
+ infamous &lt;BLINK&gt; tag etc, to suppress images with certain
+ width and height attributes (standard banner sizes or web-bugs),
+ or just to have fun. The possibilities are endless.
+</para>
+
+<para>
+ Filtering works on any text-based document type, including plain
+ text, HTML, JavaScript, CSS etc. (all <literal>text/*</literal>
+ MIME types). Substitutions are made at the source level, so if
+ you want to <quote>roll your own</quote> filters, you should be
+ familiar with HTML syntax.
+</para>
+
+<para>
+ Just like the <link linkend="actions-file">actions files</link>, the
+ filter file is organized in sections, which are called <emphasis>filters</emphasis>
+ here. Each filter consists of a heading line, that starts with the
+ <emphasis>keyword</emphasis> <literal>FILTER:</literal>, followed by
+ the filter's <emphasis>name</emphasis>, and a short (one line) 
+ <emphasis>description</emphasis> of what it does. Below that line
+ come the <emphasis>jobs</emphasis>, i.e. lines that define the actual
+ text substitutions. By convention, the name of a filter
+ should describe what the filter <emphasis>eliminates</emphasis>. The
+ comment is used in the <ulink url="http://config.privoxy.org/">web-based
+ user interface</ulink>.
+</para>
+
+<para>
+ Once a filter called <replaceable>name</replaceable> has been defined
+ in the filter file, it can be invoked by using an action of the form
+ +<literal><link linkend="filter">filter</link>{<replaceable>name</replaceable>}</literal>
+ in any <link linkend="actions-file">actions file</link>.
+</para>
+<para>
+ A filter header line for a filter called <quote>foo</quote> could look
+ like this:
+</para>
+
+<para>
+ <screen>FILTER: foo Replace all "foo" with "bar"</screen>
+</para>
+
+<para>
+ Below that line, and up to the next header line, come the jobs that
+ define what text replacements the filter executes. They are specified
+ in a syntax that imitates <ulink url="http://www.perl.org/">Perl</ulink>'s
+ <literal>s///</literal> operator. If you are familiar with Perl, you
+ will find this to be quite intuitive, and may want to look at the
+ <ulink url="http://www.oesterhelt.org/pcrs/pcrs.1.html">PCRS man page</ulink>
+ for the subtle differences to Perl behaviour. Most notably, the non-standard
+ option letter <literal>U</literal> is supported, which turns the default
+ to ungreedy matching.
+</para>
+
+<para>
+ If you are new to regular expressions, you might want to take a look at
+ the <link linkend="regex">Appendix on regular expressions</link>, and
+ see the <ulink url="http://perldoc.com/perl5.6.1/pod/perl.html">Perl
+ manual</ulink> for
+ <ulink url="http://perldoc.com/perl5.6.1/pod/perlop.html#s-PATTERN-REPLACEMENT-egimosx">the 
+ <literal>s///</literal> operator's syntax</ulink> and <ulink
+ url="http://perldoc.com/perl5.6.1/pod/perlre.html">Perl-style regular
+ expressions</ulink> in general.
+ The below examples might also help to get you started.
+</para>
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+
+<sect2><title>Filter File Tutorial</title>
+<para>
+ Now, let's complete our <quote>foo</quote> filter. We have already defined
+ the heading, but the jobs are still missing. Since all it does is to replace
+ <quote>foo</quote> with <quote>bar</quote>, there is only one (trivial) job
+ needed:
+</para>
+
+<para>
+ <screen>s/foo/bar/</screen>
+</para>
+
+<para>
+ But wait! Didn't the comment say that <emphasis>all</emphasis> occurrences
+ of <quote>foo</quote> should be replaced? Our current job will only take
+ care of the first <quote>foo</quote> on each page. For global substitution,
+ we'll need to add the <literal>g</literal> option:
+</para>
+
+<para>
+ <screen>s/foo/bar/g</screen>
+</para>
+
+<para>
+ Our complete filter now looks like this:
+</para>
+<para>
+ <screen>FILTER: foo Replace all "foo" with "bar"
+s/foo/bar/g</screen>
+</para>
+
+<para>
+ Let's look at some real filters for more interesting examples. Here you see
+ a filter that protects against some common annoyances that arise from JavaScript
+ abuse. Let's look at its jobs one after the other:
+</para>
+
+
+<para>
+ <screen>
+FILTER: js-annoyances Get rid of particularly annoying JavaScript abuse
+
+# Get rid of JavaScript referrer tracking. Test page: http://www.randomoddness.com/untitled.htm
+#
+s|(&lt;script.*)document\.referrer(.*&lt;/script&gt;)|$1"Not Your Business!"$2|Usg</screen>
+</para>
+
+<para>
+ Following the header line and a comment, you see the job. Note that it uses
+ <literal>|</literal> as the delimiter instead of <literal>/</literal>, because
+ the pattern contains a forward slash, which would otherwise have to be escaped
+ by a backslash (<literal>\</literal>).
+</para>
+
+<para>
+ Now, let's examine the pattern: it starts with the text <literal>&lt;script.*</literal>
+ enclosed in parentheses. Since the dot matches any character, and <literal>*</literal>
+ means: <quote>Match an arbitrary number of the element left of myself</quote>, this
+ matches <quote>&lt;script</quote>, followed by <emphasis>any</emphasis> text, i.e.
+ it matches the whole page, from the start of the first &lt;script&gt; tag.
+</para>
+
+<para>
+ That's more than we want, but the pattern continues: <literal>document\.referrer</literal>
+ matches only the exact string <quote>document.referrer</quote>. The dot needed to
+ be <emphasis>escaped</emphasis>, i.e. preceded by a backslash, to take away its
+ special meaning as a joker, and make it just a regular dot. So far, the meaning is:
+ Match from the start of the first &lt;script&gt; tag in a the page, up to, and including,
+ the text <quote>document.referrer</quote>, if <emphasis>both</emphasis> are present
+ in the page (and appear in that order).
+</para>
+
+<para>
+ But there's still more pattern to go. The next element, again enclosed in parentheses,
+ is <literal>.*&lt;/script&gt;</literal>. You already know what <literal>.*</literal>
+ means, so the whole pattern translates to: Match from the start of the first  &lt;script&gt;
+ tag in a page to the end of the last &lt;script&gt; tag, provided that the text
+ <quote>document.referrer</quote> appears somewhere in between.
+</para>
+
+<para>
+ This is still not the whole story, since we have ignored the options and the parentheses:
+ The portions of the page matched by sub-patterns that are enclosed in parentheses, will be
+ remembered and be available through the variables <literal>$1, $2, ...</literal> in
+ the substitute. The <literal>U</literal> option switches to ungreedy matching, which means
+ that the first <literal>.*</literal> in the pattern will only <quote>eat up</quote> all
+ text in between <quote>&lt;script</quote> and the <emphasis>first</emphasis> occurrence
+ of <quote>document.referrer</quote>, and that the second <literal>.*</literal> will
+ only span the text up to the <emphasis>first</emphasis> <quote>&lt;/script&gt;</quote>
+ tag. Furthermore, the <literal>s</literal> option says that the match may span
+ multiple lines in the page, and the <literal>g</literal> option again means that the
+ substitution is global.
+</para>
+
+<para>
+ So, to summarize, the pattern means: Match all scripts that contain the text
+ <quote>document.referrer</quote>. Remember the parts of the script from
+ (and including) the start tag up to (and excluding) the string
+ <quote>document.referrer</quote> as <literal>$1</literal>, and the part following
+ that string, up to and including the closing tag, as <literal>$2</literal>.
+</para>
+
+<para>
+ Now the pattern is deciphered, but wasn't this about substituting things? So
+ lets look at the substitute: <literal>$1"Not Your Business!"$2</literal> is
+ easy to read: The text remembered as <literal>$1</literal>, followed by 
+ <literal>"Not Your Business!"</literal> (<emphasis>including</emphasis>
+ the quotation marks!), followed by the text remembered as <literal>$2</literal>.
+ This produces an exact copy of the original string, with the middle part
+ (the <quote>document.referrer</quote>) replaced by <literal>"Not Your
+ Business!"</literal>.
+</para>
+
+<para>
+ The whole job now reads: Replace <quote>document.referrer</quote> by
+ <literal>"Not Your Business!"</literal> wherever it appears inside a
+ &lt;script&gt tag. Note that this job won't break JavaScript syntax,
+ since both the original and the replacement are syntactically valid
+ string objects. The script just won't have access to the referrer
+ information anymore.
+</para>
+
+<para>
+ We'll show you two other jobs from the JavaScript taming department, but
+ this time only point out the constructs of special interest:
+</para>
+
+<para>
+ <screen>
+# The status bar is for displaying link targets, not pointless blahblah
+#
+s/window\.status\s*=\s*['"].*?['"]/dUmMy=1/ig</screen>
+</para>
+
+<para>
+ <literal>\s</literal> stands for whitespace characters (space, tab, newline,
+ carriage return, form feed), so that <literal>\s*</literal> means: <quote>zero
+ or more whitespace</quote>. The <literal>?</literal> in <literal>.*?</literal>
+ makes this matching of arbitrary text ungreedy. (Note that the <literal>U</literal>
+ option is not set). The <literal>['"]</literal> construct means: <quote>a single
+ <emphasis>or</emphasis> a double quote</quote>.
+</para>
+
+<para>
+ So what does this job do? It replaces assignments of single- or double-quoted
+ strings to the <quote>window.status</quote> object with a dummy assignment
+ (using a variable name that is hopefully odd enough not to conflict with
+ real variables in scripts). Thus, it catches many cases where e.g. pointless
+ descriptions are displayed in the status bar instead of the link target when
+ you move your mouse over links.
+</para>
+
+<para>
+ <screen>
+# Kill OnUnload popups. Yummy. Test: http://www.zdnet.com/zdsubs/yahoo/tree/yfs.html
+#
+s/(&lt;body .*)onunload(.*&gt;)/$1never$2/iU</screen>
+</para>
+
+<para>
+ Including the
+ <ulink url="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-eventgroupings-htmlevents">OnUnload
+ event binding</ulink> in the HTML DOM was a <emphasis>CRIME</emphasis>.
+ When I close a browser window, I want it to close and die. Basta.
+ This job replaces the <quote>onunload</quote> attribute in
+ <quote>&lt;body&gt</quote> tags with the dummy word <literal>never</literal>.
+ Note that the <literal>i</literal> option makes the pattern matching
+ case-insensitive.
+</para>
+
+<para>
+ The last example is from the fun department:
+</para>
+
+<para>
+ <screen>
+FILTER: fun Fun text replacements
+
+# Spice the daily news:
+#
+s/microsoft(?!\.com)/MicroSuck/ig</screen>
+</para>
+
+<para>
+ Note the <literal>(?!\.com)</literal> part (a so-called negative lookahead)
+ in the job's pattern, which means: Don't match, if the string 
+ <quote>.com</quote> appears directly following <quote>microsoft</quote>
+ in the page. This prevents links to microsoft.com from being messed, while
+ still replacing the word everywhere else.
+</para>
+
+<para>
+ <screen>
+# Buzzword Bingo (example for extended regex syntax)
+#
+s* industry[ -]leading \
+|  cutting[ -]edge \
+|  award[ -]winning # Comments are OK, too! \
+|  high[ -]performance \
+|  solutions[ -]based \
+|  unmatched \
+|  unparalleled \
+|  unrivalled \
+*&lt;font color="red"&gt;&lt;b&gt;BINGO!&lt;/b&gt;&lt;/font&gt; \
+*igx</screen>
+</para>
+
+<para>
+ The <literal>x</literal> option in this job turns on extended syntax, and allows for
+ e.g. the liberal use of (non-interpreted!) whitespace for nicer formatting.
+</para>
+
+<para>
+ You get the idea?
+</para>
+</sect2>
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1 id="templates">
+<title>Templates</title>
+<para>
+ All <application>Privoxy</application> built-in pages, i.e. error pages such as the 
+ <ulink url="http://show-the-404-error.page"><quote>404 - No Such Domain</quote>
+ error page</ulink>, the <ulink
+ url="http://ads.bannerserver.example.com/nasty-ads/sponsor.html"><quote>BLOCKED</quote>
+ page</ulink>
+ and all pages of its <ulink url="http://config.privoxy.org/">web-based
+ user interface</ulink>, are generated from <emphasis>templates</emphasis>. 
+ (<application>Privoxy</application> must be running for the above links to work as
+ intended.)
+</para>
+
+<para>
+ These templates are stored in a subdirectory of the <link linkend="confdir">configuration
+ directory</link> called <filename>templates</filename>. On unixish platforms,
+ this is typically
+ <ulink url="file:///etc/privoxy/templates/"><filename>/etc/privoxy/templates/</filename></ulink>.
+</para>
+
+<para>
+ The templates are basically normal HTML files, but with place-holders (called symbols
+ or exports), which <application>Privoxy</application> fills at run time. You can
+ edit the templates with a normal text editor, should you want to customize them.
+ (<emphasis>Not recommended for the casual user</emphasis>). Note that
+ just like in configuration files, lines starting with <literal>#</literal> are
+ ignored when the templates are filled in.
+</para>
+
+<para>
+ The place-holders are of the form <literal>@name@</literal>, and you will
+ find a list of available symbols, which vary from template to template,
+ in the comments at the start of each file. Note that these comments are not
+ always accurate, and that it's probably best to look at the existing HTML
+ code to find out which symbols are supported and what they are filled in with.
+</para>
+
+<para>
+ A special application of this substitution mechanism is to make whole
+ blocks of HTML code disappear when a specific symbol is set. We use this
+ for many purposes, one of them being to include the beta warning in all
+ our user interface (CGI) pages when <application>Privoxy</application>
+ in in an alpha or beta development stage:
+</para>
+
+<para>
+ <screen>
+&lt;!-- @if-unstable-start --&gt;
+
+  ... beta warning HTML code goes here ...
+
+&lt;!-- if-unstable-end@ --&gt;</screen>
+</para>
+
+<para>
+ If the "unstable" symbol is set, everything in between and including
+ <literal>@if-unstable-start</literal> and <literal>if-unstable-end@</literal>
+ will disappear, leaving nothing but an empty comment:
+</para>
+
+<para>
+ <screen>&lt;!--  --&gt;</screen>
+</para>
+
+<para>
+ There's also an if-then-else construct and an <literal>#include</literal>
+ mechanism, but you'll sure find out if you are inclined to edit the
+ templates ;-)
+</para>
+
+<para>
+ All templates refer to a style located at
+ <ulink url="http://config.privoxy.org/send-stylesheet"><literal>http://config.privoxy.org/send-stylesheet</literal></ulink>.
+ This is, of course, locally served by <application>Privoxy</application>
+ and the source for it can be found and edited in the
+ <filename>cgi-style.css</filename> template.
+</para>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1 id="contact"><title>Contacting the Developers, Bug Reporting and Feature
+Requests</title>
+
+<!-- Include contacting.sgml boilerplate: -->
+ &contacting;
+<!-- end boilerplate -->
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="copyright"><title><application>Privoxy</application> Copyright, License and History</title>
+
+<!-- Include copyright.sgml: -->
+ &copyright;
+<!-- end copyright -->
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2><title>License</title>
+<!-- Include copyright.sgml: -->
+ &license;
+<!-- end copyright -->
+</sect2>
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect2 id="history"><title>History</title>
+<!-- Include history.sgml: -->
+ &history;
+<!-- end history -->
+</sect2>
+
+<sect2 id="authors"><title>Authors</title>
+<!-- Include p-authors.sgml: -->
+ &p-authors;
+<!-- end authors -->
+</sect2>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="seealso"><title>See Also</title>
+<!-- Include seealso.sgml: -->
+ &seealso;
+<!-- end seealso -->
+</sect1>
+
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 id="appendix"><title>Appendix</title>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="regex">
+<title>Regular Expressions</title>
+<para>
+ <application>Privoxy</application> uses Perl-style <quote>regular
+ expressions</quote> in its <link linkend="actions-file">actions
+ files</link> and <link linkend="filter-file">filter file</link>,
+ through the <ulink url="http://www.pcre.org/">PCRE</ulink> and
+ <ulink url="http://www.oesterhelt.org/pcrs/">PCRS</ulink> libraries.
+</para>
+
+<para>
+ If you are reading this, you probably don't understand what <quote>regular
+ expressions</quote> are, or what they can do. So this will be a very brief
+ introduction only. A full explanation would require a <ulink
+ url="http://www.oreilly.com/catalog/regex/">book</ulink> ;-)
+</para>
+
+<para>
+ Regular expressions provide a language to describe patterns that can be
+ run against strings of characters (letter, numbers, etc), to see if they
+ match the string or not. The  patterns are themselves (sometimes complex)
+ strings of literal characters, combined with  wild-cards, and other special
+ characters, called meta-characters. The <quote>meta-characters</quote> have
+ special meanings and are used to build complex patterns to be matched against.
+ Perl Compatible Regular Expressions are an especially convenient
+ <quote>dialect</quote> of the regular expression language.
+</para>
+
+<para>
+ To make a simple analogy, we do something similar when we use wild-card
+ characters when listing files with the <command>dir</command> command in DOS. 
+ <literal>*.*</literal> matches all filenames. The <quote>special</quote>
+ character here is the asterisk which matches any and all characters. We can be
+ more specific and use <literal>?</literal> to match just individual
+ characters. So <quote>dir file?.text</quote> would match
+ <quote>file1.txt</quote>, <quote>file2.txt</quote>, etc. We are pattern
+ matching, using a similar technique to <quote>regular expressions</quote>!
+</para>
+
+<para>
+ Regular expressions do essentially the same thing, but are much, much more
+ powerful. There are many more <quote>special characters</quote> and ways of 
+ building complex patterns however. Let's look at a few of the common ones,
+ and then some examples:
+</para>
+
+<para><simplelist>
+ <member>
+  <emphasis>.</emphasis> - Matches any single character, e.g. <quote>a</quote>,
+  <quote>A</quote>, <quote>4</quote>, <quote>:</quote>, or <quote>@</quote>.
+ </member>
+</simplelist></para>
+
+<para><simplelist>
+ <member>
+  <emphasis>?</emphasis> - The preceding character or expression is matched ZERO or ONE
+  times. Either/or.
+ </member>
+</simplelist></para>
+
+<para><simplelist>
+ <member>
+  <emphasis>+</emphasis> - The preceding character or expression is matched ONE or MORE
+  times.
+ </member>
+</simplelist></para>
+
+<para><simplelist>
+ <member>
+  <emphasis>*</emphasis> - The preceding character or expression is matched ZERO or MORE
+  times.
+ </member>
+</simplelist></para>
+
+<para><simplelist>
+ <member>
+  <emphasis>\</emphasis> - The <quote>escape</quote> character denotes that
+  the following character should be taken literally. This is used where one of the 
+  special characters (e.g. <quote>.</quote>) needs to be taken literally and
+  not as a special meta-character. Example: <quote>example\.com</quote>, makes 
+  sure the period is recognized only as a period (and not expanded to its 
+  meta-character meaning of any single character).
+ </member>
+</simplelist></para>
+
+<para><simplelist>
+ <member>
+  <emphasis>[]</emphasis> - Characters enclosed in brackets will be matched if
+  any of the enclosed characters are encountered. For instance, <quote>[0-9]</quote>
+  matches any numeric digit (zero through nine). As an example, we can combine 
+  this with <quote>+</quote> to match any digit one of more times: <quote>[0-9]+</quote>.
+ </member>
+</simplelist></para>
+
+<para><simplelist>
+ <member>
+  <emphasis>()</emphasis> - parentheses are used to group a sub-expression,
+  or multiple sub-expressions.
+ </member>
+</simplelist></para>
+
+<para><simplelist>
+ <member>
+  <emphasis>|</emphasis> - The <quote>bar</quote> character works like an
+  <quote>or</quote> conditional statement. A match is successful if the
+  sub-expression on either side of <quote>|</quote> matches. As an example:
+  <quote>/(this|that) example/</quote> uses grouping and the bar character 
+  and would match either <quote>this example</quote> or <quote>that
+  example</quote>, and nothing else.
+ </member>
+</simplelist></para>
+
+<para>
+ These are just some of the ones you are likely to use when matching URLs with 
+ <application>Privoxy</application>, and is a long way from a definitive
+ list. This is enough to get us started with a few simple examples which may
+ be more illuminating:
+</para>
+
+<para>
+ <emphasis><literal>/.*/banners/.*</literal></emphasis> - A  simple example
+ that uses the common combination of <quote>.</quote> and <quote>*</quote> to 
+ denote any character, zero or more times. In other words, any string at all.
+ So we start with a literal forward slash, then our regular expression pattern 
+ (<quote>.*</quote>) another literal forward slash, the string
+ <quote>banners</quote>, another forward slash, and lastly another
+ <quote>.*</quote>. We are building 
+ a directory path here. This will match any file with the path that has a
+ directory named <quote>banners</quote> in it. The <quote>.*</quote> matches
+ any characters, and this could conceivably be more forward slashes, so it
+ might expand into a much longer looking path. For example, this could match:
+ <quote>/eye/hate/spammers/banners/annoy_me_please.gif</quote>, or just
+ <quote>/banners/annoying.html</quote>, or almost an infinite number of other
+ possible combinations, just so it has <quote>banners</quote> in the path
+ somewhere.
+</para>
+
+<para>
+ A now something a little more complex:
+</para>
+
+<para>
+ <emphasis><literal>/.*/adv((er)?ts?|ertis(ing|ements?))?/</literal></emphasis> - 
+ We have several literal forward slashes again (<quote>/</quote>), so we are
+ building another expression that is a file path statement. We have another 
+ <quote>.*</quote>, so we are matching against any conceivable sub-path, just so
+ it matches our expression. The only true literal that <emphasis>must
+ match</emphasis> our pattern is <application>adv</application>, together with
+ the forward slashes. What comes after the <quote>adv</quote> string is the
+ interesting part. 
+</para>
+
+<para>
+ Remember the <quote>?</quote> means the preceding expression (either a
+ literal character or anything grouped with <quote>(...)</quote> in this case)
+ can exist or not, since this means either zero or one match. So
+ <quote>((er)?ts?|ertis(ing|ements?))</quote> is optional, as are the
+ individual sub-expressions: <quote>(er)</quote>,
+ <quote>(ing|ements?)</quote>, and the <quote>s</quote>. The <quote>|</quote>
+ means <quote>or</quote>. We have two of those. For instance, 
+ <quote>(ing|ements?)</quote>, can expand to match either <quote>ing</quote> 
+ <emphasis>OR</emphasis> <quote>ements?</quote>. What is being done here, is an
+ attempt at matching as many variations of <quote>advertisement</quote>, and 
+ similar, as possible. So this would expand to match just <quote>adv</quote>,
+ or <quote>advert</quote>, or <quote>adverts</quote>, or
+ <quote>advertising</quote>, or <quote>advertisement</quote>, or
+ <quote>advertisements</quote>. You get the idea. But it would not match 
+ <quote>advertizements</quote> (with a <quote>z</quote>). We could fix that by
+ changing our regular expression to: 
+ <quote>/.*/adv((er)?ts?|erti(s|z)(ing|ements?))?/</quote>, which would then match
+ either spelling.
+</para>
+
+<para>
+ <emphasis><literal>/.*/advert[0-9]+\.(gif|jpe?g)</literal></emphasis> - Again 
+ another path statement with forward slashes. Anything in the square brackets 
+ <quote>[]</quote> can be matched. This is using <quote>0-9</quote> as a
+ shorthand expression to mean any digit one through nine. It is the same as
+ saying <quote>0123456789</quote>. So any digit matches. The <quote>+</quote>
+ means one or more of the preceding expression must be included. The preceding 
+ expression here is what is in the square brackets -- in this case, any digit 
+ one through nine. Then, at the end, we have a grouping: <quote>(gif|jpe?g)</quote>. 
+ This includes a <quote>|</quote>, so this needs to match the expression on
+ either side of that bar character also. A simple <quote>gif</quote> on one side, and the other
+ side will in turn match either <quote>jpeg</quote> or <quote>jpg</quote>,
+ since the <quote>?</quote> means the letter <quote>e</quote> is optional and
+ can be matched once or not at all. So we are building an expression here to
+ match image GIF or JPEG type image file. It must include the literal
+ string <quote>advert</quote>, then one or more digits, and a <quote>.</quote>
+ (which is now a literal, and not a special character, since it is escaped
+ with <quote>\</quote>), and lastly either <quote>gif</quote>, or
+ <quote>jpeg</quote>, or <quote>jpg</quote>. Some possible matches would
+ include: <quote>//advert1.jpg</quote>,
+ <quote>/nasty/ads/advert1234.gif</quote>,
+ <quote>/banners/from/hell/advert99.jpg</quote>. It would not match
+ <quote>advert1.gif</quote> (no leading slash), or
+ <quote>/adverts232.jpg</quote> (the expression does not include an
+ <quote>s</quote>), or <quote>/advert1.jsp</quote> (<quote>jsp</quote> is not
+ in the expression anywhere).
+</para>
+
+<para>
+ We are barely scratching the surface of regular expressions here so that you
+ can understand the default <application>Privoxy</application>
+ configuration files, and maybe use this knowledge to customize your own
+ installation. There is much, much more that can be done with regular
+ expressions. Now that you know enough to get started, you can learn more on
+ your own :/
+</para>
+
+<para>
+ More reading on Perl Compatible Regular expressions: 
+ <ulink url="http://www.perldoc.com/perl5.6/pod/perlre.html">http://www.perldoc.com/perl5.6/pod/perlre.html</ulink>
+</para>
+
+<para>
+ For information on regular expression based substititions and their applications
+ in filters, please see the <link linkend="filter-file">filter file tutorial</link>
+ in this manual.
+</para>
+</sect2>
+
+<!--  ~  End section  ~  -->
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2>
+<title><application>Privoxy</application>'s Internal Pages</title>
+
+<para>
+ Since <application>Privoxy</application> proxies each requested 
+ web page, it is easy for <application>Privoxy</application> to 
+ trap certain special URLs. In this way, we can talk directly to
+ <application>Privoxy</application>, and see how it is 
+ configured, see how our rules are being applied, change these 
+ rules and other configuration options, and even turn
+ <application>Privoxy's</application> filtering off, all with 
+ a web browser.
+
+</para>
+
+<para>
+ The URLs listed below are the special ones that allow direct access 
+ to <application>Privoxy</application>. Of course,
+ <application>Privoxy</application> must be running to access these. If 
+ not, you will get a friendly error message. Internet access is not 
+ necessary either.
+</para>
+
+<para>
+ <itemizedlist>
+
+ <listitem>
+  <para>  
+   Privoxy main page: 
+  </para>
+  <blockquote>
+   <para> 
+     <ulink url="http://config.privoxy.org/">http://config.privoxy.org/</ulink>
+   </para>
+  </blockquote>
+  <para>
+   There is a shortcut: <ulink url="http://p.p/">http://p.p/</ulink> (But it
+   doesn't provide a fallback to a real page, in case the request is not
+   sent through <application>Privoxy</application>)
+  </para>
+ </listitem>
+
+ <listitem>
+  <para>  
+    Show information about the current configuration, including viewing and 
+    editing of actions files:
+  </para>
+   <blockquote>
+   <para> 
+    <ulink url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+   </para>
+  </blockquote>
+ </listitem>
+ <listitem>
+  <para>  
+    Show the source code version numbers:
+  </para>
+  <blockquote>
+   <para> 
+    <ulink url="http://config.privoxy.org/show-version">http://config.privoxy.org/show-version</ulink>
+   </para>
+  </blockquote>
+ </listitem>
+ <listitem>
+  <para>  
+   Show the browser's request headers:
+  </para>
+  <blockquote>
+   <para> 
+    <ulink url="http://config.privoxy.org/show-request">http://config.privoxy.org/show-request</ulink>
+   </para>
+  </blockquote>
+ </listitem>
+ <listitem>
+  <para>  
+   Show which actions apply to a URL and why:
+  </para>
+   <blockquote>
+   <para> 
+    <ulink url="http://config.privoxy.org/show-url-info">http://config.privoxy.org/show-url-info</ulink>
+   </para>
+  </blockquote>
+ </listitem>
+ <listitem>
+  <para>  
+   Toggle Privoxy on or off. In this case, <quote>Privoxy</quote> continues 
+   to run, but only as a pass-through proxy, with no actions taking place:
+  </para>
+   <blockquote>
+   <para> 
+    <ulink url="http://config.privoxy.org/toggle">http://config.privoxy.org/toggle</ulink>
+   </para>
+  </blockquote>
+  <para>
+   Short cuts. Turn off, then on: 
+  </para>
+   <blockquote>
+   <para> 
+     <ulink url="http://config.privoxy.org/toggle?set=disable">http://config.privoxy.org/toggle?set=disable</ulink>
+   </para>
+  </blockquote>
+   <blockquote>
+   <para> 
+     <ulink url="http://config.privoxy.org/toggle?set=enable">http://config.privoxy.org/toggle?set=enable</ulink>
+   </para>
+  </blockquote>
+ </listitem>
+ </itemizedlist>
+</para>
+
+<para>
+ These may be bookmarked for quick reference. See next.
+
+</para>
+
+<sect3 id="bookmarklets">
+<title>Bookmarklets</title>
+<para>
+ Below are some <quote>bookmarklets</quote> to allow you to easily access a
+ <quote>mini</quote> version of some of <application>Privoxy's</application>
+ special pages. They are designed for MS Internet Explorer, but should work
+ equally well in Netscape, Mozilla, and other browsers which support
+ JavaScript. They are designed to run directly from your bookmarks - not by
+ clicking the links below (although that should work for testing).
+</para>
+<para>
+ To save them, right-click the link and choose <quote>Add to Favorites</quote>
+ (IE) or <quote>Add Bookmark</quote> (Netscape). You will get a warning that
+ the bookmark <quote>may not be safe</quote> - just click OK. Then you can run the
+ Bookmarklet directly from your favorites/bookmarks. For even faster access,
+ you can put them on the <quote>Links</quote> bar (IE) or the <quote>Personal
+ Toolbar</quote> (Netscape), and run them with a single click. 
+</para>
+
+<para>
+ <itemizedlist>
+
+  <listitem>
+   <para>
+    <ulink
+    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&#38;set=enabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Enable</ulink>
+   </para>
+  </listitem> 
+
+  <listitem>
+   <para>
+    <ulink
+    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&#38;set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Disable</ulink>
+   </para>
+  </listitem> 
+
+  <listitem>
+   <para>
+    <ulink
+    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&#38;set=toggle','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Toggle Privoxy</ulink> (Toggles between enabled and disabled)
+   </para>
+  </listitem> 
+
+  <listitem>
+   <para>
+    <ulink
+    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y','ijbstatus','width=250,height=2,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy- View Status</ulink>
+   </para>
+  </listitem> 
+
+  <listitem>
+   <para>
+    <ulink url="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions/index.php?url='+escape(location.href),'Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Submit Actions File Feedback</ulink>
+   </para>
+  </listitem> 
+  <listitem>
+   <para>
+    <ulink url="javascript:void(window.open('http://config.privoxy.org/show-url-info?url='+escape(location.href),'Why').focus());">Privoxy - Why?</ulink>
+   </para>
+  </listitem> 
+ </itemizedlist>
+</para>
+
+<para>
+ Credit: The site which gave us the general idea for these bookmarklets is
+ <ulink url="http://www.bookmarklets.com">www.bookmarklets.com</ulink>. They
+ have more information about bookmarklets. 
+</para>
+
+
+</sect3>
+
+</sect2>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="chain">
+<title>Chain of Events</title>
+<para>
+ Let's take a quick look at the basic sequence of events when a web page is 
+ requested by your browser and <application>Privoxy</application> is on duty:
+</para>
+
+<para>
+ <itemizedlist>
+ <listitem>
+  <para>
+   First, your web browser requests a web page. The browser knows to send 
+   the request to <application>Privoxy</application>, which will in turn, 
+   relay the request to the remote web server after passing the following 
+   tests: 
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   <application>Privoxy</application> traps any request for its own internal CGI 
+   pages (e.g http://p.p/) and sends the CGI page back to the browser.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Next, <application>Privoxy</application> checks to see if the URL 
+   matches any <link
+   linkend="BLOCK"><quote>+block</quote></link> patterns. If
+   so, the URL is then blocked, and the remote web server will not be contacted.
+   <link linkend="HANDLE-AS-IMAGE"><quote>+handle-as-image</quote></link> 
+   is then checked and if it does not match, an 
+   HTML <quote>BLOCKED</quote> page is sent back. Otherwise, if it does match,
+   an image is returned. The type of image depends on the setting of <link
+   linkend="SET-IMAGE-BLOCKER"><quote>+set-image-blocker</quote></link>
+   (blank, checkerboard pattern, or an HTTP redirect to an image elsewhere).
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Untrusted URLs are blocked. If URLs are being added to the
+   <filename>trust</filename> file, then that is done.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   If the URL pattern matches the <link
+   linkend="FAST-REDIRECTS"><quote>+fast-redirects</quote></link> action,
+   it is then processed. Unwanted parts of the requested URL are stripped.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Now the rest of the client browser's request headers are processed. If any
+   of these match any of the relevant actions (e.g. <link
+   linkend="HIDE-USER-AGENT"><quote>+hide-user-agent</quote></link>,
+   etc.), headers are suppressed or forged as determined by these actions and
+   their parameters.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   Now the web server starts sending its response back (i.e. typically a web page and related 
+   data).
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   First, the server headers are read and processed to determine, among other
+   things, the MIME type (document type) and encoding. The headers are then
+   filtered as deterimed by the 
+   <link linkend="CRUNCH-INCOMING-COOKIES"><quote>+crunch-incoming-cookies</quote></link>,
+   <link linkend="SESSION-COOKIES-ONLY"><quote>+session-cookies-only</quote></link>,
+   and <link linkend="DOWNGRADE-HTTP-VERSION"><quote>+downgrade-http-version</quote></link>
+   actions.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   If the <link linkend="KILL-POPUPS"><quote>+kill-popups</quote></link>
+   action applies, and it is an HTML or JavaScript document, the popup-code in the
+   response is filtered on-the-fly as it is received.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   If a <link linkend="FILTER"><quote>+filter</quote></link>
+   or <link
+   linkend="DEANIMATE-GIFS"><quote>+deanimate-gifs</quote></link>
+   action applies (and the document type fits the action), the rest of the page is
+   read into memory (up to a configurable limit). Then the filter rules (from
+   <filename>default.filter</filename>) are processed against the buffered
+   content. Filters are applied in the order they are specified in the
+   <filename>default.filter</filename> file. Animated GIFs, if present, are
+   reduced to either the first or last frame, depending on the action
+   setting.The entire page, which is now filtered, is then sent by
+   <application>Privoxy</application> back to your browser. 
+  </para>
+  <para>
+   If neither <link linkend="FILTER"><quote>+filter</quote></link>
+   or <link
+   linkend="DEANIMATE-GIFS"><quote>+deanimate-gifs</quote></link>
+   matches, then <application>Privoxy</application> passes the raw data through 
+   to the client browser as it becomes available.
+  </para>
+ </listitem> 
+ <listitem>
+  <para>
+   As the browser receives the now (probably filtered) page content, it 
+   reads and then requests any URLs that may be embedded within the page
+   source, e.g. ad images, stylesheets, JavaScript, other HTML documents (e.g.
+   frames), sounds, etc. For each of these objects, the browser issues a new
+   request. And each such request is in turn processed as above. Note that a
+   complex web page may have many such embedded URLs.
+  </para>
+ </listitem> 
+ </itemizedlist>
+</para>
+
+</sect2>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect2 id="actionsanat">
+<title>Anatomy of an Action</title>
+
+<para>
+ The way <application>Privoxy</application> applies 
+ <link linkend="ACTIONS">actions</link> and <link linkend="FILTER">filters</link>
+ to any given URL can be complex, and not always so
+ easy to understand what is happening. And sometimes we need to be able to
+ <emphasis>see</emphasis> just what <application>Privoxy</application> is
+ doing. Especially, if something <application>Privoxy</application> is doing
+ is causing us a problem inadvertently. It can be a little daunting to look at
+ the actions and filters files themselves, since they tend to be filled with
+ <link linkend="regex">regular expressions</link> whose consequences are not
+ always so obvious. 
+</para>
+
+<para>
+ One quick test to see if <application>Privoxy</application> is causing a problem 
+ or not, is to disable it temporarily. This should be the first troubleshooting 
+ step. See <link linkend="bookmarklets">the Bookmarklets</link> section on a quick 
+ and easy way to do this (be sure to flush caches afterward!).
+</para>
+
+<para>
+ <application>Privoxy</application> also provides the 
+ <ulink url="http://config.privoxy.org/show-url-info">http://config.privoxy.org/show-url-info</ulink>
+ page that can show us very specifically how <application>actions</application>
+ are being applied to any given URL. This is a big help for troubleshooting.
+</para>
+
+<para>
+ First, enter one URL (or partial URL) at the prompt, and then
+ <application>Privoxy</application> will tell us 
+ how the current configuration will handle it. This will not
+ help with filtering effects (i.e. the <link
+ linkend="FILTER"><quote>+filter</quote></link> action) from
+ the <filename>default.filter</filename> file since this is handled very
+ differently and not so easy to trap! It also will not tell you about any other
+ URLs that may be embedded within the URL you are testing. For instance, images
+ such as ads are expressed as URLs within the raw page source of HTML pages. So
+ you will only get info for the actual URL that is pasted into the prompt area
+ -- not any sub-URLs. If you want to know about embedded URLs like ads, you
+ will have to dig those out of the HTML source. Use your browser's <quote>View
+ Page Source</quote> option for this. Or right click on the ad, and grab the
+ URL.
+</para>
+
+<para>
+ Let's try an example, <ulink url="http://google.com">google.com</ulink>, 
+ and look at it one section at a time:
+</para>
+
+<para>
+ <screen>
+ Matches for http://google.com:
+
+ In file: default.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
+
+{-add-header 
+ -block 
+ -crunch-outgoing-cookies 
+ -crunch-incoming-cookies 
+ +deanimate-gifs{last} 
+ -downgrade-http-version 
+ +fast-redirects 
+ -filter{popups} 
+ -filter{fun} 
+ -filter{shockwave-flash} 
+ -filter{crude-parental} 
+ +filter{html-annoyances} 
+ +filter{js-annoyances} 
+ +filter{content-cookies} 
+ +filter{webbugs} 
+ +filter{refresh-tags} 
+ +filter{nimda} 
+ +filter{banners-by-size} 
+ +hide-forwarded-for-headers 
+ +hide-from-header{block} 
+ +hide-referer{forge} 
+ -hide-user-agent 
+ -handle-as-image 
+ -kill-popups 
+ -limit-connect 
+ +prevent-compression 
+ -send-vanilla-wafer 
+ -send-wafer 
+ +session-cookies-only 
+ +set-image-blocker{pattern} }
+/
+
+ { -session-cookies-only }
+ .google.com
+
+ { -fast-redirects }
+ .google.com
+
+In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
+(no matches in this file)  
+</screen>
+</para>
+
+<para>
+ This tells us how we have defined our 
+ <link linkend="ACTIONS"><quote>actions</quote></link>, and
+ which ones match for our example, <quote>google.com</quote>. The first listing
+ is any matches for the <filename>standard.action</filename> file. No hits at
+ all here on <quote>standard</quote>. Then next is <quote>default</quote>, or
+ our <filename>default.action</filename> file. The large, multi-line listing,
+ is how the actions are set to match for all URLs, i.e. our default settings.
+ If you look at your <quote>actions</quote> file, this would be the section
+ just below the <quote>aliases</quote> section near the top. This will apply to
+ all URLs as signified by the single forward slash at the end of the listing
+ -- <quote>/</quote>.
+</para>
+
+<para>
+ But we can define additional actions that would be exceptions to these general
+ rules, and then list specific URLs (or patterns) that these exceptions would
+ apply to. Last match wins. Just below this then are two explicit matches for
+ <quote>.google.com</quote>. The first is negating our previous cookie setting, 
+ which was for <link
+ linkend="SESSION-COOKIES-ONLY"><quote>+session-cookies-only</quote></link>
+ (i.e. not persistent). So we will allow persistent cookies for google. The
+ second turns <emphasis>off</emphasis> any 
+ <link
+ linkend="FAST-REDIRECTS"><quote>+fast-redirects</quote></link>
+ action, allowing this to take place unmolested. Note that there is a leading
+ dot here -- <quote>.google.com</quote>. This will match any hosts and
+ sub-domains, in the google.com domain also, such as
+ <quote>www.google.com</quote>. So, apparently, we have these two actions
+ defined somewhere in the lower part of our <filename>default.action</filename>
+ file, and <quote>google.com</quote> is referenced somewhere in these latter
+ sections.
+</para>
+
+<para>
+ Then, for our <filename>user.action</filename> file, we again have no hits.
+</para>
+
+<para>
+ And finally we pull it all together in the bottom section and summarize how
+ <application>Privoxy</application> is applying all its <quote>actions</quote> 
+ to <quote>google.com</quote>:
+
+</para>
+
+<para>
+ <screen>
+
+ Final results:
+ -add-header 
+ -block 
+ -crunch-outgoing-cookies 
+ -crunch-incoming-cookies 
+ +deanimate-gifs{last} 
+ -downgrade-http-version 
+ -fast-redirects 
+ -filter{popups} 
+ -filter{fun} 
+ -filter{shockwave-flash} 
+ -filter{crude-parental} 
+ +filter{html-annoyances} 
+ +filter{js-annoyances} 
+ +filter{content-cookies} 
+ +filter{webbugs} 
+ +filter{refresh-tags} 
+ +filter{nimda} 
+ +filter{banners-by-size} 
+ +hide-forwarded-for-headers 
+ +hide-from-header{block} 
+ +hide-referer{forge} 
+ -hide-user-agent 
+ -handle-as-image 
+ -kill-popups 
+ -limit-connect 
+ +prevent-compression 
+ -send-vanilla-wafer 
+ -send-wafer
+ -session-cookies-only 
+ +set-image-blocker{pattern} 
+</screen>
+</para>
+
+<para>
+ Notice the only difference here to the previous listing, is to 
+ <quote>fast-redirects</quote> and <quote>session-cookies-only</quote>.
+</para>
+
+<para>
+ Now another example, <quote>ad.doubleclick.net</quote>:
+</para>
+
+<para>
+ <screen>
+
+ { +block +handle-as-image }
+  .ad.doubleclick.net
+
+ { +block +handle-as-image }
+  ad*.
+
+ { +block +handle-as-image }
+  .doubleclick.net
+</screen>
+</para>
+
+<para>
+ We'll just show the interesting part here, the explicit matches. It is 
+ matched three different times. Each as an <quote>+block +handle-as-image</quote>,
+ which is the expanded form of one of our aliases that had been defined as: 
+ <quote>+imageblock</quote>. (<link
+ linkend="ALIASES"><quote>Aliases</quote></link> are defined in
+ the first section of the actions file and typically used to combine more 
+ than one action.)
+</para>
+
+<para>
+ Any one of these would have done the trick and blocked this as an unwanted 
+ image. This is unnecessarily redundant since the last case effectively 
+ would also cover the first. No point in taking chances with these guys 
+ though ;-) Note that if you want an ad or obnoxious 
+ URL to be invisible, it should be defined as <quote>ad.doubleclick.net</quote>
+ is done here -- as both a <link
+ linkend="BLOCK"><quote>+block</quote></link>
+ <emphasis>and</emphasis> an 
+ <link
+ linkend="HANDLE-AS-IMAGE"><quote>+handle-as-image</quote></link>.
+ The custom alias <quote>+imageblock</quote> just simplifies the process and make 
+ it more readable.
+</para>
+
+<para>
+ One last example. Let's try <quote>http://www.rhapsodyk.net/adsl/HOWTO/</quote>.
+ This one is giving us problems. We are getting a blank page. Hmmm ...
+</para>
+
+<para>
+ <screen>
+
+ Matches for http://www.rhapsodyk.net/adsl/HOWTO/:
+
+ In file: default.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
+
+ {-add-header 
+  -block 
+  -crunch-incoming-cookies 
+  -crunch-outgoing-cookies 
+  +deanimate-gifs 
+  -downgrade-http-version 
+  +fast-redirects 
+  +filter{html-annoyances} 
+  +filter{js-annoyances} 
+  +filter{kill-popups} 
+  +filter{webbugs} 
+  +filter{nimda} 
+  +filter{banners-by-size} 
+  +filter{hal} 
+  +filter{fun} 
+  +hide-forwarded-for-headers 
+  +hide-from-header{block} 
+  +hide-referer{forge} 
+  -hide-user-agent 
+  -handle-as-image 
+  +kill-popups 
+  +prevent-compression 
+  -send-vanilla-wafer 
+  -send-wafer 
+  +session-cookies-only 
+  +set-image-blocker{blank} }
+   /
+
+ { +block +handle-as-image }
+  /ads
+</screen>
+</para>
+
+<para>
+ Ooops, the <quote>/adsl/</quote> is matching <quote>/ads</quote>! But 
+ we did not want this at all! Now we see why we get the blank page. We could
+ now add a new action below this that explicitly does <emphasis>not</emphasis>
+ block (<quote>{-block}</quote>) paths with <quote>adsl</quote>. There are
+ various ways to handle such exceptions. Example:
+</para>
+
+<para>
+ <screen>
+
+ { -block }
+  /adsl
+</screen>
+</para>
+
+<para>
+ Now the page displays ;-) Be sure to flush your browser's caches when 
+ making such changes. Or, try using <literal>Shift+Reload</literal>.
+</para>
+
+<para>
+ But now what about a situation where we get no explicit matches like 
+ we did with:
+</para>
+
+<para>
+ <screen>
+
+ { +block +handle-as-image }
+ /ads
+</screen>
+</para>
+
+<para>
+ That actually was very telling and pointed us quickly to where the problem
+ was. If you don't get this kind of match, then it means one of the default 
+ rules in the first section is causing the problem. This would require some 
+ guesswork, and maybe a little trial and error to isolate the offending rule.
+ One likely cause would be one of the <quote>{+filter}</quote> actions. Try 
+ adding the URL for the site to one of aliases that turn off <quote>+filter</quote>:
+</para>
+
+<para>
+ <screen>
+
+ {shop}
+ .quietpc.com
+ .worldpay.com   # for quietpc.com
+ .jungle.com
+ .scan.co.uk
+ .forbes.com
+</screen>
+</para>
+
+<para>
+ <quote>{shop}</quote> is an <quote>alias</quote> that expands to 
+ <quote>{ -filter -session-cookies-only }</quote>.
+ Or you could do your own exception to negate filtering:
+
+</para>
+
+<para>
+ <screen>
+
+ {-filter}
+ .forbes.com
+</screen>
+</para>
+
+<para>
+ This would probably be most appropriately put in <filename>user.action</filename>, 
+ for local site exceptions.
+</para>
+
+<para>
+ <quote>{fragile}</quote> is an alias that disables most actions. This can be 
+ used as a last resort for problem sites. Remember to flush caches! If this 
+ still does not work, you will have to go through the remaining actions one by
+ one to find which one(s) is causing the problem.
+</para>
+
+</sect2>
+
+</sect1>
+
+ <!--
+
+ This program is free software; you can redistribute it 
+ and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A
+ PARTICULAR PURPOSE.  See the GNU General Public
+ License for more details.
+
+ The GNU General Public License should be included with
+ this file.  If not, you can view it at
+ http://www.gnu.org/copyleft/gpl.html
+ or write to the Free Software Foundation, Inc., 59
+ Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ $Log: user-manual.sgml,v $
+ Revision 1.122  2002/05/24 13:24:08  oes
+ Added Bookmarklet for one-click pre-filled access to show-url-info
+
+ Revision 1.121  2002/05/23 23:20:17  oes
+  - Changed more (all?) references to actions to the
+    <literal><link> style.
+  - Small fixes in the actions chapter
+  - Small clarifications in the quickstart to ad blocking
+  - Removed <emphasis> from <title>s since the new doc CSS
+    renders them red (bad in TOC).
+
+ Revision 1.120  2002/05/23 19:16:43  roro
+ Correct Debian specials (installation and startup).
+
+ Revision 1.119  2002/05/22 17:17:05  oes
+ Added Security hint
+
+ Revision 1.118  2002/05/21 04:54:55  hal9
+ -New Section: Quickstart to Ad Blocking
+ -Reformat Actions Anatomy to match new CGI layout
+
+ Revision 1.117  2002/05/17 13:56:16  oes
+  - Reworked & extended Templates chapter
+  - Small changes to Regex appendix
+  - #included authors.sgml into (C) and hist chapter
+
+ Revision 1.116  2002/05/17 03:23:46  hal9
+ Fixing merge conflict in Quickstart section.
+
+ Revision 1.115  2002/05/16 16:25:00  oes
+ Extended the Filter File chapter & minor fixes
+
+ Revision 1.114  2002/05/16 09:42:50  oes
+ More ulink->link, added some hints to Quickstart section
+
+ Revision 1.113  2002/05/15 21:07:25  oes
+ Extended and further commented the example actions files
+
+ Revision 1.112  2002/05/15 03:57:14  hal9
+ Spell check. A few minor edits here and there for better syntax and
+ clarification.
+
+ Revision 1.111  2002/05/14 23:01:36  oes
+ Fixing the fixes   
+
+ Revision 1.110  2002/05/14 19:10:45  oes
+ Restored alphabetical order of actions
+
+ Revision 1.109  2002/05/14 17:23:11  oes
+ Renamed the prevent-*-cookies actions, extended aliases section and moved it before the example AFs
+
+ Revision 1.108  2002/05/14 15:29:12  oes
+ Completed proofreading the actions chapter
+
+ Revision 1.107  2002/05/12 03:20:41  hal9
+ Small clarifications for 127.0.0.1 vs localhost for listen-address since this
+ apparently an important distinction for some OS's.
+
+ Revision 1.106  2002/05/10 01:48:20  hal9
+ This is mostly proposed copyright/licensing additions and changes. Docs
+ are still GPL, but licensing and copyright are more visible. Also, copyright
+ changed in doc header comments (eliminate references to JB except FAQ).
+
+ Revision 1.105  2002/05/05 20:26:02  hal9
+ Sorting out license vs copyright in these docs.
+
+ Revision 1.104  2002/05/04 08:44:45  swa
+ bumped version
+
+ Revision 1.103  2002/05/04 00:40:53  hal9
+ -Remove the TOC first page kludge. It's fixed proper now in ldp.dsl.in.
+ -Some minor additions to Quickstart.
+
+ Revision 1.102  2002/05/03 17:46:00  oes
+ Further proofread & reactivated short build instructions
+
+ Revision 1.101  2002/05/03 03:58:30  hal9
+ Move the user-manual config directive to top of section. Add note about
+ Privoxy needing read permissions for configs, and write for logs.
+
+ Revision 1.100  2002/04/29 03:05:55  hal9
+ Add clarification on differences of new actions files.
+
+ Revision 1.99  2002/04/28 16:59:05  swa
+ more structure in starting section
+
+ Revision 1.98  2002/04/28 05:43:59  hal9
+ This is the break up of configuration.html into multiple files. This
+ will probably break links elsewhere :(
+
+ Revision 1.97  2002/04/27 21:04:42  hal9
+ -Rewrite of Actions File example.
+ -Add section for user-manual directive in config.
+
+ Revision 1.96  2002/04/27 05:32:00  hal9
+ -Add short section to Filter Files to tie in with +filter action.
+ -Start rewrite of examples in Actions Examples (not finished).
+
+ Revision 1.95  2002/04/26 17:23:29  swa
+ bookmarks cleaned, changed structure of user manual, screen and programlisting cleanups, and numerous other changes that I forgot
+
+ Revision 1.94  2002/04/26 05:24:36  hal9
+ -Add most of Andreas suggestions to Chain of Events section.
+ -A few other minor corrections and touch up.
+
+ Revision 1.92  2002/04/25 18:55:13  hal9
+ More catchups on new actions files, and new actions names.
+ Other assorted cleanups, and minor modifications.
+
+ Revision 1.91  2002/04/24 02:39:31  hal9
+ Add 'Chain of Events' section.
+
+ Revision 1.90  2002/04/23 21:41:25  hal9
+ Linuxconf is deprecated on RH, substitute chkconfig.
+
+ Revision 1.89  2002/04/23 21:05:28  oes
+ Added hint for startup on Red Hat
+
+ Revision 1.88  2002/04/23 05:37:54  hal9
+ Add AmigaOS install stuff.
+
+ Revision 1.87  2002/04/23 02:53:15  david__schmidt
+ Updated OSX installation section
+ Added a few English tweaks here an there
+
+ Revision 1.86  2002/04/21 01:46:32  hal9
+ Re-write actions section.
+
+ Revision 1.85  2002/04/18 21:23:23  hal9
+ Fix ugly typo (mine).
+
+ Revision 1.84  2002/04/18 21:17:13  hal9
+ Spell Redhat correctly (ie Red Hat). A few minor grammar corrections.
+
+ Revision 1.83  2002/04/18 18:21:12  oes
+ Added RPM install detail
+
+ Revision 1.82  2002/04/18 12:04:50  oes
+ Cosmetics
+
+ Revision 1.81  2002/04/18 11:50:24  oes
+ Extended Install section - needs fixing by packagers
+
+ Revision 1.80  2002/04/18 10:45:19  oes
+ Moved text to buildsource.sgml, renamed some filters, details
+
+ Revision 1.79  2002/04/18 03:18:06  hal9
+ Spellcheck, and minor touchups.
+
+ Revision 1.78  2002/04/17 18:04:16  oes
+ Proofreading part 2
+
+ Revision 1.77  2002/04/17 13:51:23  oes
+ Proofreading, part one
+
+ Revision 1.76  2002/04/16 04:25:51  hal9
+ -Added 'Note to Upgraders' and re-ordered the 'Quickstart' section.
+ -Note about proxy may need requests to re-read config files.
+
+ Revision 1.75  2002/04/12 02:08:48  david__schmidt
+ Remove OS/2 building info... it is already in the developer-manual
+
+ Revision 1.74  2002/04/11 00:54:38  hal9
+ Add small section on submitting actions.
+
+ Revision 1.73  2002/04/10 18:45:15  swa
+ generated
+
+ Revision 1.72  2002/04/10 04:06:19  hal9
+ Added actions feedback  to Bookmarklets section
+
+ Revision 1.71  2002/04/08 22:59:26  hal9
+ Version update. Spell chkconfig correctly :)
+
+ Revision 1.70  2002/04/08 20:53:56  swa
+ ?
+
+ Revision 1.69  2002/04/06 05:07:29  hal9
+ -Add privoxy-man-page.sgml, for man page.
+ -Add authors.sgml for AUTHORS (and p-authors.sgml)
+ -Reworked various aspects of various docs.
+ -Added additional comments to sub-docs.
+
+ Revision 1.68  2002/04/04 18:46:47  swa
+ consistent look. reuse of copyright, history et. al.
+
+ Revision 1.67  2002/04/04 17:27:57  swa
+ more single file to be included at multiple points. make maintaining easier
+
+ Revision 1.66  2002/04/04 06:48:37  hal9
+ Structural changes to allow for conditional inclusion/exclusion of content
+ based on entity toggles, e.g. 'entity % p-not-stable  "INCLUDE"'. And
+ definition of internal entities, e.g. 'entity p-version "2.9.13"' that will
+ eventually be set by Makefile.
+ More boilerplate text for use across multiple docs.
+
+ Revision 1.65  2002/04/03 19:52:07  swa
+ enhance squid section due to user suggestion
+
+ Revision 1.64  2002/04/03 03:53:43  hal9
+ A few minor bug fixes, and touch ups. Ready for review.
+
+ Revision 1.63  2002/04/01 16:24:49  hal9
+ Define entities to include boilerplate text. See doc/source/*.
+
+ Revision 1.62  2002/03/30 04:15:53  hal9
+ - Fix privoxy.org/config links.
+ - Paste in Bookmarklets from Toggle page.
+ - Move Quickstart nearer top, and minor rework.
+
+ Revision 1.61  2002/03/29 01:31:08  hal9
+ Minor update.
+
+ Revision 1.60  2002/03/27 01:57:34  hal9
+ Added more to Anatomy section.
+
+ Revision 1.59  2002/03/27 00:54:33  hal9
+ Touch up intro for new name.
+
+ Revision 1.58  2002/03/26 22:29:55  swa
+ we have a new homepage!
+
+ Revision 1.57  2002/03/24 20:33:30  hal9
+ A few minor catch ups with name change.
+
+ Revision 1.56  2002/03/24 16:17:06  swa
+ configure needs to be generated.
+
+ Revision 1.55  2002/03/24 16:08:08  swa
+ we are too lazy to make a block-built
+ privoxy logo. hence removed the option.
+
+ Revision 1.54  2002/03/24 15:46:20  swa
+ name change related issue.
+
+ Revision 1.53  2002/03/24 11:51:00  swa
+ name change. changed filenames.
+
+ Revision 1.52  2002/03/24 11:01:06  swa
+ name change
+
+ Revision 1.51  2002/03/23 15:13:11  swa
+ renamed every reference to the old name with foobar.
+ fixed "application foobar application" tag, fixed
+ "the foobar" with "foobar". left junkbustser in cvs
+ comments and remarks to history untouched.
+
+ Revision 1.50  2002/03/23 05:06:21  hal9
+ Touch up.
+
+ Revision 1.49  2002/03/21 17:01:05  hal9
+ New section in Appendix.
+
+ Revision 1.48  2002/03/12 06:33:01  hal9
+ Catching up to Andreas and re_filterfile changes.
+
+ Revision 1.47  2002/03/11 13:13:27  swa
+ correct feedback channels
+
+ Revision 1.46  2002/03/10 00:51:08  hal9
+ Added section on JB internal pages in Appendix.
+
+ Revision 1.45  2002/03/09 17:43:53  swa
+ more distros
+
+ Revision 1.44  2002/03/09 17:08:48  hal9
+ New section on Jon's actions file editor, and move some stuff around.
+
+ Revision 1.43  2002/03/08 00:47:32  hal9
+ Added imageblock{pattern}.
+
+ Revision 1.42  2002/03/07 18:16:55  swa
+ looks better
+
+ Revision 1.41  2002/03/07 16:46:43  hal9
+ Fix a few markup problems for jade.
+
+ Revision 1.40  2002/03/07 16:28:39  swa
+ provide correct feedback channels
+
+ Revision 1.39  2002/03/06 16:19:28  hal9
+ Note on perceived filtering slowdown per FR.
+
+ Revision 1.38  2002/03/05 23:55:14  hal9
+ Stupid I did it again. Double hyphen in comment breaks jade.
+
+ Revision 1.37  2002/03/05 23:53:49  hal9
+ jade barfs on '- -' embedded in comments. - -user option broke it.
+
+ Revision 1.36  2002/03/05 22:53:28  hal9
+ Add new - - user option.
+
+ Revision 1.35  2002/03/05 00:17:27  hal9
+ Added section on command line options.
+
+ Revision 1.34  2002/03/04 19:32:07  oes
+ Changed default port to 8118
+
+ Revision 1.33  2002/03/03 19:46:13  hal9
+ Emphasis on where/how to report bugs, etc
+
+ Revision 1.32  2002/03/03 09:26:06  joergs
+ AmigaOS changes, config is now loaded from PROGDIR: instead of
+ AmiTCP:db/junkbuster/ if no configuration file is specified on the
+ command line.
+
+ Revision 1.31  2002/03/02 22:45:52  david__schmidt
+ Just tweaking
+
+ Revision 1.30  2002/03/02 22:00:14  hal9
+ Updated 'New Features' list. Ran through spell-checker.
+
+ Revision 1.29  2002/03/02 20:34:07  david__schmidt
+ Update OS/2 build section
+
+ Revision 1.28  2002/02/24 14:34:24  jongfoster
+ Formatting changes.  Now changing the doctype to DocBook XML 4.1
+ will work - no other changes are needed.
+
+ Revision 1.27  2002/01/11 14:14:32  hal9
+ Added a very short section on Templates
+
+ Revision 1.26  2002/01/09 20:02:50  hal9
+ Fix bug re: auto-detect config file changes.
+
+ Revision 1.25  2002/01/09 18:20:30  hal9
+ Touch ups for *.action files.
+
+ Revision 1.24  2001/12/02 01:13:42  hal9
+ Fix typo.
+
+ Revision 1.23  2001/12/02 00:20:41  hal9
+ Updates for recent changes.
+
+ Revision 1.22  2001/11/05 23:57:51  hal9
+ Minor update for startup now daemon mode.
+
+ Revision 1.21  2001/10/31 21:11:03  hal9
+ Correct 2 minor errors
+
+ Revision 1.18  2001/10/24 18:45:26  hal9
+ *** empty log message ***
+
+ Revision 1.17  2001/10/24 17:10:55  hal9
+ Catching up with Jon's recent work, and a few other things.
+
+ Revision 1.16  2001/10/21 17:19:21  swa
+ wrong url in documentation
+
+ Revision 1.15  2001/10/14 23:46:24  hal9
+ Various minor changes. Fleshed out SEE ALSO section.
+
+ Revision 1.13  2001/10/10 17:28:33  hal9
+ Very minor changes.
+
+ Revision 1.12  2001/09/28 02:57:04  hal9
+ Ditto :/
+
+ Revision 1.11  2001/09/28 02:25:20  hal9
+ Ditto.
+
+ Revision 1.9  2001/09/27 23:50:29  hal9
+ A few changes. A short section on regular expression in appendix.
+
+ Revision 1.8  2001/09/25 00:34:59  hal9
+ Some additions, and re-arranging.
+
+ Revision 1.7  2001/09/24 14:31:36  hal9
+ Diddling.
+
+ Revision 1.6  2001/09/24 14:10:32  hal9
+ Including David's OS/2 installation instructions.
+
+ Revision 1.2  2001/09/13 15:27:40  swa
+ cosmetics
+
+ Revision 1.1  2001/09/12 15:36:41  swa
+ source files for junkbuster documentation
+
+ Revision 1.3  2001/09/10 17:43:59  swa
+ first proposal of a structure.
+
+ Revision 1.2  2001/06/13 14:28:31  swa
+ docs should have an author.
+
+ Revision 1.1  2001/06/13 14:20:37  swa
+ first import of project's documentation for the webserver.
+
+ -->
+
+</article>
diff --git a/doc/source/webserver/index.sgml b/doc/source/webserver/index.sgml
new file mode 100644 (file)
index 0000000..d01cf4d
--- /dev/null
@@ -0,0 +1,287 @@
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!entity % dummy "INCLUDE"> 
+<!entity p-intro SYSTEM "privoxy.sgml">
+<!entity contacting SYSTEM "contacting.sgml">
+<!entity history SYSTEM "history.sgml">
+<!entity copyright SYSTEM "copyright.sgml">
+<!entity license SYSTEM "license.sgml">
+<!entity p-version "2.9.15">
+<!entity p-status "beta">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
+<!entity % p-text "IGNORE">        <!-- define we are not a text only doc -->
+<!entity % p-doc "INCLUDE">        <!-- and we are a formal doc           -->
+<!entity % p-readme "IGNORE">
+<!entity  my-copy "&copy;">        <!-- kludge for docbook2man            -->
+]>
+<!--
+ File        :  $Source: /cvsroot/ijbswa/current/doc/source/webserver/index.sgml,v $
+
+ Purpose     :  Index file of the project's homepage
+                This file belongs into
+                ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+                
+ $Id: index.sgml,v 1.15 2002/05/24 00:02:05 oes Exp $
+
+ Copyright (C) 2001, 2002 Privoxy Developers <developers@privoxy.org>
+ See LICENSE.
+
+ ========================================================================
+ NOTE: Please read developer-manual/documentation.html before touching 
+ anything in this, or other Privoxy documentation. 
+ ========================================================================
+
+ Note: This is the privoxy home page. The Makefile is adding additional
+ meta data and content via perl.
+
+-->
+
+<article id="index">
+<artheader>
+ <title>Privoxy - Homepage</title>
+
+<!-- copyright is at bottom of page -->
+
+ <keywordset>
+  <keyword>privoxy</keyword> <keyword>HTTP</keyword> <keyword>proxy</keyword> <keyword>privacy</keyword>
+  <keyword>popups</keyword>  <keyword>po-ups</keyword> <keyword>HTML</keyword> <keyword>JavaScript</keyword>
+  <keyword>cleaning</keyword> <keyword>blocking</keyword> <keyword>cleaner</keyword> <keyword>blocker</keyword>
+  <keyword>filter</keyword> <keyword>proxy</keyword> <keyword>junk</keyword> <keyword>ad</keyword>
+  <keyword>advertisement</keyword> <keyword>banner</keyword> <keyword>webbugs</keyword>
+  <keyword>web-bugs</keyword> <keyword>werbung</keyword> <keyword>junkbusters</keyword>
+  <keyword>junkbuster</keyword>
+ </keywordset>
+
+ <abstract>
+
+<![%dummy;[
+  <para>
+   <comment>
+    This is here to keep vim syntax file from breaking :/
+    If I knew enough to fix it, I would.
+    PLEASE DO NOT REMOVE! HB: hal@foobox.net
+   </comment>
+  </para>
+]]>
+
+<!-- Include privoxy.sgml boilerplate: -->
+  &p-intro;
+<!-- end boilerplate -->
+
+  <para>
+   The most recent release is &p-version; (&p-status;).
+  </para>
+
+ </abstract>
+</artheader>
+
+<!--   ~~~~~       New section      ~~~~~     -->
+
+
+<sect1 renderas="sect2" id="download" label=""><title>Download</title>
+<para>
+ <itemizedlist>
+  <listitem>
+   <para>
+    <ulink url="http://sourceforge.net/project/showfiles.php?group_id=11118">Download recent releases</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="http://cvs.sourceforge.net/cvstarballs/ijbswa-cvsroot.tar.gz">Download the latest CVS snapshot (source tarball)</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="user-manual/quickstart.html">Quickstart after installation</ulink>
+   </para>
+  </listitem>
+ </itemizedlist>
+</para>
+</sect1>
+
+<sect1 renderas="sect2" id="docs" label=""><title>Documentation</title>
+<para>
+ <itemizedlist>
+  <listitem>
+   <para>
+    <ulink url="user-manual/index.html">User manual</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="faq/index.html">Frequently Asked Questions</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="developer-manual/index.html">Developer Manual</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="man-page/privoxy-man-page.html">Classic Man Page</ulink>
+   </para>
+  </listitem>
+ </itemizedlist>
+</para>
+</sect1>
+
+<sect1 renderas="sect2" id="moreinfo" label=""><title>More information</title>
+<para>
+ <itemizedlist>
+  <listitem>
+   <para>
+    <ulink url="user-manual/contact.html">Support &amp; Service</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="user-manual/copyright.html">Copyright, License, History & Authors</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="user-manual/introduction.html#FEATURES">List of (new) Features</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="http://sourceforge.net/projects/ijbswa/">The project page</ulink> at <ulink url="http://sourceforge.net/">SourceForge</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="user-manual/seealso.html">Related links</ulink>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    <ulink url="team/index.html">Pictures of the Privoxy Team</ulink>
+   </para>
+  </listitem>
+ </itemizedlist>
+</para>
+</sect1>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect1 label="">
+<!-- dummy section, for spacing -->
+<title></title>
+<para>
+<!-- show the SF logo per AUP -->
+<informaltable frame=none label="" pgwide="1">
+ <tgroup cols=1 align="center" colsep=1 rowsep=1>
+  <colspec colname=c1 align="center">
+  <tbody>
+   <row>
+    <entry align="center">Prixoxy is developed on:</entry>
+   </row>
+   <row>
+    <entry align="center">
+     <ulink url="http://sourceforge.net/">
+      <inlinegraphic  fileref="http://sourceforge.net/sflogo.php?group_id=11118&#38;type=1&#38;dummy=.gif"></inlinegraphic>
+     </ulink>
+    </entry>
+   </row>
+  </tbody>
+ </tgroup>
+</informaltable>
+</para>
+
+
+<!--
+<informalfigure pgwide="1">
+ <ulink url="http://sourceforge.net/">
+  <inlinegraphic align="center" fileref="http://sourceforge.net/sflogo.php?group_id=11118&#38;type=1&#38;dummy=.gif"></inlinegraphic>
+ </ulink>
+</informalfigure>
+-->
+
+<!-- Formal copyright markup does not work here. HB. -->
+<para>
+ <subscript>
+  Copyright &copy; 2001, 2002 by Privoxy Developers
+ </subscript>
+</para>
+
+</sect1>
+ <!--
+
+ This program is free software; you can redistribute it 
+ and/or modify it under the terms of the GNU General
+ Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A
+ PARTICULAR PURPOSE.  See the GNU General Public
+ License for more details.
+
+ The GNU General Public License should be included with
+ this file.  If not, you can view it at
+ http://www.gnu.org/copyleft/gpl.html
+ or write to the Free Software Foundation, Inc., 59
+ Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ $Log: index.sgml,v $
+ Revision 1.15  2002/05/24 00:02:05  oes
+ Tried to make more useful and concise:
+   Reordered, no more TOC, link to instead of include info,
+   added some links. Should we use the free space to better
+   describe what Privoxy is good for?
+
+ Revision 1.14  2002/05/10 01:48:20  hal9
+ This is mostly proposed copyright/licensing additions and changes. Docs
+ are still GPL, but licensing and copyright are more visible. Also, copyright
+ changed in doc header comments (eliminate references to JB except FAQ).
+
+ Revision 1.13  2002/05/05 20:29:59  hal9
+ Ooops, fixing an accidental delete of title element.
+
+ Revision 1.12  2002/05/05 20:26:02  hal9
+ Sorting out license vs copyright in these docs.
+
+ Revision 1.11  2002/05/04 08:44:45  swa
+ bumped version
+
+ Revision 1.10  2002/04/26 17:24:31  swa
+ bookmarks cleaned, changed structure of user manual, screen and programlisting cleanups, and numerous other changes that I forgot
+
+ Revision 1.9  2002/04/14 01:00:07  hal9
+ Fix the logo properly with docbook.
+
+ Revision 1.7  2002/04/12 10:11:53  swa
+ changed bookmarklet text so that users can easily find the bookmark
+
+ Revision 1.6  2002/04/12 08:34:18  swa
+ added link to new page
+
+ Revision 1.5  2002/04/12 02:05:19  david__schmidt
+ Tiny English fix: infos -> info
+ Add copyright date 2002
+
+ Revision 1.4  2002/04/08 20:42:07  swa
+ fixed JB spelling
+
+ Revision 1.3  2002/04/07 20:27:18  hal9
+ Fix meta data.
+
+ Revision 1.2  2002/04/07 09:06:45  swa
+ users can now completely browse offline
+
+ Revision 1.1  2002/04/07 08:10:48  swa
+ create some of the webserver docs
+ automatically (in particular if
+ those docs recycle other documentation
+ fragments). Now committed webserver's
+ index file.
+
+
+ -->
+
+</article>
diff --git a/doc/text/developer-manual.txt b/doc/text/developer-manual.txt
new file mode 100644 (file)
index 0000000..99df01d
--- /dev/null
@@ -0,0 +1,2143 @@
+Privoxy Developer Manual
+
+Copyright Â© 2001, 2002 by Privoxy Developers
+
+$Id: developer-manual.sgml,v 1.42 2002/05/05 20:26:02 hal9 Exp $
+
+The developer manual gives the users information on how to help the developer
+team. It provides guidance on coding, testing, documentation and other issues.
+
+You can find the latest version of the this manual at http://www.privoxy.org/
+developer-manual/. Please see the Contact section on how to contact the
+developers.
+
+-------------------------------------------------------------------------------
+
+Table of Contents
+1. Introduction
+   
+    1.1. Quickstart to Privoxy Development
+   
+2. The CVS Repository
+   
+    2.1. Access to CVS
+    2.2. CVS Commit Guideline
+    2.3. Discussing Changes First
+   
+3. Documentation Guidelines
+   
+    3.1. Quickstart to Docbook and SGML
+    3.2. Privoxy Documentation Style
+    3.3. Privoxy Custom Entities
+   
+4. Coding Guidelines
+   
+    4.1. Introduction
+    4.2. Using Comments
+       
+        4.2.1. Comment, Comment, Comment
+        4.2.2. Use blocks for comments
+        4.2.3. Keep Comments on their own line
+        4.2.4. Comment each logical step
+        4.2.5. Comment All Functions Thoroughly
+        4.2.6. Comment at the end of braces if the content is more than one
+            screen length
+       
+    4.3. Naming Conventions
+       
+        4.3.1. Variable Names
+        4.3.2. Function Names
+        4.3.3. Header file prototypes
+        4.3.4. Enumerations, and #defines
+        4.3.5. Constants
+       
+    4.4. Using Space
+       
+        4.4.1. Put braces on a line by themselves.
+        4.4.2. ALL control statements should have a block
+        4.4.3. Do not belabor/blow-up boolean expressions
+        4.4.4. Use white space freely because it is free
+        4.4.5. Don't use white space around structure operators
+        4.4.6. Make the last brace of a function stand out
+        4.4.7. Use 3 character indentions
+       
+    4.5. Initializing
+       
+        4.5.1. Initialize all variables
+       
+    4.6. Functions
+       
+        4.6.1. Name functions that return a boolean as a question.
+        4.6.2. Always specify a return type for a function.
+        4.6.3. Minimize function calls when iterating by using variables
+        4.6.4. Pass and Return by Const Reference
+        4.6.5. Pass and Return by Value
+        4.6.6. Names of include files
+        4.6.7. Provide multiple inclusion protection
+        4.6.8. Use `extern "C"` when appropriate
+        4.6.9. Where Possible, Use Forward Struct Declaration Instead of
+            Includes
+       
+    4.7. General Coding Practices
+       
+        4.7.1. Turn on warnings
+        4.7.2. Provide a default case for all switch statements
+        4.7.3. Try to avoid falling through cases in a switch statement.
+        4.7.4. Use 'long' or 'short' Instead of 'int'
+        4.7.5. Don't mix size_t and other types
+        4.7.6. Declare each variable and struct on its own line.
+        4.7.7. Use malloc/zalloc sparingly
+        4.7.8. The Programmer Who Uses 'malloc' is Responsible for Ensuring
+            'free'
+        4.7.9. Add loaders to the `file_list' structure and in order
+        4.7.10. "Uncertain" new code and/or changes to existing code, use FIXME
+       
+    4.8. Addendum: Template for files and function comment blocks:
+   
+5. Testing Guidelines
+   
+    5.1. Testplan for releases
+    5.2. Test reports
+   
+6. Releasing a New Version
+   
+    6.1. Version numbers
+    6.2. Before the Release: Freeze
+    6.3. Building and Releasing the Packages
+       
+        6.3.1. Source Tarball
+        6.3.2. SuSE or Red Hat RPM
+        6.3.3. OS/2
+        6.3.4. Solaris
+        6.3.5. Windows
+        6.3.6. Debian
+        6.3.7. Mac OSX
+        6.3.8. FreeBSD
+        6.3.9. HP-UX 11
+        6.3.10. Amiga OS
+        6.3.11. AIX
+       
+    6.4. Uploading and Releasing Your Package
+    6.5. After the Release
+   
+7. Update the Webserver
+8. Contacting the developers, Bug Reporting and Feature Requests
+   
+    8.1. Get Support
+    8.2. Report bugs
+    8.3. Request new features
+    8.4. Report ads or other filter problems
+    8.5. Other
+   
+9. Privoxy Copyright, License and History
+   
+    9.1. License
+    9.2. History
+   
+10. See also
+
+1. Introduction
+
+Privoxy, as an heir to Junkbuster, is an Open Source project and licensed under
+the GPL. As such, Privoxy development is potentially open to anyone who has the
+time, knowledge, and desire to contribute in any capacity. Our goals are simply
+to continue the mission, to improve Privoxy, and to make it available to as
+wide an audience as possible.
+
+One does not have to be a programmer to contribute. Packaging, testing, and
+porting, are all important jobs as well.
+
+-------------------------------------------------------------------------------
+
+1.1. Quickstart to Privoxy Development
+
+You'll need an account on Sourceforge to support our development. Mail your ID
+to the list and wait until a project manager has added you.
+
+For the time being (read, this section is under construction), please refer to
+the extensive comments in the source code.
+
+-------------------------------------------------------------------------------
+
+2. The CVS Repository
+
+If you intend to help us with programming, documentation or packaging you will
+need write access to our holy grail, the CVS repository. Please read this
+chapter completely before accessing via CVS.
+
+-------------------------------------------------------------------------------
+
+2.1. Access to CVS
+
+The project's CVS repository is hosted on SourceForge. Please refer to the
+chapters 6 and 7 in SF's site documentation for the technical access details
+for your operating system. For historical reasons, the CVS server is called
+cvs.ijbswa.sourceforge.net, the repository is called ijbswa, and the source
+tree module is called current.
+
+-------------------------------------------------------------------------------
+
+2.2. CVS Commit Guideline
+
+The source tree is the heart of every software project. Every effort must be
+made to ensure that it is readable, compilable and consistent at all times. We
+therefore ask anyone with CVS access to strictly adhere to the following
+guidelines:
+
+  * Never (read: never, ever) be tempted to commit that small change without
+    testing it thoroughly first. When we're close to a public release, ask a
+    fellow developer to review your changes.
+   
+  * Your commit message should give a concise overview of what you changed (no
+    big details) and why you changed it Just check previous messages for good
+    examples.
+   
+  * Don't use the same message on multiple files, unless it equally applies to
+    all those files.
+   
+  * If your changes span multiple files, and the code won't recompile unless
+    all changes are commited (e.g. when changing the signature of a function),
+    then commit all files one after another, without long delays in beween. If
+    necessary, prepare the commit messages in advance.
+   
+  * Before changing things on CVS, make sure that your changes are in line with
+    the team's general consensus on what should be done (see below).
+   
+-------------------------------------------------------------------------------
+
+2.3. Discussing Changes First
+
+We don't have a too formal policy on this, just use common sense. Hints: If it
+is..
+
+ 1. ..a bugfix / clean-up / cosmetic thing: shoot
+   
+ 2. ..a new feature that can be turned off: shoot
+   
+ 3. ..a clear improvement w/o side effects on other parts of the code: shoot
+   
+ 4. ..a matter of taste: ask the list
+   
+ 5. ..a major redesign of some part of the code: ask the list
+   
+Note that near a major public release, we get a bit more cautious - if unsure,
+it doesn't hurt to ask first. There is always the possibility to submit a patch
+to the patches tracker instead.
+
+-------------------------------------------------------------------------------
+
+3. Documentation Guidelines
+
+All formal documents are maintained in Docbook SGML and located in the doc/
+source/* directory. You will need Docbook, the Docbook DTD's and the Docbook
+modular stylesheets (or comparable alternatives), and either jade or openjade
+(recommended) installed in order to build docs from source. Currently there is 
+user-manual, FAQ, and, of course this, the developer-manual in this format. The
+README, AUTHORS privoxy.1 (man page) files are also now maintained as Docbook
+SGML. The finished files are all in the top-level source directory are
+generated files! Also, index.html, the Privoxy home page, is maintained as
+SGML. DO NOT edit these directly. Edit the SGML source, or contact someone
+involved in the documentation (at present Stefan and Hal).
+
+Other, less formal documents (e.g. LICENSE, INSTALL) are maintained as plain
+text files in the top-level source directory. At least for the time being.
+
+Packagers are encouraged to include this documentation. For those without the
+ability to build the docs locally, text versions of each are kept in CVS. HTML
+versions are also now being kept in CVS under doc/webserver/*.
+
+Formal documents are built with the Makefile targets of make dok, or
+alternately make redhat-dok. If you have problems, try both. The build process
+uses the document SGML sources in doc/source/*/* to update all text files in
+doc/text/ and to update all HTML documents in doc/webserver/.
+
+Documentation writers should please make sure documents build successfully
+before committing to CVS, if possible.
+
+How do you update the webserver (i.e. the pages on privoxy.org)?
+
+ 1. First, build the docs by running make dok (or alternately make redhat-dok).
+   
+ 2. Run make webserver which copies all files from doc/webserver to the
+    sourceforge webserver via scp.
+   
+Finished docs should be occasionally submitted to CVS (doc/webserver/*/*.html)
+so that those without the ability to build them locally, have access to them if
+needed. This is especially important just prior to a new release! Please do
+this after the $VERSION and other release specific data in configure.in has
+been updated (this is done just prior to a new release).
+
+-------------------------------------------------------------------------------
+
+3.1. Quickstart to Docbook and SGML
+
+If you are not familiar with SGML, it is a markup language similar to HTML.
+Actually, not a mark up language per se, but a language used to define markup
+languages. In fact, HTML is an SGML application. Both will use "tags" to format
+text and other content. SGML tags can be much more varied, and flexible, but do
+much of the same kinds of things. The tags, or "elements", are definable in
+SGML. There is no set "standards". Since we are using Docbook, our tags are
+those that are defined by Docbook. Much of how the finish document is rendered
+is determined by the "stylesheets". The stylesheets determine how each tag gets
+translated to HTML, or other formats.
+
+Tags in Docbook SGML need to be always "closed". If not, you will likely
+generate errors. Example: <title>My Title</title>. They are also
+case-insensitive, but we strongly suggest using all lower case. This keeps
+compatibility with [Docbook] XML.
+
+Our documents use "sections" for the most part. Sections will be processed into
+HTML headers (e.g. h1 for sect1). The Docbook stylesheets will use these to
+also generate the Table of Contents for each doc. Our TOC's are set to a depth
+of three. Meaning sect1, sect2, and sect3 will have TOC entries, but sect4 will
+not. Each section requires a <title> element, and at least one <para>. There is
+a limit of five section levels in Docbook, but generally three should be
+sufficient for our purposes.
+
+Some common elements that you likely will use:
+
+<para></para>, paragraph delimiter. Most text needs to be within paragraph     
+elements (there are some exceptions).                                          
+<emphasis></emphasis>, the stylesheets make this italics.                      
+<filename></filename>, files and directories.                                  
+<command></command>, command examples.                                         
+<literallayout></literallayout>, like <pre>, more or less.                     
+<itemizedlist></itemizedlist>, list with bullets.                              
+<listitem></listitem>, member of the above.                                    
+<screen></screen>, screen output, implies <literallayout>.                     
+<ulink url="example.com"></ulink>, like HTML <a> tag.                          
+<quote></quote>, for, doh, quoting text.                                       
+
+Look at any of the existing docs for examples of all these and more.
+
+You might also find "Writing Documentation Using DocBook - A Crash Course"
+useful.
+
+-------------------------------------------------------------------------------
+
+3.2. Privoxy Documentation Style
+
+It will be easier if everyone follows a similar writing style. This just makes
+it easier to read what someone else has written if it is all done in a similar
+fashion.
+
+Here it is:
+
+  * All tags should be lower case.
+   
+  * Tags delimiting a block of text (even small blocks) should be on their own
+    line. Like:
+   
+     <para>
+      Some text goes here.
+     </para>
+           
+   
+    Tags marking individual words, or few words, should be in-line:
+   
+      Just to <emphasis>emphasize</emphasis>, some text goes here.
+           
+   
+  * Tags should be nested and step indented for block text like: (except
+    in-line tags)
+   
+     <para>
+      <itemizedlist>
+       <para>
+        <listitem>
+          Some text goes here in our list example.
+         </listitem>
+       </para>
+      </itemizedlist>
+     </para>
+           
+   
+    This makes it easier to find the text amongst the tags ;-)
+   
+  * Use white space to separate logical divisions within a document, like
+    between sections. Running everything together consistently makes it harder
+    to read and work on.
+   
+  * Do not hesitate to make comments. Comments can either use the <comment>
+    element, or the <!-- --> style comment familiar from HTML. (Note in Docbook
+    v4.x <comment> is replaced by <remark>.)
+   
+  * We have an international audience. Refrain from slang, or English
+    idiosyncrasies (too many to list :). Humor also does not translate well
+    sometimes.
+   
+  * Try to keep overall line lengths in source files to 80 characters or less
+    for obvious reasons. This is not always possible, with lengthy URLs for
+    instance.
+   
+  * Our documents are available in differing formats. Right now, they are just
+    plain text, and HTML, but PDF, and others is always a future possibility.
+    Be careful with URLs (<ulink>), and avoid this mistake:
+   
+    My favorite site is <ulink url="http://example.com">here</ulink>.
+   
+    This will render as "My favorite site is here", which is not real helpful
+    in a text doc. Better like this:
+   
+    My favorite site is <ulink url="http://example.com">example.com</ulink>.
+   
+  * All documents should be spell checked occasionally. aspell can check SGML
+    with the -H option. (ispell I think too.)
+   
+-------------------------------------------------------------------------------
+
+3.3. Privoxy Custom Entities
+
+Privoxy documentation is using a number of customized "entities" to facilitate
+documentation maintenance.
+
+We are using a set of "boilerplate" files with generic text, that is used by
+multiple docs. This way we can write something once, and use it repeatedly
+without having to re-write the same content over and over again. If editing
+such a file, keep in mind that it should be generic. That is the purpose; so it
+can be used in varying contexts without additional modifications.
+
+We are also using what Docbook calls "internal entities". These are like
+variables in programming. Well, sort of. For instance, we have the p-version
+entity that contains the current Privoxy version string. You are strongly
+encouraged to use these where possible. Some of these obviously require
+re-setting with each release (done by the Makefile). A sampling of custom
+entities are listed below. See any of the main docs for examples.
+
+  * Re- "boilerplate" text entities are defined like:
+   
+    <!entity supported SYSTEM "supported.sgml">
+   
+    In this example, the contents of the file, supported.sgml is available for
+    inclusion anywhere in the doc. To make this happen, just reference the now
+    defined entity: &supported; (starts with an ampersand and ends with a
+    semi-colon), and the contents will be dumped into the finished doc at that
+    point.
+   
+  * Commonly used "internal entities":
+   
+    p-version: the Privoxy version string, e.g. "2.9.15".                      
+    p-status: the project status, either "alpha", "beta", or "stable".         
+    p-not-stable: use to conditionally include text in "not stable" releases   
+    (e.g. "beta").                                                             
+    p-stable: just the opposite.                                               
+    p-text: this doc is only generated as text.                                
+   
+There are others in various places that are defined for a specific purpose.
+Read the source!
+
+-------------------------------------------------------------------------------
+
+4. Coding Guidelines
+
+4.1. Introduction
+
+This set of standards is designed to make our lives easier. It is developed
+with the simple goal of helping us keep the "new and improved Privoxy"
+consistent and reliable. Thus making maintenance easier and increasing chances
+of success of the project.
+
+And that of course comes back to us as individuals. If we can increase our
+development and product efficiencies then we can solve more of the request for
+changes/improvements and in general feel good about ourselves. ;->
+
+-------------------------------------------------------------------------------
+
+4.2. Using Comments
+
+4.2.1. Comment, Comment, Comment
+
+Explanation:
+
+Comment as much as possible without commenting the obvious. For example do not
+comment "aVariable is equal to bVariable". Instead explain why aVariable should
+be equal to the bVariable. Just because a person can read code does not mean
+they will understand why or what is being done. A reader may spend a lot more
+time figuring out what is going on when a simple comment or explanation would
+have prevented the extra research. Please help your brother IJB'ers out!
+
+The comments will also help justify the intent of the code. If the comment
+describes something different than what the code is doing then maybe a
+programming error is occurring.
+
+Example:
+
+/* if page size greater than 1k ... */                                         
+if ( PageLength() > 1024 )                                                     
+{                                                                              
+    ... "block" the page up ...                                                
+}                                                                              
+                                                                               
+/* if page size is small, send it in blocks */                                 
+if ( PageLength() > 1024 )                                                     
+{                                                                              
+    ... "block" the page up ...                                                
+}                                                                              
+                                                                               
+This demonstrates 2 cases of "what not to do".  The first is a                 
+"syntax comment".  The second is a comment that does not fit what              
+is actually being done.                                                        
+
+-------------------------------------------------------------------------------
+
+4.2.2. Use blocks for comments
+
+Explanation:
+
+Comments can help or they can clutter. They help when they are differentiated
+from the code they describe. One line comments do not offer effective
+separation between the comment and the code. Block identifiers do, by
+surrounding the code with a clear, definable pattern.
+
+Example:
+
+/*********************************************************************         
+ * This will stand out clearly in your code!                                   
+ *********************************************************************/        
+if ( thisVariable == thatVariable )                                            
+{                                                                              
+   DoSomethingVeryImportant();                                                 
+}                                                                              
+                                                                               
+                                                                               
+/* unfortunately, this may not */                                              
+if ( thisVariable == thatVariable )                                            
+{                                                                              
+   DoSomethingVeryImportant();                                                 
+}                                                                              
+                                                                               
+                                                                               
+if ( thisVariable == thatVariable ) /* this may not either */                  
+{                                                                              
+   DoSomethingVeryImportant();                                                 
+}                                                                              
+
+Exception:
+
+If you are trying to add a small logic comment and do not wish to "disrupt" the
+flow of the code, feel free to use a 1 line comment which is NOT on the same
+line as the code.
+
+-------------------------------------------------------------------------------
+
+4.2.3. Keep Comments on their own line
+
+Explanation:
+
+It goes back to the question of readability. If the comment is on the same line
+as the code it will be harder to read than the comment that is on its own line.
+
+There are three exceptions to this rule, which should be violated freely and
+often: during the definition of variables, at the end of closing braces, when
+used to comment parameters.
+
+Example:
+
+/*********************************************************************         
+ * This will stand out clearly in your code,                                   
+ * But the second example won't.                                               
+ *********************************************************************/        
+if ( thisVariable == thatVariable )                                            
+{                                                                              
+   DoSomethingVeryImportant();                                                 
+}                                                                              
+                                                                               
+if ( thisVariable == thatVariable ) /*can you see me?*/                        
+{                                                                              
+   DoSomethingVeryImportant(); /*not easily*/                                  
+}                                                                              
+                                                                               
+                                                                               
+/*********************************************************************         
+ * But, the encouraged exceptions:                                             
+ *********************************************************************/        
+int urls_read     = 0;     /* # of urls read + rejected */                     
+int urls_rejected = 0;     /* # of urls rejected */                            
+                                                                               
+if ( 1 == X )                                                                  
+{                                                                              
+   DoSomethingVeryImportant();                                                 
+}                                                                              
+                                                                               
+                                                                               
+short DoSomethingVeryImportant(                                                
+   short firstparam,   /* represents something */                              
+   short nextparam     /* represents something else */ )                       
+{                                                                              
+   ...code here...                                                             
+                                                                               
+}   /* -END- DoSomethingVeryImportant */                                       
+
+-------------------------------------------------------------------------------
+
+4.2.4. Comment each logical step
+
+Explanation:
+
+Logical steps should be commented to help others follow the intent of the
+written code and comments will make the code more readable.
+
+If you have 25 lines of code without a comment, you should probably go back
+into it to see where you forgot to put one.
+
+Most "for", "while", "do", etc... loops _probably_ need a comment. After all,
+these are usually major logic containers.
+
+-------------------------------------------------------------------------------
+
+4.2.5. Comment All Functions Thoroughly
+
+Explanation:
+
+A reader of the code should be able to look at the comments just prior to the
+beginning of a function and discern the reason for its existence and the
+consequences of using it. The reader should not have to read through the code
+to determine if a given function is safe for a desired use. The proper
+information thoroughly presented at the introduction of a function not only
+saves time for subsequent maintenance or debugging, it more importantly aids in
+code reuse by allowing a user to determine the safety and applicability of any
+function for the problem at hand. As a result of such benefits, all functions
+should contain the information presented in the addendum section of this
+document.
+
+-------------------------------------------------------------------------------
+
+4.2.6. Comment at the end of braces if the content is more than one screen
+length
+
+Explanation:
+
+Each closing brace should be followed on the same line by a comment that
+describes the origination of the brace if the original brace is off of the
+screen, or otherwise far away from the closing brace. This will simplify the
+debugging, maintenance, and readability of the code.
+
+As a suggestion , use the following flags to make the comment and its brace
+more readable:
+
+use following a closing brace: } /* -END- if() or while () or etc... */
+
+Example:
+
+if ( 1 == X )                                                                  
+{                                                                              
+   DoSomethingVeryImportant();                                                 
+   ...some long list of commands...                                            
+} /* -END- if x is 1 */                                                        
+                                                                               
+or:                                                                            
+                                                                               
+if ( 1 == X )                                                                  
+{                                                                              
+   DoSomethingVeryImportant();                                                 
+   ...some long list of commands...                                            
+} /* -END- if ( 1 == X ) */                                                    
+
+-------------------------------------------------------------------------------
+
+4.3. Naming Conventions
+
+4.3.1. Variable Names
+
+Explanation:
+
+Use all lowercase, and separate words via an underscore ('_'). Do not start an
+identifier with an underscore. (ANSI C reserves these for use by the compiler
+and system headers.) Do not use identifiers which are reserved in ANSI C++.
+(E.g. template, class, true, false, ...). This is in case we ever decide to
+port Privoxy to C++.
+
+Example:
+
+int ms_iis5_hack = 0;                                                          
+
+Instead of:
+
+int msiis5hack = 0; int msIis5Hack = 0;                                        
+
+-------------------------------------------------------------------------------
+
+4.3.2. Function Names
+
+Explanation:
+
+Use all lowercase, and separate words via an underscore ('_'). Do not start an
+identifier with an underscore. (ANSI C reserves these for use by the compiler
+and system headers.) Do not use identifiers which are reserved in ANSI C++.
+(E.g. template, class, true, false, ...). This is in case we ever decide to
+port Privoxy to C++.
+
+Example:
+
+int load_some_file( struct client_state *csp )                                 
+
+Instead of:
+
+int loadsomefile( struct client_state *csp )                                   
+int loadSomeFile( struct client_state *csp )                                   
+
+-------------------------------------------------------------------------------
+
+4.3.3. Header file prototypes
+
+Explanation:
+
+Use a descriptive parameter name in the function prototype in header files. Use
+the same parameter name in the header file that you use in the c file.
+
+Example:
+
+(.h) extern int load_aclfile( struct client_state *csp );                      
+(.c) int load_aclfile( struct client_state *csp )                              
+
+Instead of:
+
+(.h) extern int load_aclfile( struct client_state * ); or                      
+(.h) extern int load_aclfile();                                                
+(.c) int load_aclfile( struct client_state *csp )                              
+
+-------------------------------------------------------------------------------
+
+4.3.4. Enumerations, and #defines
+
+Explanation:
+
+Use all capital letters, with underscores between words. Do not start an
+identifier with an underscore. (ANSI C reserves these for use by the compiler
+and system headers.)
+
+Example:
+
+(enumeration) : enum Boolean { FALSE, TRUE };                                  
+(#define) : #define DEFAULT_SIZE 100;                                          
+
+Note: We have a standard naming scheme for #defines that toggle a feature in
+the preprocessor: FEATURE_>, where > is a short (preferably 1 or 2 word)
+description.
+
+Example:
+
+#define FEATURE_FORCE 1                                                        
+                                                                               
+#ifdef FEATURE_FORCE                                                           
+#define FORCE_PREFIX blah                                                      
+#endif /* def FEATURE_FORCE */                                                 
+
+-------------------------------------------------------------------------------
+
+4.3.5. Constants
+
+Explanation:
+
+Spell common words out entirely (do not remove vowels).
+
+Use only widely-known domain acronyms and abbreviations. Capitalize all letters
+of an acronym.
+
+Use underscore (_) to separate adjacent acronyms and abbreviations. Never
+terminate a name with an underscore.
+
+Example:
+
+#define USE_IMAGE_LIST 1                                                       
+
+Instead of:
+
+#define USE_IMG_LST 1 or                                                       
+#define _USE_IMAGE_LIST 1 or                                                   
+#define USE_IMAGE_LIST_ 1 or                                                   
+#define use_image_list 1 or                                                    
+#define UseImageList 1                                                         
+
+-------------------------------------------------------------------------------
+
+4.4. Using Space
+
+4.4.1. Put braces on a line by themselves.
+
+Explanation:
+
+The brace needs to be on a line all by itself, not at the end of the statement.
+Curly braces should line up with the construct that they're associated with.
+This practice makes it easier to identify the opening and closing braces for a
+block.
+
+Example:
+
+if ( this == that )                                                            
+{                                                                              
+   ...                                                                         
+}                                                                              
+
+Instead of:
+
+if ( this == that ) { ... }
+
+or
+
+if ( this == that ) { ... }
+
+Note: In the special case that the if-statement is inside a loop, and it is
+trivial, i.e. it tests for a condition that is obvious from the purpose of the
+block, one-liners as above may optically preserve the loop structure and make
+it easier to read.
+
+Status: developer-discretion.
+
+Example exception:
+
+while ( more lines are read )                                                  
+{                                                                              
+   /* Please document what is/is not a comment line here */                    
+   if ( it's a comment ) continue;                                             
+                                                                               
+   do_something( line );                                                       
+}                                                                              
+
+-------------------------------------------------------------------------------
+
+4.4.2. ALL control statements should have a block
+
+Explanation:
+
+Using braces to make a block will make your code more readable and less prone
+to error. All control statements should have a block defined.
+
+Example:
+
+if ( this == that )                                                            
+{                                                                              
+   DoSomething();                                                              
+   DoSomethingElse();                                                          
+}                                                                              
+
+Instead of:
+
+if ( this == that ) DoSomething(); DoSomethingElse();
+
+or
+
+if ( this == that ) DoSomething();
+
+Note: The first example in "Instead of" will execute in a manner other than
+that which the developer desired (per indentation). Using code braces would
+have prevented this "feature". The "explanation" and "exception" from the point
+above also applies.
+
+-------------------------------------------------------------------------------
+
+4.4.3. Do not belabor/blow-up boolean expressions
+
+Example:
+
+structure->flag = ( condition );                                               
+
+Instead of:
+
+if ( condition ) { structure->flag = 1; } else { structure->flag = 0; }
+
+Note: The former is readable and concise. The later is wordy and inefficient.
+Please assume that any developer new to the project has at least a "good"
+knowledge of C/C++. (Hope I do not offend by that last comment ... 8-)
+
+-------------------------------------------------------------------------------
+
+4.4.4. Use white space freely because it is free
+
+Explanation:
+
+Make it readable. The notable exception to using white space freely is listed
+in the next guideline.
+
+Example:
+
+int firstValue   = 0;                                                          
+int someValue    = 0;                                                          
+int anotherValue = 0;                                                          
+int thisVariable = 0;                                                          
+                                                                               
+if ( thisVariable == thatVariable )                                            
+                                                                               
+firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )            
+
+-------------------------------------------------------------------------------
+
+4.4.5. Don't use white space around structure operators
+
+Explanation:
+
+- structure pointer operator ( "->" ) - member operator ( "." ) - functions and
+parentheses
+
+It is a general coding practice to put pointers, references, and function
+parentheses next to names. With spaces, the connection between the object and
+variable/function name is not as clear.
+
+Example:
+
+aStruct->aMember;                                                              
+aStruct.aMember;                                                               
+FunctionName();                                                                
+
+Instead of: aStruct -> aMember; aStruct . aMember; FunctionName ();
+
+-------------------------------------------------------------------------------
+
+4.4.6. Make the last brace of a function stand out
+
+Example:
+
+int function1( ... )                                                           
+{                                                                              
+   ...code...                                                                  
+   return( retCode );                                                          
+                                                                               
+}   /* -END- function1 */                                                      
+                                                                               
+                                                                               
+int function2( ... )                                                           
+{                                                                              
+}   /* -END- function2 */                                                      
+
+Instead of:
+
+int function1( ... ) { ...code... return( retCode ); } int function2( ... ) { }
+
+Note: Use 1 blank line before the closing brace and 2 lines afterward. This
+makes the end of function standout to the most casual viewer. Although function
+comments help separate functions, this is still a good coding practice. In
+fact, I follow these rules when using blocks in "for", "while", "do" loops, and
+long if {} statements too. After all whitespace is free!
+
+Status: developer-discretion on the number of blank lines. Enforced is the end
+of function comments.
+
+-------------------------------------------------------------------------------
+
+4.4.7. Use 3 character indentions
+
+Explanation:
+
+If some use 8 character TABs and some use 3 character TABs, the code can look *
+very* ragged. So use 3 character indentions only. If you like to use TABs, pass
+your code through a filter such as "expand -t3" before checking in your code.
+
+Example:
+
+static const char * const url_code_map[256] =                                  
+{                                                                              
+   NULL, ...                                                                   
+};                                                                             
+                                                                               
+                                                                               
+int function1( ... )                                                           
+{                                                                              
+   if ( 1 )                                                                    
+   {                                                                           
+      return( ALWAYS_TRUE );                                                   
+   }                                                                           
+   else                                                                        
+   {                                                                           
+      return( HOW_DID_YOU_GET_HERE );                                          
+   }                                                                           
+                                                                               
+   return( NEVER_GETS_HERE );                                                  
+                                                                               
+}                                                                              
+
+-------------------------------------------------------------------------------
+
+4.5. Initializing
+
+4.5.1. Initialize all variables
+
+Explanation:
+
+Do not assume that the variables declared will not be used until after they
+have been assigned a value somewhere else in the code. Remove the chance of
+accidentally using an unassigned variable.
+
+Example:
+
+short anShort = 0;                                                             
+float aFloat  = 0;                                                             
+struct *ptr = NULL;                                                            
+
+Note: It is much easier to debug a SIGSEGV if the message says you are trying
+to access memory address 00000000 and not 129FA012; or arrayPtr[20] causes a
+SIGSEV vs. arrayPtr[0].
+
+Status: developer-discretion if and only if the variable is assigned a value
+"shortly after" declaration.
+
+-------------------------------------------------------------------------------
+
+4.6. Functions
+
+4.6.1. Name functions that return a boolean as a question.
+
+Explanation:
+
+Value should be phrased as a question that would logically be answered as a
+true or false statement
+
+Example:
+
+ShouldWeBlockThis();                                                           
+ContainsAnImage();                                                             
+IsWebPageBlank();                                                              
+
+-------------------------------------------------------------------------------
+
+4.6.2. Always specify a return type for a function.
+
+Explanation:
+
+The default return for a function is an int. To avoid ambiguity, create a
+return for a function when the return has a purpose, and create a void return
+type if the function does not need to return anything.
+
+-------------------------------------------------------------------------------
+
+4.6.3. Minimize function calls when iterating by using variables
+
+Explanation:
+
+It is easy to write the following code, and a clear argument can be made that
+the code is easy to understand:
+
+Example:
+
+for ( size_t cnt = 0; cnt < blockListLength(); cnt ++ )                        
+{                                                                              
+   ....                                                                        
+}                                                                              
+
+Note: Unfortunately, this makes a function call for each and every iteration.
+This increases the overhead in the program, because the compiler has to look up
+the function each time, call it, and return a value. Depending on what occurs
+in the blockListLength() call, it might even be creating and destroying
+structures with each iteration, even though in each case it is comparing "cnt"
+to the same value, over and over. Remember too - even a call to blockListLength
+() is a function call, with the same overhead.
+
+Instead of using a function call during the iterations, assign the value to a
+variable, and evaluate using the variable.
+
+Example:
+
+size_t len = blockListLength();                                                
+                                                                               
+for ( size_t cnt = 0; cnt < len; cnt ++ )                                      
+{                                                                              
+   ....                                                                        
+}                                                                              
+
+Exceptions: if the value of blockListLength() *may* change or could *
+potentially* change, then you must code the function call in the for/while
+loop.
+
+-------------------------------------------------------------------------------
+
+4.6.4. Pass and Return by Const Reference
+
+Explanation:
+
+This allows a developer to define a const pointer and call your function. If
+your function does not have the const keyword, we may not be able to use your
+function. Consider strcmp, if it were defined as: extern int strcmp( char *s1,
+char *s2 );
+
+I could then not use it to compare argv's in main: int main( int argc, const
+char *argv[] ) { strcmp( argv[0], "privoxy" ); }
+
+Both these pointers are *const*! If the c runtime library maintainers do it, we
+should too.
+
+-------------------------------------------------------------------------------
+
+4.6.5. Pass and Return by Value
+
+Explanation:
+
+Most structures cannot fit onto a normal stack entry (i.e. they are not 4 bytes
+or less). Aka, a function declaration like: int load_aclfile( struct
+client_state csp )
+
+would not work. So, to be consistent, we should declare all prototypes with
+"pass by value": int load_aclfile( struct client_state *csp )
+
+-------------------------------------------------------------------------------
+
+4.6.6. Names of include files
+
+Explanation:
+
+Your include statements should contain the file name without a path. The path
+should be listed in the Makefile, using -I as processor directive to search the
+indicated paths. An exception to this would be for some proprietary software
+that utilizes a partial path to distinguish their header files from system or
+other header files.
+
+Example:
+
+#include <iostream.h>     /* This is not a local include */                    
+#include "config.h"       /* This IS a local include */                        
+
+Exception:
+
+/* This is not a local include, but requires a path element. */                
+#include <sys/fileName.h>                                                      
+
+Note: Please! do not add "-I." to the Makefile without a _very_ good reason.
+This duplicates the #include "file.h" behavior.
+
+-------------------------------------------------------------------------------
+
+4.6.7. Provide multiple inclusion protection
+
+Explanation:
+
+Prevents compiler and linker errors resulting from redefinition of items.
+
+Wrap each header file with the following syntax to prevent multiple inclusions
+of the file. Of course, replace PROJECT_H with your file name, with "." Changed
+to "_", and make it uppercase.
+
+Example:
+
+#ifndef PROJECT_H_INCLUDED                                                     
+#define PROJECT_H_INCLUDED                                                     
+ ...                                                                           
+#endif /* ndef PROJECT_H_INCLUDED */                                           
+
+-------------------------------------------------------------------------------
+
+4.6.8. Use `extern "C"` when appropriate
+
+Explanation:
+
+If our headers are included from C++, they must declare our functions as
+`extern "C"`. This has no cost in C, but increases the potential re-usability
+of our code.
+
+Example:
+
+#ifdef __cplusplus                                                             
+extern "C"                                                                     
+{                                                                              
+#endif /* def __cplusplus */                                                   
+                                                                               
+... function definitions here ...                                              
+                                                                               
+#ifdef __cplusplus                                                             
+}                                                                              
+#endif /* def __cplusplus */                                                   
+
+-------------------------------------------------------------------------------
+
+4.6.9. Where Possible, Use Forward Struct Declaration Instead of Includes
+
+Explanation:
+
+Useful in headers that include pointers to other struct's. Modifications to
+excess header files may cause needless compiles.
+
+Example:
+
+/*********************************************************************         
+ * We're avoiding an include statement here!                                   
+ *********************************************************************/        
+struct file_list;                                                              
+extern file_list *xyz;                                                         
+
+Note: If you declare "file_list xyz;" (without the pointer), then including the
+proper header file is necessary. If you only want to prototype a pointer,
+however, the header file is unnecessary.
+
+Status: Use with discretion.
+
+-------------------------------------------------------------------------------
+
+4.7. General Coding Practices
+
+4.7.1. Turn on warnings
+
+Explanation
+
+Compiler warnings are meant to help you find bugs. You should turn on as many
+as possible. With GCC, the switch is "-Wall". Try and fix as many warnings as
+possible.
+
+-------------------------------------------------------------------------------
+
+4.7.2. Provide a default case for all switch statements
+
+Explanation:
+
+What you think is guaranteed is never really guaranteed. The value that you
+don't think you need to check is the one that someday will be passed. So, to
+protect yourself from the unknown, always have a default step in a switch
+statement.
+
+Example:
+
+switch( hash_string( cmd ) )                                                   
+{                                                                              
+   case hash_actions_file :                                                    
+      ... code ...                                                             
+      break;                                                                   
+                                                                               
+   case hash_confdir :                                                         
+      ... code ...                                                             
+      break;                                                                   
+                                                                               
+   default :                                                                   
+      log_error( ... );                                                        
+      ... anomaly code goes here ...                                           
+      continue; / break; / exit( 1 ); / etc ...                                
+                                                                               
+} /* end switch( hash_string( cmd ) ) */                                       
+
+Note: If you already have a default condition, you are obviously exempt from
+this point. Of note, most of the WIN32 code calls `DefWindowProc' after the
+switch statement. This API call *should* be included in a default statement.
+
+Another Note: This is not so much a readability issue as a robust programming
+issue. The "anomaly code goes here" may be no more than a print to the STDERR
+stream (as in load_config). Or it may really be an ABEND condition.
+
+Status: Programmer discretion is advised.
+
+-------------------------------------------------------------------------------
+
+4.7.3. Try to avoid falling through cases in a switch statement.
+
+Explanation:
+
+In general, you will want to have a 'break' statement within each 'case' of a
+switch statement. This allows for the code to be more readable and
+understandable, and furthermore can prevent unwanted surprises if someone else
+later gets creative and moves the code around.
+
+The language allows you to plan the fall through from one case statement to
+another simply by omitting the break statement within the case statement. This
+feature does have benefits, but should only be used in rare cases. In general,
+use a break statement for each case statement.
+
+If you choose to allow fall through, you should comment both the fact of the
+fall through and reason why you felt it was necessary.
+
+-------------------------------------------------------------------------------
+
+4.7.4. Use 'long' or 'short' Instead of 'int'
+
+Explanation:
+
+On 32-bit platforms, int usually has the range of long. On 16-bit platforms,
+int has the range of short.
+
+Status: open-to-debate. In the case of most FSF projects (including X/
+GNU-Emacs), there are typedefs to int4, int8, int16, (or equivalence ... I
+forget the exact typedefs now). Should we add these to IJB now that we have a
+"configure" script?
+
+-------------------------------------------------------------------------------
+
+4.7.5. Don't mix size_t and other types
+
+Explanation:
+
+The type of size_t varies across platforms. Do not make assumptions about
+whether it is signed or unsigned, or about how long it is. Do not compare a
+size_t against another variable of a different type (or even against a
+constant) without casting one of the values. Try to avoid using size_t if you
+can.
+
+-------------------------------------------------------------------------------
+
+4.7.6. Declare each variable and struct on its own line.
+
+Explanation:
+
+It can be tempting to declare a series of variables all on one line. Don't.
+
+Example:
+
+long a = 0;                                                                    
+long b = 0;                                                                    
+long c = 0;                                                                    
+
+Instead of:
+
+long a, b, c;
+
+Explanation: - there is more room for comments on the individual variables -
+easier to add new variables without messing up the original ones - when
+searching on a variable to find its type, there is less clutter to "visually"
+eliminate
+
+Exceptions: when you want to declare a bunch of loop variables or other trivial
+variables; feel free to declare them on 1 line. You should, although, provide a
+good comment on their functions.
+
+Status: developer-discretion.
+
+-------------------------------------------------------------------------------
+
+4.7.7. Use malloc/zalloc sparingly
+
+Explanation:
+
+Create a local struct (on the stack) if the variable will live and die within
+the context of one function call.
+
+Only "malloc" a struct (on the heap) if the variable's life will extend beyond
+the context of one function call.
+
+Example:
+
+If a function creates a struct and stores a pointer to it in a                 
+list, then it should definitely be allocated via `malloc'.                     
+
+-------------------------------------------------------------------------------
+
+4.7.8. The Programmer Who Uses 'malloc' is Responsible for Ensuring 'free'
+
+Explanation:
+
+If you have to "malloc" an instance, you are responsible for insuring that the
+instance is `free'd, even if the deallocation event falls within some other
+programmer's code. You are also responsible for ensuring that deletion is
+timely (i.e. not too soon, not too late). This is known as "low-coupling" and
+is a "good thing (tm)". You may need to offer a free/unload/destuctor type
+function to accommodate this.
+
+Example:
+
+int load_re_filterfile( struct client_state *csp ) { ... }                     
+static void unload_re_filterfile( void *f ) { ... }                            
+
+Exceptions:
+
+The developer cannot be expected to provide `free'ing functions for C run-time
+library functions ... such as `strdup'.
+
+Status: developer-discretion. The "main" use of this standard is for allocating
+and freeing data structures (complex or nested).
+
+-------------------------------------------------------------------------------
+
+4.7.9. Add loaders to the `file_list' structure and in order
+
+Explanation:
+
+I have ordered all of the "blocker" file code to be in alpha order. It is
+easier to add/read new blockers when you expect a certain order.
+
+Note: It may appear that the alpha order is broken in places by POPUP tests
+coming before PCRS tests. But since POPUPs can also be referred to as
+KILLPOPUPs, it is clear that it should come first.
+
+-------------------------------------------------------------------------------
+
+4.7.10. "Uncertain" new code and/or changes to existing code, use FIXME
+
+Explanation:
+
+If you have enough confidence in new code or confidence in your changes, but
+are not *quite* sure of the repercussions, add this:
+
+/* FIXME: this code has a logic error on platform XYZ, * attempting to fix */ #
+ifdef PLATFORM ...changed code here... #endif
+
+or:
+
+/* FIXME: I think the original author really meant this... */ ...changed code
+here...
+
+or:
+
+/* FIXME: new code that *may* break something else... */ ...new code here...
+
+Note: If you make it clear that this may or may not be a "good thing (tm)", it
+will be easier to identify and include in the project (or conversely exclude
+from the project).
+
+-------------------------------------------------------------------------------
+
+4.8. Addendum: Template for files and function comment blocks:
+
+Example for file comments:
+
+const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.42 2002/05/05 20:26:02 hal9 Exp $"; 
+/*********************************************************************                          
+ *                                                                                              
+ * File        :  $Source$                                                                      
+ *                                                                                              
+ * Purpose     :  (Fill me in with a good description!)                                         
+ *                                                                                              
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge                             
+ *                Privoxy team. http://www.privoxy.org/                                         
+ *                                                                                              
+ *                Based on the Internet Junkbuster originally written                           
+ *                by and Copyright (C) 1997 Anonymous Coders and                                
+ *                Junkbusters Corporation.  http://www.junkbusters.com                          
+ *                                                                                              
+ *                This program is free software; you can redistribute it                        
+ *                and/or modify it under the terms of the GNU General                           
+ *                Public License as published by the Free Software                              
+ *                Foundation; either version 2 of the License, or (at                           
+ *                your option) any later version.                                               
+ *                                                                                              
+ *                This program is distributed in the hope that it will                          
+ *                be useful, but WITHOUT ANY WARRANTY; without even the                         
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A                          
+ *                PARTICULAR PURPOSE.  See the GNU General Public                               
+ *                License for more details.                                                     
+ *                                                                                              
+ *                The GNU General Public License should be included with                        
+ *                this file.  If not, you can view it at                                        
+ *                http://www.gnu.org/copyleft/gpl.html                                          
+ *                or write to the Free Software Foundation, Inc., 59                            
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.                        
+ *                                                                                              
+ * Revisions   :                                                                                
+ *    $Log$                                                                                     
+ *                                                                                              
+ *********************************************************************/                         
+                                                                                                
+                                                                                                
+#include "config.h"                                                                             
+                                                                                                
+   ...necessary include files for us to do our work...                                          
+                                                                                                
+const char FILENAME_h_rcs[] = FILENAME_H_VERSION;                                               
+
+Note: This declares the rcs variables that should be added to the
+"show-proxy-args" page. If this is a brand new creation by you, you are free to
+change the "Copyright" section to represent the rights you wish to maintain.
+
+Note: The formfeed character that is present right after the comment flower box
+is handy for (X|GNU)Emacs users to skip the verbiage and get to the heart of
+the code (via `forward-page' and `backward-page'). Please include it if you
+can.
+
+Example for file header comments:
+
+#ifndef _FILENAME_H                                                                           
+#define _FILENAME_H                                                                           
+#define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.42 2002/05/05 20:26:02 hal9 Exp $" 
+/*********************************************************************                        
+ *                                                                                            
+ * File        :  $Source$                                                                    
+ *                                                                                            
+ * Purpose     :  (Fill me in with a good description!)                                       
+ *                                                                                            
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge                           
+ *                Privoxy team. http://www.privoxy.org/                                       
+ *                                                                                            
+ *                Based on the Internet Junkbuster originally written                         
+ *                by and Copyright (C) 1997 Anonymous Coders and                              
+ *                Junkbusters Corporation.  http://www.junkbusters.com                        
+ *                                                                                            
+ *                This program is free software; you can redistribute it                      
+ *                and/or modify it under the terms of the GNU General                         
+ *                Public License as published by the Free Software                            
+ *                Foundation; either version 2 of the License, or (at                         
+ *                your option) any later version.                                             
+ *                                                                                            
+ *                This program is distributed in the hope that it will                        
+ *                be useful, but WITHOUT ANY WARRANTY; without even the                       
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A                        
+ *                PARTICULAR PURPOSE.  See the GNU General Public                             
+ *                License for more details.                                                   
+ *                                                                                            
+ *                The GNU General Public License should be included with                      
+ *                this file.  If not, you can view it at                                      
+ *                http://www.gnu.org/copyleft/gpl.html                                        
+ *                or write to the Free Software Foundation, Inc., 59                          
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.                      
+ *                                                                                            
+ * Revisions   :                                                                              
+ *    $Log$                                                                                   
+ *                                                                                            
+ *********************************************************************/                       
+                                                                                              
+                                                                                              
+#include "project.h"                                                                          
+                                                                                              
+#ifdef __cplusplus                                                                            
+extern "C" {                                                                                  
+#endif                                                                                        
+                                                                                              
+   ... function headers here ...                                                              
+                                                                                              
+                                                                                              
+/* Revision control strings from this header and associated .c file */                        
+extern const char FILENAME_rcs[];                                                             
+extern const char FILENAME_h_rcs[];                                                           
+                                                                                              
+                                                                                              
+#ifdef __cplusplus                                                                            
+} /* extern "C" */                                                                            
+#endif                                                                                        
+                                                                                              
+#endif /* ndef _FILENAME_H */                                                                 
+                                                                                              
+/*                                                                                            
+  Local Variables:                                                                            
+  tab-width: 3                                                                                
+  end:                                                                                        
+*/                                                                                            
+
+Example for function comments:
+
+/*********************************************************************         
+ *                                                                             
+ * Function    :  FUNCTION_NAME                                                
+ *                                                                             
+ * Description :  (Fill me in with a good description!)                        
+ *                                                                             
+ * parameters  :                                                               
+ *          1  :  param1 = pointer to an important thing                       
+ *          2  :  x      = pointer to something else                           
+ *                                                                             
+ * Returns     :  0 => Ok, everything else is an error.                        
+ *                                                                             
+ *********************************************************************/        
+int FUNCTION_NAME( void *param1, const char *x )                               
+{                                                                              
+   ...                                                                         
+   return( 0 );                                                                
+                                                                               
+}                                                                              
+
+Note: If we all follow this practice, we should be able to parse our code to
+create a "self-documenting" web page.
+
+-------------------------------------------------------------------------------
+
+5. Testing Guidelines
+
+To be filled.
+
+-------------------------------------------------------------------------------
+
+5.1. Testplan for releases
+
+Explain release numbers. major, minor. developer releases. etc.
+
+ 1. Remove any existing rpm with rpm -e
+   
+ 2. Remove any file that was left over. This includes (but is not limited to)
+   
+      + /var/log/privoxy
+       
+      + /etc/privoxy
+       
+      + /usr/sbin/privoxy
+       
+      + /etc/init.d/privoxy
+       
+      + /usr/doc/privoxy*
+       
+ 3. Install the rpm. Any error messages?
+   
+ 4. start,stop,status Privoxy with the specific script (e.g. /etc/rc.d/init/
+    privoxy stop). Reboot your machine. Does autostart work?
+   
+ 5. Start browsing. Does Privoxy work? Logfile written?
+   
+ 6. Remove the rpm. Any error messages? All files removed?
+   
+-------------------------------------------------------------------------------
+
+5.2. Test reports
+
+Please submit test reports only with the test form at sourceforge. Three simple
+steps:
+
+  * Select category: the distribution you test on.
+   
+  * Select group: the version of Privoxy that we are about to release.
+   
+  * Fill the Summary and Detailed Description with something intelligent (keep
+    it short and precise).
+   
+Do not mail to the mailinglist (we cannot keep track on issues there).
+
+-------------------------------------------------------------------------------
+
+6. Releasing a New Version
+
+When we release versions of Privoxy, our work leaves our cozy secret lab and
+has to work in the cold RealWorld[tm]. Once it is released, there is no way to
+call it back, so it is very important that great care is taken to ensure that
+everything runs fine, and not to introduce problems in the very last minute.
+
+So when releasing a new version, please adhere exactly to the procedure
+outlined in this chapter.
+
+The following programs are required to follow this process: ncftpput (ncftp),
+scp, ssh (ssh), gmake (GNU's version of make), autoconf, cvs.
+
+-------------------------------------------------------------------------------
+
+6.1. Version numbers
+
+First you need to determine which version number the release will have. Privoxy
+version numbers consist of three numbers, separated by dots, like in X.Y.Z,
+where:
+
+  * X, the version major, is rarely ever changed. It is increased by one if
+    turning a development branch into stable substantially changes the
+    functionality, user interface or configuration syntax. Majors 1 and 2 were
+    Junkbuster, and 3 will be the first stable Privoxy release.
+   
+  * Y, the version minor, represents the branch within the major version. At
+    any point in time, there are two branches being maintained: The stable
+    branch, with an even minor, say, 2N, in which no functionality is being
+    added and only bugfixes are made, and 2N+1, the development branch, in
+    which the further development of Privoxy takes place. This enables us to
+    turn the code upside down and inside out, while at the same time providing
+    and maintaining a stable version. The minor is reset to zero (and one) when
+    the major is inrcemented. When a development branch has matured to the
+    point where it can be turned into stable, the old stable branch 2N is given
+    up (i.e. no longer maintained), the former development branch 2N+1 becomes
+    the new stable branch 2N+2, and a new development branch 2N+3 is opened.
+   
+  * Z, the point or sub version, represents a release of the software within a
+    branch. It is therefore incremented immediately before each code freeze. In
+    development branches, only the even point versions correspond to actual
+    releases, while the odd ones denote the evolving state of the sources on
+    CVS in between. It follows that Z is odd on CVS in development branches
+    most of the time. There, it gets increased to an even number immediately
+    before a code freeze, and is increased to an odd number again immediately
+    thereafter. This ensures that builds from CVS snapshots are easily
+    distinguished from released versions. The point version is reset to zero
+    when the minor changes.
+   
+-------------------------------------------------------------------------------
+
+6.2. Before the Release: Freeze
+
+The following must be done by one of the developers prior to each new release.
+
+  * Make sure that everybody who has worked on the code in the last couple of
+    days has had a chance to yell "no!" in case they have pending changes/fixes
+    in their pipelines. Announce the freeze so that nobody will interfere with
+    last minute changes.
+   
+  * Increment the version number (point from odd to even in development
+    branches!) in configure.in.
+   
+  * If default.action has changed since last release (i.e. software release or
+    standalone actions file release), bump up its version info to A.B in this
+    line:
+   
+      {+add-header{X-Actions-File-Version: A.B} -filter -no-popups}    
+   
+    Then change the version info in doc/webserver/actions/index.php, line:
+    '$required_actions_file_version = "A.B";'
+   
+  * If the HTML documentation is not in sync with the SGML sources you need to
+    regenerate and upload it to the webserver. (If in doubt, just do it.) See
+    the Section "Updating the webserver" in this manual for details.
+   
+  * Commit all files that were changed in the above steps!
+   
+  * Tag all files in CVS with the version number with "cvs tag v_X_Y_Z". Don't
+    use vX_Y_Z, ver_X_Y_Z, v_X.Y.Z (won't work) etc.
+   
+  * If the release was in a development branch, increase the point version from
+    even to odd (X.Y.(Z+1)) again in configure.in and commit your change.
+   
+  * On the webserver, copy the user manual to a new top-level directory called
+    X.Y.Z. This ensures that help links from the CGI pages, which have the
+    version as a prefix, will go into the right version of the manual. If this
+    is a development branch release, also symlink X.Y.(Z-1) to X.Y.Z and X.Y.
+    (Z+1) to . (i.e. dot).
+   
+-------------------------------------------------------------------------------
+
+6.3. Building and Releasing the Packages
+
+Now the individual packages can be built and released. Note that for GPL
+reasons the first package to be released is always the source tarball.
+
+For all types of packages, including the source tarball, you must make sure
+that you build from clean sources by exporting the right version from CVS into
+an empty directory:.
+
+  mkdir dist # delete or choose different name if it already exists                                
+  cd dist                                                                                          
+  cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login                        
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r v_X_Y_Z current
+
+Do NOT change a single bit, including, but not limited to version information
+after export from CVS. This is to make sure that all release packages, and with
+them, all future bug reports, are based on exactly the same code.
+
+Please find additional instructions for the source tarball and the individual
+platform dependent binary packages below.
+
+-------------------------------------------------------------------------------
+
+6.3.1. Source Tarball
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above). Then run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then do:
+
+  make tarball-dist                                                            
+
+To upload the package to Sourceforge, simply issue
+
+  make tarball-upload                                                          
+
+Go to the displayed URL and release the file publicly on Sourceforge. For the
+change log field, use the relevant section of the ChangeLog file.
+
+-------------------------------------------------------------------------------
+
+6.3.2. SuSE or Red Hat RPM
+
+In following text, replace dist with either "rh" for Red Hat or "suse" for
+SuSE.
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above).
+
+As the only exception to not changing anything after export from CVS, now
+examine the file privoxy-dist.spec and make sure that the version information
+and the RPM release number are correct. The RPM release numbers for each
+version start at one. Hence it must be reset to one if this is the first RPM
+for dist which is built from version X.Y.Z. Check the file list if unsure.
+Else, it must be set to the highest already available RPM release number for
+that version plus one.
+
+Then run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then do
+
+  make dist-dist                                                               
+
+To upload the package to Sourceforge, simply issue
+
+  make dist-upload rpm_packagerev                                              
+
+where rpm_packagerev is the RPM release number as determined above. Go to the
+displayed URL and release the file publicly on Sourceforge. Use the release
+notes and change log from the source tarball package.
+
+-------------------------------------------------------------------------------
+
+6.3.3. OS/2
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above). Then get the OS/2
+Setup module:
+
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co os2setup
+
+You will need a mix of development tools. The main compilation takes place with
+IBM Visual Age C++. Some ancillary work takes place with GNU tools, available
+from various sources like hobbes.nmsu.edu. Specificially, you will need
+autoheader, autoconf and sh tools. The packaging takes place with WarpIN,
+available from various sources, including its home page: xworkplace.
+
+Change directory to the os2setup directory. Edit the os2build.cmd file to set
+the final executable filename. For example,
+
+  installExeName='privoxyos2_setup_X.Y.Z.exe'                                  
+
+Next, edit the IJB.wis file so the release number matches in the PACKAGEID
+section:
+
+  PACKAGEID="Privoxy Team\Privoxy\Privoxy Package\X\Y\Z"                       
+
+You're now ready to build. Run:
+
+  os2build                                                                     
+
+You will find the WarpIN-installable executable in the ./files directory.
+Upload this anonymously to uploads.sourceforge.net/incoming, create a release
+for it, and you're done. Use the release notes and Change Log from the source
+tarball package.
+
+-------------------------------------------------------------------------------
+
+6.3.4. Solaris
+
+Login to Sourceforge's compilefarm via ssh:
+
+  ssh cf.sourceforge.net                                                       
+
+Choose the right operating system (not the Debian one). When logged in, make
+sure that you have freshly exported the right version into an empty directory.
+(See "Building and releasing packages" above). Then run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then run
+
+  gmake solaris-dist                                                           
+
+which creates a gzip'ed tar archive. Sadly, you cannot use make solaris-upload
+on the Sourceforge machine (no ncftpput). You now have to manually upload the
+archive to Sourceforge's ftp server and release the file publicly. Use the
+release notes and Change Log from the source tarball package.
+
+-------------------------------------------------------------------------------
+
+6.3.5. Windows
+
+You should ensure you have the latest version of Cygwin (from http://
+www.cygwin.com/). Run the following commands from within a Cygwin bash shell.
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above). Then get the Windows
+setup module:
+
+        cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co winsetup
+
+Then you can build the package. This is fully automated, and is controlled by
+winsetup/GNUmakefile. All you need to do is:
+
+        cd winsetup                                                            
+        make                                                                   
+
+Now you can manually rename privoxy_setup.exe to privoxy_setup_X_Y_Z.exe, and
+upload it to SourceForge. When releasing the package on SourceForge, use the
+release notes and Change Log from the source tarball package.
+
+-------------------------------------------------------------------------------
+
+6.3.6. Debian
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above). Then, run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then do FIXME.
+
+-------------------------------------------------------------------------------
+
+6.3.7. Mac OSX
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above). Then get the Mac OSX
+setup module:
+
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co osxsetup
+
+Then run:
+
+  cd osxsetup                                                                  
+  build                                                                        
+
+This will run autoheader, autoconf and configure as well as make. Finally, it
+will copy over the necessary files to the ./osxsetup/files directory for
+further processing by PackageMaker.
+
+Bring up PackageMaker with the PrivoxyPackage.pmsp definition file, modify the
+package name to match the release, and hit the "Create package" button. If you
+specify ./Privoxy.pkg as the output package name, you can then create the
+distributable zip file with the command:
+
+zip -r privoxyosx_setup_x.y.z.zip Privoxy.pkg                                  
+
+You can then upload privoxyosx_setup_x.y.z.zip anonymously to
+uploads.sourceforge.net/incoming, create a release for it, and you're done. Use
+the release notes and Change Log from the source tarball package.
+
+-------------------------------------------------------------------------------
+
+6.3.8. FreeBSD
+
+Login to Sourceforge's compilefarm via ssh:
+
+  ssh cf.sourceforge.net                                                       
+
+Choose the right operating system. When logged in, make sure that you have
+freshly exported the right version into an empty directory. (See "Building and
+releasing packages" above). Then run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then run:
+
+  gmake freebsd-dist                                                           
+
+which creates a gzip'ed tar archive. Sadly, you cannot use make freebsd-upload
+on the Sourceforge machine (no ncftpput). You now have to manually upload the
+archive to Sourceforge's ftp server and release the file publicly. Use the
+release notes and Change Log from the source tarball package.
+
+-------------------------------------------------------------------------------
+
+6.3.9. HP-UX 11
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above). Then run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then do FIXME.
+
+-------------------------------------------------------------------------------
+
+6.3.10. Amiga OS
+
+First, make sure that you have freshly exported the right version into an empty
+directory. (See "Building and releasing packages" above). Then run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then do FIXME.
+
+-------------------------------------------------------------------------------
+
+6.3.11. AIX
+
+Login to Sourceforge's compilefarm via ssh:
+
+  ssh cf.sourceforge.net                                                       
+
+Choose the right operating system. When logged in, make sure that you have
+freshly exported the right version into an empty directory. (See "Building and
+releasing packages" above). Then run:
+
+  cd current                                                                   
+  autoheader && autoconf && ./configure                                        
+
+Then run:
+
+  make aix-dist                                                                
+
+which creates a gzip'ed tar archive. Sadly, you cannot use make aix-upload on
+the Sourceforge machine (no ncftpput). You now have to manually upload the
+archive to Sourceforge's ftp server and release the file publicly. Use the
+release notes and Change Log from the source tarball package.
+
+-------------------------------------------------------------------------------
+
+6.4. Uploading and Releasing Your Package
+
+After the package is ready, it is time to upload it to SourceForge, and go
+through the release steps. The upload is done via FTP:
+
+  * Upload to: ftp://upload.sourceforge.net/incoming
+   
+  * user: anonymous
+   
+  * password: ijbswa-developers@lists.sourceforge.net
+   
+Once this done go to http://sourceforge.net/project/admin/editpackages.php?
+group_id=11118, making sure you are logged in. Find your target platform in the
+second column, and click Add Release. You will then need to create a new
+release for your package, using the format of $VERSION ($CODE_STATUS), e.g.
+2.9.15 (beta).
+
+Now just follow the prompts. Be sure to add any appropriate Release notes. You
+should see your freshly uploaded packages in "Step 2. Add Files To This
+Release". Check the appropriate box(es). Remember at each step to hit the
+"Refresh/Submit" buttons! You should now see your file(s) listed in Step 3.
+Fill out the forms with the appropriate information for your platform, being
+sure to hit "Update" for each file. If anyone is monitoring your platform,
+check the "email" box at the very bottom to notify them of the new package.
+This should do it!
+
+If you have made errors, or need to make changes, you can go through
+essentially the same steps, but select Edit Release, instead of Add Release.
+
+-------------------------------------------------------------------------------
+
+6.5. After the Release
+
+When all (or: most of the) packages have been uploaded and made available, send
+an email to the announce mailing list, Subject: "Version X.Y.Z available for
+download". Be sure to include the download location, the release notes and the
+change log.
+
+-------------------------------------------------------------------------------
+
+7. Update the Webserver
+
+When updating the webserver, please follow these steps to make sure that no
+broken links, incosistent contents or permission problems will occur:
+
+If you have changed anything in the documentation source SGML files, do:
+
+  make dok # (or make redkat-dok if make dok doesn't work for you)             
+
+That will generate doc/webserver/user-manual, doc/webserver/developer-manual,
+doc/webserver/faq and doc/webserver/index.html automatically.
+
+If you changed the manual page source, generate doc/webserver/man-page/
+privoxy-man-page.html by running "make man". (This is a separate target due to
+dependencies on some obscure perl scripts. See comments in GNUmakefile.)
+
+If you want to add new files to the webserver, create them locally in the doc/
+webserver/* directory (or create new directories under doc/webserver).
+
+Next, commit any changes from the above steps to CVS. All set? Then do
+
+  make webserver                                                               
+
+This will do the upload to the webserver (www.privoxy.org) and ensure all files
+and directories there are group writable.
+
+Please do NOT use any other means of transferring files to the webserver to
+avoid permission problems.
+
+-------------------------------------------------------------------------------
+
+8. Contacting the developers, Bug Reporting and Feature Requests
+
+We value your feedback. However, to provide you with the best support, please
+note the following sections.
+
+-------------------------------------------------------------------------------
+
+8.1. Get Support
+
+To get support, use the Sourceforge Support Forum:
+
+    http://sourceforge.net/tracker/?group_id=11118&atid=211118
+
+-------------------------------------------------------------------------------
+
+8.2. Report bugs
+
+To submit bugs, use the Sourceforge Bug Forum:
+
+    http://sourceforge.net/tracker/?group_id=11118&atid=111118. 
+
+Make sure that the bug has not already been submitted. Please try to verify
+that it is a Privoxy bug, and not a browser or site bug first. If you are using
+your own custom configuration, please try the stock configs to see if the
+problem is a configuration related bug. And if not using the latest development
+snapshot, please try the latest one. Or even better, CVS sources. Please be
+sure to include the Privoxy version, platform, browser, any pertinent log data,
+any other relevant details (please be specific) and, if possible, some way to
+reproduce the bug.
+
+-------------------------------------------------------------------------------
+
+8.3. Request new features
+
+To submit ideas on new features, use the Sourceforge feature request forum:
+
+    http://sourceforge.net/tracker/?atid=361118&group_id=11118&func=browse.
+
+-------------------------------------------------------------------------------
+
+8.4. Report ads or other filter problems
+
+You can also send feedback on websites that Privoxy has problems with. Please
+bookmark the following link: "Privoxy - Submit Filter Feedback". Once you surf
+to a page with problems, use the bookmark to send us feedback. We will look
+into the issue as soon as possible.
+
+New, improved default.action files will occasionally be made available based on
+your feedback. These will be announced on the ijbswa-announce list.
+
+-------------------------------------------------------------------------------
+
+8.5. Other
+
+For any other issues, feel free to use the mailing lists:
+    http://sourceforge.net/mail/?group_id=11118.
+
+Anyone interested in actively participating in development and related
+discussions can also join the appropriate mailing list. Archives are available,
+too. See the page on Sourceforge.
+
+-------------------------------------------------------------------------------
+
+9. Privoxy Copyright, License and History
+
+Copyright Â© 2001, 2002 by Privoxy Developers <developers@privoxy.org>
+
+Some source code is based on code Copyright Â© 1997 by Anonymous Coders and
+Junkbusters, Inc. and licensed under the GNU General Public License.
+
+-------------------------------------------------------------------------------
+
+9.1. License
+
+Privoxy is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License, version 2, as published by the Free
+Software Foundation.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details, which
+is available from the Free Software Foundation, Inc, 59 Temple Place - Suite
+330, Boston, MA 02111-1307, USA.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the
+
+ Free Software
+ Foundation, Inc. 59 Temple Place - Suite 330
+ Boston, MA 02111-1307
+ USA 
+
+-------------------------------------------------------------------------------
+
+9.2. History
+
+Privoxy is evolved, and derived from, the Internet Junkbuster, with many
+improvments and enhancements over the original.
+
+Junkbuster was originally written by Anonymous Coders and Junkbusters
+Corporation, and was released as free open-source software under the GNU GPL. 
+Stefan Waldherr made many improvements, and started the SourceForge project
+Privoxy to rekindle development. There are now several active developers
+contributing. The last stable release of Junkbuster was v2.0.2, which has now
+grown whiskers ;-).
+
+-------------------------------------------------------------------------------
+
+10. See also
+
+Other references and sites of interest to Privoxy users:
+
+http://www.privoxy.org/, The Privoxy Home page.
+
+http://sourceforge.net/projects/ijbswa, the Project Page for Privoxy on        
+Sourceforge.                                                                   
+
+http://p.p/, access Privoxy from your browser. Alternately, http://            
+config.privoxy.org may work in some situations where the first does not.       
+
+http://p.p/, and select "Privoxy - Submit Filter Feedback" to submit "misses"  
+to the developers.                                                             
+
+http://www.junkbusters.com/ht/en/cookies.html
+
+http://www.waldherr.org/junkbuster/
+
+http://privacy.net/analyze/
+
+http://www.squid-cache.org/
+
+
diff --git a/doc/text/faq.txt b/doc/text/faq.txt
new file mode 100644 (file)
index 0000000..5c4cbeb
--- /dev/null
@@ -0,0 +1,1022 @@
+Privoxy Frequently Asked Questions
+
+Copyright Â© 2001, 2002 by Privoxy Developers
+
+$Id: faq.sgml,v 1.57 2002/05/05 20:26:02 hal9 Exp $
+
+This FAQ gives users and developers alike answers to frequently asked questions
+about Privoxy .
+
+Privoxy is a web proxy with advanced filtering capabilities for protecting
+privacy, filtering web page content, managing cookies, controlling access, and
+removing ads, banners, pop-ups and other obnoxious Internet junk. Privoxy has a
+very flexible configuration and can be customized to suit individual needs and
+tastes. Privoxy has application for both stand-alone systems and multi-user
+networks.
+
+Privoxy is based on Internet Junkbuster (tm).
+
+You can find the latest version of the document at http://www.privoxy.org/faq/.
+Please see the Contact section if you want to contact the developers.
+
+-------------------------------------------------------------------------------
+
+Table of Contents
+1. General Information
+   
+    1.1. What is this new version of Privoxy?
+    1.2. Why "Privoxy"? Why a name change at all?
+    1.3. How does Privoxy differ from the old Junkbuster?
+    1.4. What are some of the new features?
+    1.5. What is a "proxy"? How does Privoxy work?
+    1.6. How does Privoxy know what is an ad, and what is not?
+    1.7. Can Privoxy make mistakes? This does not sound very scientific.
+    1.8. My browser does the same things as Privoxy. Why should I use Privoxy
+        at all?
+    1.9. Is there is a license or fee? What about a warranty? Registration?
+    1.10. I would like to help you, what do I do?
+       
+        1.10.1. Money Money Money
+        1.10.2. You want to work with us?
+       
+2. Installation
+   
+    2.1. Which browsers are supported by Privoxy?
+    2.2. Which operating systems are supported?
+    2.3. Can I install Privoxy over Junkbuster?
+    2.4. I just installed Privoxy. Is there anything special I have to do now?
+    2.5. What is the proxy address of Privoxy?
+    2.6. I just installed Privoxy, and nothing is happening. All the ads are
+        there. What's wrong?
+   
+3. Configuration
+   
+    3.1. Can I use my old config files?
+    3.2. What is an "actions" file?
+    3.3. The "actions" concept confuses me. Please list some of these
+        "actions".
+    3.4. How are actions files configured? What is the easiest way to do this?
+    3.5. There are several different "actions" files. What are the differences?
+    3.6. Why can I change the configuration with a browser? Does that not raise
+        security issues?
+    3.7. What is "default.filter"?
+    3.8. How can I set up Privoxy to act as a proxy for my LAN?
+    3.9. Instead of ads, now I get a checkerboard pattern. I don't want to see
+        anything.
+    3.10. Why would anybody want to see a checkerboard pattern?
+    3.11. I see large red banners on some pages that say "Blocked". Why and how
+        do I get rid of this?
+    3.12. I cannot see all of the "Blocked" page banner. Help.
+    3.13. Can Privoxy run as a service on Win2K/NT?
+    3.14. How can I make Privoxy work with other proxies like Squid?
+    3.15. Can Privoxy run as a "transparent" proxy?
+   
+4. Miscellaneous
+   
+    4.1. How much does Privoxy slow my browsing down? This has to add extra
+        time to browsing.
+    4.2. I noticed considerable delays in page requests compared to the old
+        Junkbuster. What's wrong?
+    4.3. What is the "http://p.p/"?
+    4.4. Do you still maintain the blocklists?
+    4.5. How can I submit new ads?
+    4.6. How can I hide my IP address?
+    4.7. Can Privoxy guarantee I am anonymous?
+    4.8. Might some things break because header information is being altered?
+    4.9. Can Privoxy act as a "caching" proxy to speed up web browsing?
+    4.10. What about as a firewall? Can Privoxy protect me?
+    4.11. The Privoxy logo that replaces ads is very blocky and ugly looking.
+        Can't a better font be used?
+    4.12. I have large empty spaces now where ads used to be. Why?
+    4.13. How can Privoxy filter Secure (HTTPS) URLs?
+    4.14. Privoxy runs as a "server". How secure is it? Do I need to take any
+        special precautions?
+    4.15. How can I temporarily disable Privoxy?
+    4.16. Where can I find more information about Privoxy and related issues?
+   
+5. Troubleshooting
+   
+    5.1. I just upgraded and am getting "connection refused" with every web
+        page?
+    5.2. I just added a new rule, but the steenkin ad is still getting through.
+        How?
+    5.3. One of my favorite sites does not work with Privoxy. What can I do?
+   
+6. Contacting the developers, Bug Reporting and Feature Requests
+   
+    6.1. Get Support
+    6.2. Report bugs
+    6.3. Request new features
+    6.4. Report ads or other filter problems
+    6.5. Other
+   
+7. Privoxy Copyright, License and History
+   
+    7.1. License
+    7.2. History
+   
+1. General Information
+
+1.1. What is this new version of Privoxy?
+
+The original Internet JunkbusterTM (tm) is a copyrighted product of Junkbusters
+Corporation. Development of this effort stopped some time ago as of version
+2.0.2. Stefan Waldherr started the ijbswa project on Sourceforge to rekindle
+development. Other developers subsequently joined with Stefan, and have since
+added many new features, refinements and enhancements. The result of this
+effort is Privoxy.
+
+Privoxy has evolved from the Junkbuster 2.0.2 code base, and has advanced
+significantly at this point.
+
+Please see the History section for more information on the history of
+Junkbuster and Privoxy.
+
+-------------------------------------------------------------------------------
+
+1.2. Why "Privoxy"? Why a name change at all?
+
+Privoxy is the "Privacy Enhancing Proxy".
+
+There are potential legal complications from the continued use of the
+Junkbuster name, which is a registered trademark of Junkbusters Corporation.
+And thus they "own" the rights to the name. (There are, however, no objections
+from Junkbusters Corporation to the Privoxy project itself, and they, in fact,
+still share our ideals and goals.)
+
+The developers also believed that there are so many changes from the original
+code, that it was time to make a clean break from the past and make a name in
+their own right, especially now with the pending release of version 3.0.
+
+-------------------------------------------------------------------------------
+
+1.3. How does Privoxy differ from the old Junkbuster?
+
+Privoxy picks up where Junkbuster left off. All the old features remain. The
+new Privoxy still blocks ads and banners, still manages cookies, and still
+helps protect your privacy. But, these are all enhanced, and many new features
+have been added, all in the same vein.
+
+The configuration has changed significantly as well. This is something that
+users will notice right off the bat if you are upgrading from Junkbuster 2.0.x.
+The "blocklist" file does not exist any more. This is replaced by "actions"
+files, such as default.actions. This is where most of the per site
+configuration is now.
+
+-------------------------------------------------------------------------------
+
+1.4. What are some of the new features?
+
+  * Integrated browser based configuration and control utility at http://
+    config.privoxy.org/ (shortcut: http://p.p/). Browser-based tracing of rule
+    and filter effects. Remote toggling.
+   
+  * Web page content filtering (removes banners based on size, invisible
+    "web-bugs", JavaScript and HTML annoyances, pop-up windows, etc.)
+   
+  * Modularized configuration that allows for standard settings and user
+    settings to reside in separate files, so that installing updated actions
+    files won't overwrite idividual user settings.
+   
+  * HTTP/1.1 compliant (but not all optional 1.1 features are supported).
+   
+  * Support for Perl Compatible Regular Expressions in the configuration files,
+    and generally a more sophisticated and flexible configuration syntax over
+    previous versions.
+   
+  * Improved cookie management features (e.g. session based cookies).
+   
+  * GIF de-animation.
+   
+  * Bypass many click-tracking scripts (avoids script redirection).
+   
+  * Multi-threaded (POSIX and native threads).
+   
+  * User-customizable HTML templates for all proxy-generated pages (e.g.
+    "blocked" page).
+   
+  * Auto-detection and re-reading of config file changes.
+   
+  * Improved signal handling, and a true daemon mode (Unix).
+   
+  * Every feature now controllable on a per-site or per-location basis,
+    configuration more powerful and versatile over-all.
+   
+  * Many smaller new features added, limitations and bugs removed, and security
+    holes fixed.
+   
+-------------------------------------------------------------------------------
+
+1.5. What is a "proxy"? How does Privoxy work?
+
+When you connect to a web site with Privoxy, you are really connecting to your
+locally running version of Privoxy. Privoxy intercepts your requests for the
+web page, and relays that to the "real" web site. The web site sends the HTTP
+data stream back to Privoxy, where Privoxy can work its magic before it relays
+this data back to your web browser.
+
+Since Privoxy sits between you and the WWW, it is in a position to intercept
+and completely manage all web traffic and HTTP content before it gets to your
+browser. Privoxy uses various programming methods to do this, all of which is
+under your control via the various configuration files and options.
+
+There are many kinds of proxies. Privoxy best fits the "filtering proxy"
+category.
+
+-------------------------------------------------------------------------------
+
+1.6. How does Privoxy know what is an ad, and what is not?
+
+Privoxy processes all the raw content of every web page. So it reads everything
+on each page. It then compares this to the rules as set up in the configuration
+files, and looks for any matches to these rules. Privoxy makes heavy use of
+"regular expressions". (If you are not familiar with regular expressions, it is
+explained briefly in the user manual.) Regular expressions facilitate matching
+of one text string against another, using wildcards to build complex patterns.
+So Privoxy will typically look for URLs and other content that match certain
+key words and expressions as defined in the configuration files. For instance a
+URL that contains "/banners", has a high probability of containing ad banners,
+and thus would be a prime candidate to have a matching rule.
+
+So Privoxy will look for these kinds of obvious looking culprits. And also,
+will use lists of known organizations that specialize in ads. Again, using
+complex patterns to match as many potential combinations as possible since
+there tend to be many, many variations used by advertisers, and new ones are
+being introduced all the time.
+
+-------------------------------------------------------------------------------
+
+1.7. Can Privoxy make mistakes? This does not sound very scientific.
+
+Actually, it's a black art ;-) And yes, it is always possible to have a broad
+rule accidentally block something by mistake. There is a good chance you may
+run into such a situation at some point. It is tricky writing rules to cover
+every conceivable possibility, and not occasionally get false positives.
+
+But this should not be a big concern since the Privoxy configuration is very
+flexible, and includes tools to help identify these types of situations so they
+can be addressed as needed, allowing you to customize your installation. (See
+the Troubleshooting section below.)
+
+-------------------------------------------------------------------------------
+
+1.8. My browser does the same things as Privoxy. Why should I use Privoxy at
+all?
+
+Modern browsers do indeed have some of the same functionality as Privoxy. Maybe
+this is adequate for you. But Privoxy is much more versatile and powerful, and
+can do a number of things that browsers just can't.
+
+In addition, a proxy is good choice if you use multiple browsers, or have a LAN
+with multiple computers. This way all the configuration is in one place, and
+you don't have to maintain a similar configuration for possibly many browsers.
+
+-------------------------------------------------------------------------------
+
+1.9. Is there is a license or fee? What about a warranty? Registration?
+
+Privoxy is licensed under the GNU General Public License (GPL). It is free to
+use, copy, modify or distribute as you wish under the terms of this license.
+Please see the Copyright section for more information on the license and
+copyright. Or the LICENSE file that should be included.
+
+There is no warranty of any kind, expressed, implied or otherwise. That is
+something that would cost real money ;-) There is no registration either.
+Privoxy really is free in every respect!
+
+-------------------------------------------------------------------------------
+
+1.10. I would like to help you, what do I do?
+
+1.10.1. Money Money Money
+
+We, of course, welcome donations and use the money for domain registering,
+regular world-wide get-togethers (hahaha). Anyway, we'll soon describe the
+process how to donate money to the team.
+
+-------------------------------------------------------------------------------
+
+1.10.2. You want to work with us?
+
+Well, helping the team is always a good idea. We welcome new developers, RPM
+gurus or documentation makers. Simply get an account on sourceforge.net and
+mail your id to the developer mailing list. Then read the section Quickstart in
+the Developer's Manual.
+
+Once we have added you to the team, you'll have write access to the CVS
+repository, and together we'll find a suitable task for you.
+
+-------------------------------------------------------------------------------
+
+2. Installation
+
+2.1. Which browsers are supported by Privoxy?
+
+Any browser that can be configured to use a "proxy", which should be virtually
+all browsers. Direct browser support is not necessary since Privoxy runs as a
+separate application and just exchanges standard HTML data with your browser,
+just like a web server does.
+
+-------------------------------------------------------------------------------
+
+2.2. Which operating systems are supported?
+
+At present, Privoxy is known to run on Windows(95, 98, ME, 2000, XP), Linux
+(RedHat, Suse, Debian), Mac OSX, OS/2, AmigaOS, FreeBSD, NetBSD, BeOS, and many
+more flavors of Unix.
+
+But any operating system that runs TCP/IP, can conceivably take advantage of
+Privoxy in a networked situation where Privoxy would run as a server on a LAN
+gateway. Then only the "gateway" needs to be running one of the above operating
+systems.
+
+Source code is freely available, so porting to other operating systems, is
+always a possibility.
+
+-------------------------------------------------------------------------------
+
+2.3. Can I install Privoxy over Junkbuster?
+
+We recommend you uninstall Junkbuster first to minimize conflicts and
+confusion. You may want to save your old configuration files for future
+reference. The configuration is substantially changed.
+
+See the user-manual for platform specific installation instructions.
+
+Note: Some installers may automatically uninstall Junkbuster, if present!
+
+-------------------------------------------------------------------------------
+
+2.4. I just installed Privoxy. Is there anything special I have to do now?
+
+All browsers must be told to use Privoxy as a proxy by specifying the correct
+proxy address and port number in the appropriate configuration area for the
+browser. See below. Also, you should flush your browser's memory and disk cache
+to get rid of any cached items. 
+
+-------------------------------------------------------------------------------
+
+2.5. What is the proxy address of Privoxy?
+
+If you set up the Privoxy to run on the computer you browse from (rather than
+your ISP's server or some networked computer on a LAN), the proxy will be on
+"localhost" (which is the special name used by every computer on the Internet
+to refer to itself) and the port will be 8118 (unless you have Privoxy to run
+on a different port with the listen-address config option).
+
+When configuring your browser's proxy settings you typically enter the word
+"localhost" in the boxes next to "HTTP" and "Secure" (HTTPS) and then the
+number "8118" for "port". This tells your browser to send all web requests to
+Privoxy instead of directly to the Internet.
+
+Privoxy can also be used to proxy for a Local Area Network. In this case, your
+would enter either the IP address of the LAN host where Privoxy is running, or
+the equivalent hostname. Port assignment would be same as above.
+
+Privoxy does not currently handle protocols such as FTP, SMTP, IM, IRC, ICQ, or
+other Internet protocols.
+
+-------------------------------------------------------------------------------
+
+2.6. I just installed Privoxy, and nothing is happening. All the ads are there.
+What's wrong?
+
+Did you configure your browser to use Privoxy as a proxy? It does not sound
+like it. See above. You might also try flushing the browser's caches to force a
+full re-reading of pages. You can verify that Privoxy is running, and your
+browser is correctly configured by entering the special URL: http://p.p/. This
+should give you a banner that says "This is Privoxy" and access to Privoxy's
+internal configuration. If you see this, then you are good to go. If not, the
+browser or Privoxy are not set up correctly. 
+
+-------------------------------------------------------------------------------
+
+3. Configuration
+
+3.1. Can I use my old config files?
+
+There are major changes to Junkbuster/ Privoxy configuration from version 2.0.x
+to 2.9.x and later. Most of the older files will not work at all. This is
+especially true of blocklist. If this is the case, you will need to re-enter
+your old data into the new configuration structure. This is probably also a
+good recommendation even if upgrading from 2.9.x to 3.x since there were many
+minor changes along the way.
+
+-------------------------------------------------------------------------------
+
+3.2. What is an "actions" file?
+
+"actions" files are where various actions that Privoxy might take, are
+configured. Typically, you would define a set of default actions that apply to
+all URLs, then add exceptions to these defaults where needed.
+
+Actions can be defined on a per site basis, or for groups of sites. Actions can
+also be grouped together and then applied to one or more sites. There are many
+possible actions that might apply to any given site. As an example, if we are
+blocking cookies as one of our default actions, but need to accept cookies from
+a given site, we would define this in our "actions" file. 
+
+-------------------------------------------------------------------------------
+
+3.3. The "actions" concept confuses me. Please list some of these "actions".
+
+These are all explained in the user-manual. Please refer to that.
+
+-------------------------------------------------------------------------------
+
+3.4. How are actions files configured? What is the easiest way to do this?
+
+The easiest way to do this, is to access Privoxy with your web browser at http:
+//p.p/, and then select "View & change the current configuration" from the
+selection list. You can also do this by editing the appropriate file with a
+text editor.
+
+Please see the user-manual for a detailed explanation of these and other
+configuration files, and their various options and syntax.
+
+-------------------------------------------------------------------------------
+
+3.5. There are several different "actions" files. What are the differences?
+
+As of Privoxy v2.9.15, three actions files are being included, to be used for
+different purposes. These are default.action, standard.action, and user.action.
+Please see the User Manual for an explanation of each.
+
+Earlier versions included three different versions default.action files. The
+new scheme allows for greater flexibility of local configuration, and for
+browser based configuration.
+
+-------------------------------------------------------------------------------
+
+3.6. Why can I change the configuration with a browser? Does that not raise
+security issues?
+
+What I don't understand, is how I can browser edit the config file as a regular
+user, while the whole /etc/privoxy hierarchy belongs to the user "privoxy",
+with only 644 permissions.
+
+When you use the browser-based editor, Privoxy itself is writing to the config
+files. Because Privoxy is running as the user "privoxy", it can update the
+config files.
+
+If you don't like this, setting "enable-edit-actions 0" in the config file will
+disable the browser-based editor. If you're that paranoid, you should also
+consider setting "enable-remote-toggle 0" to prevent browser-based enabling/
+disabling of Privoxy.
+
+Note that normally only local users can connect to Privoxy, so this is not
+(normally) a security problem.
+
+-------------------------------------------------------------------------------
+
+3.7. What is "default.filter"?
+
+The "default.filter" file is where "filters" are defined, which are used to
+"filter" any web page content. By "filtering" we mean it can modify, remove, or
+change anything on the page, including HTML tags, and JavaScript. Regular
+expressions are used to accomplish this, and operate on a line by line basis.
+This is potentially a very powerful feature, but requires some expertise.
+
+If you are familiar with regular expressions, and HTML, you can look at the
+provided default.filter with a text editor and see some of things it can be
+used for.
+
+Presently, there is no GUI editor option for this part of the configuration,
+but you can disable/enable various sections of the included default file with
+the "View & change the current configuration" from your browser.
+
+-------------------------------------------------------------------------------
+
+3.8. How can I set up Privoxy to act as a proxy for my LAN?
+
+By default, Privoxy only responds to requests from localhost. To have it act as
+a server for a network, this needs to be changed in the main config file where
+the Privoxy configuration is located. In that file is a "listen-address"
+option. It may be commented out with a "#" symbol. Make sure it is uncommented,
+and assign it the address of the LAN gateway interface, and port number to use:
+
+  listen-address  192.168.1.1:8118                                             
+
+Save the file, and restart Privoxy. Configure all browsers on the network then
+to use this address and port number.
+
+-------------------------------------------------------------------------------
+
+3.9. Instead of ads, now I get a checkerboard pattern. I don't want to see
+anything.
+
+This is a configuration option for images that Privoxy is stopping. You have
+the choice of a checkerboard pattern, a transparent 1x1 GIF image (aka
+"blank"), or a custom URL of your choice. Note that to fit this category, the
+URL must match both the "+handle-as-image" and "+block" actions.
+
+If you want to see nothing, then change the "+set-image-blocker" action to
+"+image-blocker{blank}". This can be done from the "View & change the current
+configuration" selection at http://p.p/. Or by hand editing the appropriate
+actions file. This will only effect what is defined as "images" though. Also,
+some URLs that generate the bright red "Blocked" banner, can be moved to the
+"+set-image-blocker" section for the same reason, but there are some limits and
+risks to this (see below).
+
+-------------------------------------------------------------------------------
+
+3.10. Why would anybody want to see a checkerboard pattern?
+
+This can be helpful for troubleshooting problems. It might also be good for
+anyone new to Privoxy so that they can see if their favorite pages are
+displaying correctly, and Privoxy is not inadvertently removing something
+important.
+
+-------------------------------------------------------------------------------
+
+3.11. I see large red banners on some pages that say "Blocked". Why and how do
+I get rid of this?
+
+These are URLs that match something in one of Privoxy's block actions ("+block"
+). It is meant to be a warning so that you know something has been blocked and
+an easy way for you to see why. These are handled differently than what has
+been defined explicitly as "images" (e.g. ads that are GIF image files).
+Depending on the URL itself, it is sometimes hard for Privoxy to really know
+whether there is indeed an ad image there or not. And there are limitations as
+to what Privoxy can do to "fool" the browser.
+
+For instance, if the ad is in a frame, then it is embedded in the separate HTML
+page used for the frame. In this case, you cannot just substitute an aribitrary
+image (like we would for a "blank" image), for an HTML page. The browser is
+expecting an HTML page, and that is what it must have for frames. Such
+situations can be a little trickier to deal with, and Privoxy may show the
+"Blocked" page, despite your best efforts.
+
+If you want these to be treated as if they were images, so that they can be
+made invisible, you can try moving the offending URL from the "+block" section
+to the "+imageblock" section of your actions file. Just be forewarned, if any
+URL is made "invisible", you may not have any inkling that something has been
+removed from that page, or why. If this approach does not work, then you are
+probably dealing with a frame (or "ilayer"), and the only thing that can go
+there is an HTML page of some sort.
+
+To deal with this situation, you could modify the "block" HTML template that is
+used by Privoxy to display this, and make it something more to your liking.
+Currently, there is no configuration option for this. You will have to modify,
+or create your own page, and use this to replace templates/blocked, which is
+what Privoxy uses to display the "Blocked" page.
+
+Another way to deal with this is find why and where Privoxy is blocking the
+frame, and diable this. Then let the "+set-image-blocker" action handle the ad
+that is embedded in the frame's HTML page.
+
+-------------------------------------------------------------------------------
+
+3.12. I cannot see all of the "Blocked" page banner. Help.
+
+There is not enough available space to fit the entire Blocked page. Try right
+clicking on the visible portion, and select "Show Frame", or equivalent. This
+will usually allow you to see the entire Privoxy "Blocked" page, and from there
+you can see just what is being blocked, and why.
+
+As of Privoxy 2.9.14, the Blocked banner page is re-sizeable, and tries to
+adjust to the allotted space. There may be occassions where there just isn't
+enough room to display much of anything useful though.  
+
+-------------------------------------------------------------------------------
+
+3.13. Can Privoxy run as a service on Win2K/NT?
+
+Yes, it can run as a system service using srvany.exe. The only catch is that
+this will effectively disable the Privoxy icon in the taskbar. You can have one
+or the other, but not both at this time :(
+
+There is a pending feature request for this functionality. See thread: http://
+sourceforge.net/tracker/?func=detail&atid=361118&aid=485617&group_id=11118, for
+details, and a sample configuration. 
+
+-------------------------------------------------------------------------------
+
+3.14. How can I make Privoxy work with other proxies like Squid?
+
+This can be done. See the user manual, which describes how to do this.
+
+-------------------------------------------------------------------------------
+
+3.15. Can Privoxy run as a "transparent" proxy?
+
+No, Privoxy currently does not have this ability, though it is planned for a
+future release. Transparent proxies require special handling of the request
+headers beyond what Privoxy is now capable of.
+
+Chaining Privoxy with another proxy that has this ability should work though.
+See the user manual, which describes this, and also http://
+www.transproxy.nlc.net.au/.
+
+-------------------------------------------------------------------------------
+
+4. Miscellaneous
+
+4.1. How much does Privoxy slow my browsing down? This has to add extra time to
+browsing.
+
+It should not slow you down any in real terms, and may actually help speed
+things up since ads, banners and other junk are not being displayed. The actual
+processing time required by Privoxy itself for each page, is relatively small
+in the overall scheme of things, and happens very quickly. This is typically
+more than offset by time saved not downloading and rendering ad images.
+
+"Filtering" via the filterfile mechanism may cause a perceived slowdown, since
+the entire page is buffered before displaying. See below.
+
+-------------------------------------------------------------------------------
+
+4.2. I noticed considerable delays in page requests compared to the old
+Junkbuster. What's wrong?
+
+The entire page content must be loaded into memory in order for the filtering
+mechanism to work, and nothing is sent to the browser during this time. The
+loading time does not really change in real numbers, but the feeling is
+different, because most browsers are able to start rendering incomplete
+content, giving the user a feeling of "it works".
+
+To modify the content of a page (i.e. make frames resizeable again, etc.) and
+not just replace ads, Privoxy needs to download the entire page first, do its
+content magic and then send the page to the browser.
+
+-------------------------------------------------------------------------------
+
+4.3. What is the "http://p.p/"?
+
+Since Privoxy sits between your web browser and the Internet, it can be
+programmed to handle certain pages specially.
+
+With recent versions of Privoxy (version 2.9.x and greater), you can get some
+information about Privoxy and change some settings by going to http://p.p/ or,
+equivalently, http://config.privoxy.org/ (Note that p.p is far easier to type
+but may not work in some configurations. With the name change to Privoxy, this
+is changed from the previous http://i.j.b/ and earlier 2.9.x versions).
+
+These pages are not forwarded to a server on the Internet - instead they are
+handled by a special web server which is built in to Privoxy.
+
+If you are not running Privoxy, then http://p.p/ will fail, and http://
+config.privoxy.org/ will return a web page telling you you're not running
+Privoxy.
+
+If you have version 2.0.2, then the equivalent is http://example.com/
+show-proxy-args (but you get far less information, and you should really
+consider upgrading to 2.9.15).
+
+-------------------------------------------------------------------------------
+
+4.4. Do you still maintain the blocklists?
+
+No, not by this name. The format of the blocklists has changed significantly in
+versions 2.9.x and later. This functionality is done by the "actions" file now.
+See next question ...
+
+-------------------------------------------------------------------------------
+
+4.5. How can I submit new ads?
+
+Please see the Contact section.
+
+This process does not work with earlier versions of Privoxy or Junkbuster.
+
+-------------------------------------------------------------------------------
+
+4.6. How can I hide my IP address?
+
+You cannot hide your IP address with Privoxy or any other software, since the
+server needs to know your IP address to send the answers back to you.
+
+Fortunately there are many publicly usable anonymous proxies out there, which
+solve the problem by providing a further level of indirection between you and
+the web server, shared by many people and thus letting your requests "drown" in
+white noise of unrelated requests as far as user tracking is concerned.
+
+Most of them will, however, log your IP address and make it available to the
+authorities in case you abuse that anonymity for criminal purposes. In fact you
+can't even rule out that some of them only exist to *collect* information on
+(those suspicious) people with a more than average preference for privacy.
+
+You can find a list of anonymous public proxies at multiproxy.org and many more
+through Google.
+
+-------------------------------------------------------------------------------
+
+4.7. Can Privoxy guarantee I am anonymous?
+
+No. Your chances of remaining anonymous are greatly improved, but unless you
+are an expert on Internet security it would be safest to assume that everything
+you do on the Web can be traced back to you.
+
+Privoxy can remove various information about you, and allows you more freedom
+to decide which sites you can trust, and what details you want to reveal. But
+it's still possible that web sites can find out who you are. Here's one way
+this can happen.
+
+A few browsers disclose the user's email address in certain situations, such as
+when transferring a file by FTP. Privoxy does not filter FTP. If you need this
+feature, or are concerned about the mail handler of your browser disclosing
+your email address, you might consider products such as NSClean.
+
+Browsers available only as binaries could use non-standard headers to give out
+any information they can have access to: see the manufacturer's license
+agreement. It's impossible to anticipate and prevent every breach of privacy
+that might occur. The professionally paranoid prefer browsers available as
+source code, because anticipating their behavior is easier. Trust the source,
+Luke!
+
+-------------------------------------------------------------------------------
+
+4.8. Might some things break because header information is being altered?
+
+Definitely. More and more sites use HTTP header content to decide what to
+display and how to display it. There is many ways that this can be handled, so
+having hard and fast rules, is tricky.
+
+"USER AGENT" in particular is often used in this way to identify the browser,
+and adjust content accordingly. Changing this now is not recommended, since so
+many sites do look for this. You may get undesirable results by changing this.
+
+For instance, different browsers use different encodings of Russian and Czech
+characters, certain web servers convert pages on-the-fly according to the User
+Agent header. Giving a "User Agent" with the wrong operating system or browser
+manufacturer causes some sites in these languages to be garbled; Surfers to
+Eastern European sites should change it to something closer. And then some page
+access counters work by looking at the "REFERER" header; they may fail or break
+if unavailable. The weather maps of Intellicast have been blocked by their
+server when no "REFERER" or cookie is provided, is another example. There are
+many, many other ways things can go wrong when trying to fool a web server.
+
+If you have problems with a site, you will have to adjust your configuration
+accordingly. Cookies are probably the most likely adjustment that may be
+required, but by no means the only one.
+
+-------------------------------------------------------------------------------
+
+4.9. Can Privoxy act as a "caching" proxy to speed up web browsing?
+
+No, it does not have this ability at all. You want something like Squid for
+this. And, yes, before you ask, Privoxy can co-exist with other kinds of
+proxies like Squid.
+
+-------------------------------------------------------------------------------
+
+4.10. What about as a firewall? Can Privoxy protect me?
+
+Not in the way you mean, or in the way a true firewall can, or a proxy that has
+this specific capability. Privoxy can help protect your privacy, but not really
+protect you from intrusion attempts.
+
+-------------------------------------------------------------------------------
+
+4.11. The Privoxy logo that replaces ads is very blocky and ugly looking. Can't
+a better font be used?
+
+This is not a font problem. The logo is an image that is created by Privoxy on
+the fly. So as to not waste memory, the image is rather small. The blockiness
+comes when the image is scaled to fill a largish area. There is not much to be
+done about this, other than to use one of the other "imageblock" directives:
+pattern, blank, or a URL of your choosing.
+
+Given the above problem, we have decided to remove the logo option entirely [as
+of v2.9.13].
+
+-------------------------------------------------------------------------------
+
+4.12. I have large empty spaces now where ads used to be. Why?
+
+It would be easy enough to just eliminate this space altogether, rather than
+fill it with blank space. But, this would create problems with many pages that
+use the overall size of the ad to help organize the page layout and position
+the various components of the page where they were intended to be. It is best
+left this way.
+
+-------------------------------------------------------------------------------
+
+4.13. How can Privoxy filter Secure (HTTPS) URLs?
+
+This is a limitation since HTTPS transactions are encrypted SSL sessions
+between your browser and the secure site, and are meant to be reliably secure
+and private. This means that all cookies and HTTP header information are also
+encrypted from the time they leave your browser, to the site, and vice versa.
+Privoxy does not try to unencrypt this information, so it just passes through
+as is. Privoxy can still catch images and ads that are embedded in the SSL
+stream though.
+
+-------------------------------------------------------------------------------
+
+4.14. Privoxy runs as a "server". How secure is it? Do I need to take any
+special precautions?
+
+There are no known exploits that might effect Privoxy. On Unix-like systems,
+Privoxy can run as a non-privileged user, which is how we recommend it be run.
+Also, by default Privoxy only listens to requests from "localhost". The server
+aspect of Privoxy is not itself directly exposed to the Internet in this
+configuration. If you want to have Privoxy serve as a LAN proxy, this will have
+to be opened up to allow for LAN requests. In this case, we'd recommend you
+specify only the LAN gateway address, e.g. 192.168.1.1, in the main Privoxy
+config file. All LAN hosts can then use this as their proxy address in the
+browser proxy configuration. In this way, Privoxy will not listen on any
+external ports. Of course, a firewall is always good too. Better safe than
+sorry.
+
+-------------------------------------------------------------------------------
+
+4.15. How can I temporarily disable Privoxy?
+
+The easiest way is to access Privoxy with your browser by using the special
+URL: http://p.p/ and select "Toggle Privoxy on or off" from that page. 
+
+-------------------------------------------------------------------------------
+
+4.16. Where can I find more information about Privoxy and related issues?
+
+Other references and sites of interest to Privoxy users:
+
+http://www.privoxy.org/, The Privoxy Home page.
+
+http://sourceforge.net/projects/ijbswa, the Project Page for Privoxy on        
+Sourceforge.                                                                   
+
+http://p.p/, access Privoxy from your browser. Alternately, http://            
+config.privoxy.org may work in some situations where the first does not.       
+
+http://p.p/, and select "Privoxy - Submit Filter Feedback" to submit "misses"  
+to the developers.                                                             
+
+http://www.junkbusters.com/ht/en/cookies.html
+
+http://www.waldherr.org/junkbuster/
+
+http://privacy.net/analyze/
+
+http://www.squid-cache.org/
+
+
+-------------------------------------------------------------------------------
+
+5. Troubleshooting
+
+5.1. I just upgraded and am getting "connection refused" with every web page?
+
+Either Privoxy is not running, or your browser is configured for a different
+port than what Privoxy is using.
+
+The old Privoxy (and also Junkbuster) used port 8000 by default. This has been
+changed to port 8118 now, due to a conflict with NAS (Network Audio Service),
+which uses port 8000. If you haven't, you need to change your browser to the
+new port number, or alternately change Privoxy's "listen-address" setting in
+the config file used to start Privoxy.
+
+-------------------------------------------------------------------------------
+
+5.2. I just added a new rule, but the steenkin ad is still getting through.
+How?
+
+If the ad had been displayed before you added its URL, it will probably be held
+in the browser's cache for some time, so it will be displayed without the need
+for any request to the server, and Privoxy will not be in the picture. The best
+thing to do is try flushing the browser's caches. And then try again.
+
+If this doesn't help, you probably have an error in the rule you applied. Try
+pasting the full URL of the offending ad into http://config.privoxy.org/
+show-url-info and see if any actions match your new rule.
+
+-------------------------------------------------------------------------------
+
+5.3. One of my favorite sites does not work with Privoxy. What can I do?
+
+First verify that it is indeed a Privoxy problem, by disabling Privoxy
+filtering and blocking. Go to http://p.p/ and click on "Toggle Privoxy On or
+Off", then disable it. Now try that page again. It's probably a good idea to
+flush the browser cache as well with Shift+Reload to flush caches.
+
+If still a problem, go to "Show which actions apply to a URL and why" from 
+http://p.p/ and paste the full URL of the page in question into the prompt. See
+which actions are being applied to the URL. Now, armed with this information,
+go to "View & change the current configuration". Here you should see various
+sections that have various Privoxy features disabled for specific sites. Most
+disabled "actions" will have a "-" (minus sign) in front of them. Some aliases
+are used just to disable other actions, e.g. "shop" and "fragile", and won't
+necessarily use a "+" or "-" sign. Add your problem page URL to one of these
+sections that looks like it is disabling the feature that is causing the
+problem. Rember to flush your browser's caches when making such changes! As a
+last resort, try "fragile" which disables most actions. Now re-try the page.
+There might be some trial and error involved. This is discussed in more detail
+in the user-manual appendix. 
+
+Alternately, if you are comfortable with a text editor, you can accomplish the
+same thing by editing the appropriate "actions" file.
+
+-------------------------------------------------------------------------------
+
+6. Contacting the developers, Bug Reporting and Feature Requests
+
+We value your feedback. However, to provide you with the best support, please
+note the following sections.
+
+-------------------------------------------------------------------------------
+
+6.1. Get Support
+
+To get support, use the Sourceforge Support Forum:
+
+    http://sourceforge.net/tracker/?group_id=11118&atid=211118
+
+-------------------------------------------------------------------------------
+
+6.2. Report bugs
+
+To submit bugs, use the Sourceforge Bug Forum:
+
+    http://sourceforge.net/tracker/?group_id=11118&atid=111118. 
+
+Make sure that the bug has not already been submitted. Please try to verify
+that it is a Privoxy bug, and not a browser or site bug first. If you are using
+your own custom configuration, please try the stock configs to see if the
+problem is a configuration related bug. And if not using the latest development
+snapshot, please try the latest one. Or even better, CVS sources. Please be
+sure to include the Privoxy version, platform, browser, any pertinent log data,
+any other relevant details (please be specific) and, if possible, some way to
+reproduce the bug.
+
+-------------------------------------------------------------------------------
+
+6.3. Request new features
+
+To submit ideas on new features, use the Sourceforge feature request forum:
+
+    http://sourceforge.net/tracker/?atid=361118&group_id=11118&func=browse.
+
+-------------------------------------------------------------------------------
+
+6.4. Report ads or other filter problems
+
+You can also send feedback on websites that Privoxy has problems with. Please
+bookmark the following link: "Privoxy - Submit Filter Feedback". Once you surf
+to a page with problems, use the bookmark to send us feedback. We will look
+into the issue as soon as possible.
+
+New, improved default.action files will occasionally be made available based on
+your feedback. These will be announced on the ijbswa-announce list.
+
+-------------------------------------------------------------------------------
+
+6.5. Other
+
+For any other issues, feel free to use the mailing lists:
+    http://sourceforge.net/mail/?group_id=11118.
+
+Anyone interested in actively participating in development and related
+discussions can also join the appropriate mailing list. Archives are available,
+too. See the page on Sourceforge.
+
+-------------------------------------------------------------------------------
+
+7. Privoxy Copyright, License and History
+
+Copyright Â© 2001, 2002 by Privoxy Developers <developers@privoxy.org>
+
+Some source code is based on code Copyright Â© 1997 by Anonymous Coders and
+Junkbusters, Inc. and licensed under the GNU General Public License.
+
+Portions of this document are "borrowed" from the original Junkbuster (tm) FAQ,
+and modified as appropriate for Privoxy.
+
+-------------------------------------------------------------------------------
+
+7.1. License
+
+Privoxy is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License, version 2, as published by the Free
+Software Foundation.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details, which
+is available from the Free Software Foundation, Inc, 59 Temple Place - Suite
+330, Boston, MA 02111-1307, USA.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the
+
+ Free Software
+ Foundation, Inc. 59 Temple Place - Suite 330
+ Boston, MA 02111-1307
+ USA 
+
+-------------------------------------------------------------------------------
+
+7.2. History
+
+Privoxy is evolved, and derived from, the Internet Junkbuster, with many
+improvments and enhancements over the original.
+
+Junkbuster was originally written by Anonymous Coders and Junkbusters
+Corporation, and was released as free open-source software under the GNU GPL. 
+Stefan Waldherr made many improvements, and started the SourceForge project
+Privoxy to rekindle development. There are now several active developers
+contributing. The last stable release of Junkbuster was v2.0.2, which has now
+grown whiskers ;-).
+
diff --git a/doc/text/user-manual.txt b/doc/text/user-manual.txt
new file mode 100644 (file)
index 0000000..e3566a0
--- /dev/null
@@ -0,0 +1,4396 @@
+Privoxy User Manual
+
+Copyright Â© 2001, 2002 by Privoxy Developers
+
+$Id: user-manual.sgml,v 1.117 2002/05/17 13:56:16 oes Exp $
+
+The user manual gives users information on how to install, configure and use 
+Privoxy.
+
+Privoxy is a web proxy with advanced filtering capabilities for protecting
+privacy, filtering web page content, managing cookies, controlling access, and
+removing ads, banners, pop-ups and other obnoxious Internet junk. Privoxy has a
+very flexible configuration and can be customized to suit individual needs and
+tastes. Privoxy has application for both stand-alone systems and multi-user
+networks.
+
+Privoxy is based on Internet Junkbuster (tm).
+
+You can find the latest version of the user manual at http://www.privoxy.org/
+user-manual/. Please see the Contact section on how to contact the developers.
+
+-------------------------------------------------------------------------------
+
+Table of Contents
+1. Introduction
+   
+    1.1. Features
+   
+2. Installation
+   
+    2.1. Binary Packages
+       
+        2.1.1. Red Hat, SuSE RPMs and Conectiva
+        2.1.2. Debian
+        2.1.3. Windows
+        2.1.4. Solaris, NetBSD, FreeBSD, HP-UX
+        2.1.5. OS/2
+        2.1.6. Max OSX
+        2.1.7. AmigaOS
+       
+    2.2. Building from Source
+   
+3. Note to Upgraders
+4. Quickstart to Using Privoxy
+   
+    4.1. Quickstart to Ad Blocking
+   
+5. Starting Privoxy
+   
+    5.1. RedHat, Conectiva and Debian
+    5.2. SuSE
+    5.3. Windows
+    5.4. Solaris, NetBSD, FreeBSD, HP-UX and others
+    5.5. OS/2
+    5.6. MAX OSX
+    5.7. AmigaOS
+    5.8. Command Line Options
+   
+6. Privoxy Configuration
+   
+    6.1. Controlling Privoxy with Your Web Browser
+    6.2. Configuration Files Overview
+   
+7. The Main Configuration File
+   
+    7.1. Configuration and Log File Locations
+       
+        7.1.1. confdir
+        7.1.2. logdir
+        7.1.3. actionsfile
+        7.1.4. filterfile
+        7.1.5. logfile
+        7.1.6. jarfile
+        7.1.7. trustfile
+       
+    7.2. Local Set-up Documentation
+       
+        7.2.1. user-manual
+        7.2.2. trust-info-url
+        7.2.3. admin-address
+        7.2.4. proxy-info-url
+       
+    7.3. Debugging
+       
+        7.3.1. debug
+        7.3.2. single-threaded
+       
+    7.4. Access Control and Security
+       
+        7.4.1. listen-address
+        7.4.2. toggle
+        7.4.3. enable-remote-toggle
+        7.4.4. enable-edit-actions
+        7.4.5. ACLs: permit-access and deny-access
+        7.4.6. buffer-limit
+       
+    7.5. Forwarding
+       
+        7.5.1. forward
+        7.5.2. forward-socks4 and forward-socks4a
+        7.5.3. Advanced Forwarding Examples
+       
+    7.6. Windows GUI Options
+   
+8. Actions Files
+   
+    8.1. Finding the Right Mix
+    8.2. How to Edit
+    8.3. How Actions are Applied to URLs
+    8.4. Patterns
+       
+        8.4.1. The Domain Pattern
+        8.4.2. The Path Pattern
+       
+    8.5. Actions
+       
+        8.5.1. add-header
+        8.5.2. block
+        8.5.3. crunch-incoming-cookies
+        8.5.4. crunch-outgoing-cookies
+        8.5.5. deanimate-gifs
+        8.5.6. downgrade-http-version
+        8.5.7. fast-redirects
+        8.5.8. filter
+        8.5.9. handle-as-image
+        8.5.10. hide-forwarded-for-headers
+        8.5.11. hide-from-header
+        8.5.12. hide-referrer
+        8.5.13. hide-user-agent
+        8.5.14. kill-popups
+        8.5.15. limit-connect
+        8.5.16. prevent-compression
+        8.5.17. send-vanilla-wafer
+        8.5.18. send-wafer
+        8.5.19. session-cookies-only
+        8.5.20. set-image-blocker
+        8.5.21. Summary
+       
+    8.6. Aliases
+    8.7. Actions Files Tutorial
+       
+        8.7.1. default.action
+        8.7.2. user.action
+       
+9. The Filter File
+   
+    9.1. Filter File Tutorial
+   
+10. Templates
+11. Contacting the Developers, Bug Reporting and Feature Requests
+   
+    11.1. Get Support
+    11.2. Report Bugs
+    11.3. Request New Features
+    11.4. Report Ads or Other Actions-Related Problems
+    11.5. Other
+   
+12. Privoxy Copyright, License and History
+   
+    12.1. License
+    12.2. History
+    12.3. Authors
+   
+13. See Also
+14. Appendix
+   
+    14.1. Regular Expressions
+    14.2. Privoxy's Internal Pages
+       
+        14.2.1. Bookmarklets
+       
+    14.3. Chain of Events
+    14.4. Anatomy of an Action
+   
+1. Introduction
+
+This documentation is included with the current beta version of Privoxy,
+v.2.9.15, and is mostly complete at this point. The most up to date reference
+for the time being is still the comments in the source files and in the
+individual configuration files. Development of version 3.0 is currently nearing
+completion, and includes many significant changes and enhancements over earlier
+versions. The target release date for stable v3.0 is "soon" ;-).
+
+Since this is a beta version, not all new features are well tested. This
+documentation may be slightly out of sync as a result (especially with CVS
+sources). And there may be bugs, though hopefully not many!
+
+-------------------------------------------------------------------------------
+
+1.1. Features
+
+In addition to Internet Junkbuster's traditional features of ad and banner
+blocking and cookie management, Privoxy provides new features, some of them
+currently under development:
+
+  * Integrated browser based configuration and control utility at http://
+    config.privoxy.org/ (shortcut: http://p.p/). Browser-based tracing of rule
+    and filter effects. Remote toggling.
+   
+  * Web page content filtering (removes banners based on size, invisible
+    "web-bugs", JavaScript and HTML annoyances, pop-up windows, etc.)
+   
+  * Modularized configuration that allows for standard settings and user
+    settings to reside in separate files, so that installing updated actions
+    files won't overwrite individual user settings.
+   
+  * HTTP/1.1 compliant (but not all optional 1.1 features are supported).
+   
+  * Support for Perl Compatible Regular Expressions in the configuration files,
+    and generally a more sophisticated and flexible configuration syntax over
+    previous versions.
+   
+  * Improved cookie management features (e.g. session based cookies).
+   
+  * GIF de-animation.
+   
+  * Bypass many click-tracking scripts (avoids script redirection).
+   
+  * Multi-threaded (POSIX and native threads).
+   
+  * User-customizable HTML templates for all proxy-generated pages (e.g.
+    "blocked" page).
+   
+  * Auto-detection and re-reading of config file changes.
+   
+  * Improved signal handling, and a true daemon mode (Unix).
+   
+  * Every feature now controllable on a per-site or per-location basis,
+    configuration more powerful and versatile over-all.
+   
+  * Many smaller new features added, limitations and bugs removed, and security
+    holes fixed.
+   
+-------------------------------------------------------------------------------
+
+2. Installation
+
+Privoxy is available both in convenient pre-compiled packages for a wide range
+of operating systems, and as raw source code. For most users, we recommend
+using the packages, which can be downloaded from our Privoxy Project Page.
+
+Note: If you have a previous Junkbuster or Privoxy installation on your system,
+you will need to remove it. On some platforms, this may be done for you as part
+of their installation procedure. (See below for your platform). In any case be
+sure to backup your old configuration if it is valuable to you. See the note to
+upgraders section below.
+
+-------------------------------------------------------------------------------
+
+2.1. Binary Packages
+
+How to install the binary packages depends on your operating system:
+
+-------------------------------------------------------------------------------
+
+2.1.1. Red Hat, SuSE RPMs and Conectiva
+
+RPMs can be installed with rpm -Uvh privoxy-2.9.15-1.rpm, and will use /etc/
+privoxy for the location of configuration files.
+
+Note that on Red Hat, Privoxy will not be automatically started on system boot.
+You will need to enable that using chkconfig, ntsysv, or similar methods. Note
+that SuSE will automatically start Privoxy in the boot process.
+
+If you have problems with failed dependencies, try rebuilding the SRC RPM: rpm
+--rebuild privoxy-2.9.15-1.src.rpm;. This will use your locally installed
+libraries and RPM version.
+
+Also note that if you have a Junkbuster RPM installed on your system, you need
+to remove it first, because the packages conflict. Otherwise, RPM will try to
+remove Junkbuster automatically, before installing Privoxy.
+
+-------------------------------------------------------------------------------
+
+2.1.2. Debian
+
+FIXME.
+
+-------------------------------------------------------------------------------
+
+2.1.3. Windows
+
+Just double-click the installer, which will guide you through the installation
+process. You will find the configuration files in the same directory as you
+installed Privoxy in. We do not use the registry of Windows.
+
+-------------------------------------------------------------------------------
+
+2.1.4. Solaris, NetBSD, FreeBSD, HP-UX
+
+Create a new directory, cd to it, then unzip and untar the archive. For the
+most part, you'll have to figure out where things go. FIXME.
+
+-------------------------------------------------------------------------------
+
+2.1.5. OS/2
+
+First, make sure that no previous installations of Junkbuster and / or Privoxy
+are left on your system. You can do this by
+
+Then, just double-click the WarpIN self-installing archive, which will guide
+you through the installation process. A shadow of the Privoxy executable will
+be placed in your startup folder so it will start automatically whenever OS/2
+starts.
+
+The directory you choose to install Privoxy into will contain all of the
+configuration files.
+
+-------------------------------------------------------------------------------
+
+2.1.6. Max OSX
+
+Unzip the downloaded package (you can either double-click on the file in the
+finder, or on the desktop if you downloaded it there). Then, double-click on
+the package installer icon and follow the installation process. Privoxy will be
+installed in the subdirectory /Applications/Privoxy.app. Privoxy will set
+itself up to start automatically on system bring-up via /System/Library/
+StartupItems/Privoxy.
+
+-------------------------------------------------------------------------------
+
+2.1.7. AmigaOS
+
+Copy and then unpack the lha archive to a suitable location. All necessary
+files will be installed into Privoxy directory, including all configuration and
+log files. To uninstall, just remove this directory.
+
+Start Privoxy (with RUN <>NIL:) in your startnet script (AmiTCP), in s:
+user-startup (RoadShow), as startup program in your startup script (Genesis),
+or as startup action (Miami and MiamiDx). Privoxy will automatically quit when
+you quit your TCP/IP stack (just ignore the harmless warning your TCP/IP stack
+may display that Privoxy is still running).
+
+-------------------------------------------------------------------------------
+
+2.2. Building from Source
+
+The most convenient way to obtain the Privoxy sources is to download the source
+tarball from our project page.
+
+If you like to live on the bleeding edge and are not afraid of using possibly
+unstable development versions, you can check out the up-to-the-minute version
+directly from the CVS repository or simply download the nightly CVS tarball.
+
+To build Privoxy from source, autoconf, GNU make (gmake), and, of course, a C
+compiler like gcc are required.
+
+When building from a source tarball (either release version or nightly CVS
+tarball), first unpack the source:
+
+ tar xzvf privoxy-2.9.15-beta-src* [.tgz or .tar.gz]                           
+ cd privoxy-2.9.15-beta                                                        
+
+For retrieving the current CVS sources, you'll need CVS installed. Note that
+sources from CVS are development quality, and may not be stable, or well
+tested. To download CVS source:
+
+  cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login          
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co current 
+  cd current                                                                         
+
+This will create a directory named current/, which will contain the source
+tree.
+
+Then, in either case, to build from unpacked tarball or CVS source:
+
+ autoheader                                                                    
+ autoconf                                                                      
+ ./configure      # (--help to see options)                                    
+ make             # (the make from gnu, gmake for *BSD)                        
+ su                                                                            
+ make -n install  # (to see where all the files will go)                       
+ make install     # (to really install)                                        
+
+If you have gnu make, you can have the first four steps automatically done for
+you by just typing:
+
+  make                                                                         
+
+in the freshly downloaded or unpacked source directory.
+
+For more detailed instructions on how to build Redhat and SuSE RPMs, Windows
+self-extracting installers, building on platforms with special requirements
+etc, please consult the developer manual.
+
+-------------------------------------------------------------------------------
+
+3. Note to Upgraders
+
+There are very significant changes from earlier Junkbuster versions to the
+current Privoxy. The number, names, syntax, and purposes of configuration files
+have substantially changed. Junkbuster 2.0.x configuration files will not
+migrate, Junkbuster 2.9.x and Privoxy configurations will need to be ported.
+The functionalities of the old blockfile, cookiefile and imagelist are now
+combined into the "actions files". default.action, is the main actions file.
+Local exceptions should best be put into user.action.
+
+A "filter file" (typically default.filter) is new as of Privoxy 2.9.x, and
+provides some of the new sophistication (explained below). config is much the
+same as before.
+
+If upgrading from a 2.0.x version, you will have to use the new config files,
+and possibly adapt any personal rules from your older files. When porting
+personal rules over from the old blockfile to the new actions files, please
+note that even the pattern syntax has changed. If upgrading from 2.9.x
+development versions, it is still recommended to use the new configuration
+files.
+
+A quick list of things to be aware of before upgrading:
+
+  * The default listening port is now 8118 due to a conflict with another
+    service (NAS).
+   
+  * Some installers may remove earlier versions completely. Save any important
+    configuration files!
+   
+  * Privoxy is controllable with a web browser at the special URL: http://
+    config.privoxy.org/ (Shortcut: http://p.p/). Many aspects of configuration
+    can be done here, including temporarily disabling Privoxy.
+   
+  * The primary configuration files for cookie management, ad and banner
+    blocking, and many other aspects of Privoxy configuration are the actions
+    files. It is strongly recommended to become familiar with the new actions
+    concept below, before modifying these files. Locally defined rules should
+    go into user.action.
+   
+  * Some installers may not automatically start Privoxy after installation.
+   
+-------------------------------------------------------------------------------
+
+4. Quickstart to Using Privoxy
+
+  * If upgrading, from versions before 2.9.16, please back up any configuration
+    files. See the Note to Upgraders Section.
+   
+  * Install Privoxy. See the Installation Section below for platform specific
+    information.
+   
+  * Advanced users and those who want to offer Privoxy service to more than
+    just their local machine should check the main config file, especially the 
+    security-relevant options. These are off by default.
+   
+  * Start Privoxy, if the installation program has not done this already (may
+    vary according to platform). See the section Starting Privoxy.
+   
+  * Set your browser to use Privoxy as HTTP and HTTPS proxy by setting the
+    proxy configuration for address of 127.0.0.1 and port 8118. (Junkbuster and
+    earlier versions of Privoxy used port 8000.) See the section Starting
+    Privoxy below for more details on this.
+   
+  * Flush your browser's disk and memory caches, to remove any cached ad
+    images.
+   
+  * A default installation should provide a reasonable starting point for most.
+    There will undoubtedly be occasions where you will want to adjust the
+    configuration, but that can be dealt with as the need arises. Little to no
+    initial configuration is required in most cases.
+   
+    See the Configuration section for more configuration options, and how to
+    customize your installation.
+   
+  * If you experience ads that slipped through, innocent images that are
+    blocked, or otherwise feel the need to fine-tune Privoxy's behaviour, take
+    a look at the actions files. As a quick start, you might find the richly
+    commented examples helpful. You can also view and edit the actions files
+    through the web-based user interface. The Appendix "Anatomy of an Action"
+    has hints how to debug actions that "misbehave".
+   
+  * Please see the section Contacting the Developers on how to report bugs or
+    problems with websites or to get help.
+   
+  * Now enjoy surfing with enhanced comfort and privacy!
+   
+-------------------------------------------------------------------------------
+
+4.1. Quickstart to Ad Blocking
+
+Ad blocking is but one of Privoxy's array of features. Many of these features
+are for the technically minded advanced user. But, ad and banner blocking is
+surely common ground for everybody.
+
+This section will provide a quick summary of ad blocking so you can get up to
+speed quickly without having to read the more extensive information provided
+below, though this is highly recommeneded.
+
+First a bit of a warning ... blocking ads is much like blocking SPAM: the more
+aggressive you are about it, the more likely you are to block things that were
+not intended. So there is a trade off here. If you want extreme ad free
+browsing, be prepared to deal with more "problem" sites, and to spend more time
+adjusting the configuration to solve these unintended consequences. In short,
+there is not an easy way to eliminate all ads. Either take the easy way and
+settle for most ads blocked with the default configuration, or jump in and
+tweak it for your personal surfing habits and preferences.
+
+Secondly, a brief explanation of Privoxy's "actions". "Actions" in this
+context, are the directives we use to tell Privoxy to perform some task
+relating to HTTP transactions (i.e. web browsing). We tell Privoxy to take some
+"action". Each action has a unique name and function. While there are many
+potential actions in Privoxy's arsenal, only a few are used for ad blocking. 
+Actions, and action configuration files, are explained in depth below.
+
+Actions are specified in Privoxy's configuration, followed by one or more URLs
+to which the action should apply. URLs can actually be URL type patterns that
+use wildcards so they can apply potentially to a range of similar URLs.
+
+When you connect to a website, the full path of the URL will either match one
+of the "actions" as defined in Privoxy's configuration, or not. If so, then
+Privoxy will perform the action accordingly. If not, then nothing special
+happens. Futhermore, web pages may contain embedded, secondary URLs that your
+web browser will display as it parses the original page's HTML content. An ad
+image for instance, is just a URL embedded in the page somewhere. The image
+itself may be on the same server, or a server somewhere else on the Internet.
+Complex web pages will have many such embedded URLs.
+
+The actions we need to know about for ad blocking are: block, handle-as-image,
+and set-image-blocker:
+
+  * block - this action stops any contact between your browser and any URL
+    patterns that match this action's configuration. It can be used for
+    blocking ads, but also anything that is determined to be unwanted. By
+    itself, it simply stops any communication with the remote server. If this
+    is the only action that matches for this particular URL, then Privoxy will
+    display its own BLOCKED page to let you now what has happened.
+   
+  * handle-as-image - forces Privoxy to treat this URL as if it were an image.
+    Privoxy knows about common image types (e.g. GIF), but there are many
+    situations where this does not apply. So we'll force it. This is
+    particularly important for ad blocking, since once we can treat it as an
+    image, we can make more intelligent decisisions on how to handle it. There
+    are some limitations to this though. For instance, you can't just force an
+    image substituion for an entire HTML page in most situations.
+   
+  * set-image-blocker - tells Privoxy what to display in place of an ad image
+    that has hit a block rule. For this to come into play, the URL must match a
+    block action somewhere in the configuration. And, it must also either be of
+    a known image type, or match an handle-as-image action.
+   
+    The configuration options on what to display instead of the ad are:
+   
+       pattern - a checkboard pattern, so that an ad replacement is obvious.   
+    This is the default.                                                       
+   
+       blank - A very small empty GIF image is displayed. This is the so-called
+    "invisible" configuration option.                                          
+   
+       http://<URL> - A redirect to any URL of the user's choosing (advanced   
+    usage).                                                                    
+   
+The quickest way to adjust any of these settings is with your browser through
+the special Privoxy editor at http://config.privoxy.org/show-status (shortcut: 
+http://p.p/show-status). This is an internal page, and does not require
+Internet access. Select the appropriate "actions" file, and click "Edit". It is
+best to put personal or local preferences in user.action since this is not
+meant to be overwritten during upgrades, and will over-ride the settings in
+other files. Here you can insert new "actions", and URLs for ad blocking or
+other purposes, and make other adjustments to the configuration. Privoxy will
+detect these changes automatically.
+
+A quick and simple step by step example:
+
+  * Right click on the ad image to be blocked, then select "Copy Link Location"
+    from the pop-up menu.
+   
+  * Set your browser to http://config.privoxy.org/show-status
+   
+  * Find user.action in the top section, and click on "Edit":
+   
+    Figure 1. Actions Files in Use
+   
+    Screenshot of Files in Use
+   
+  * You should have an Actions section labeled +block. If not, click the "Edit"
+    button just under the word "Actions". This will bring up a list of all
+    actions. Find block near the top, and click in the "Enabled" column, then
+    "Submit" just below the list.
+   
+  * Now, in the +block actions section, click the "Add" button, and paste the
+    URL the browser got from "Copy Link Location". Remove the http:// at the
+    beginning of the URL. Then, click "Submit".
+   
+  * Now go back to the original page, and press SHIFT-Reload (or flush all
+    browser caches). The image should be gone now.
+   
+This is a very crude and simple example. There might be good reasons to use a
+wildcard pattern match to include potentially similar images from the same
+site. For a more extensive explanation of "patterns", and the entire actions
+concept, see the Actions section.
+
+For advanced users who want to hand edit their config files, you might want to
+now go to the Actions Files Tutorial.
+
+-------------------------------------------------------------------------------
+
+5. Starting Privoxy
+
+Before launching Privoxy for the first time, you will want to configure your
+browser(s) to use Privoxy as a HTTP and HTTPS proxy. The default is 127.0.0.1
+(or localhost) for the proxy address, and port 8118 (earlier versions used port
+8000). This is the one configuration step that must be done!
+
+With Netscape (and Mozilla), this can be set under Edit -> Preferences ->
+Advanced -> Proxies -> HTTP Proxy. For Internet Explorer: Tools -> Internet
+Properties -> Connections -> LAN Setting. Then, check "Use Proxy" and fill in
+the appropriate info (Address: 127.0.0.1, Port: 8118). Include if HTTPS proxy
+support too.
+
+After doing this, flush your browser's disk and memory caches to force a
+re-reading of all pages and to get rid of any ads that may be cached. You are
+now ready to start enjoying the benefits of using Privoxy!
+
+Privoxy is typically started by specifying the main configuration file to be
+used on the command line. If no configuration file is specified on the command
+line, Privoxy will look for a file named config in the current directory.
+Except on Win32 where it will try config.txt.
+
+-------------------------------------------------------------------------------
+
+5.1. RedHat, Conectiva and Debian
+
+We use a script. Note that RedHat does not start Privoxy upon booting per
+default. It will use the file /etc/privoxy/config as its main configuration
+file. FIXME: Debian??
+
+ # /etc/rc.d/init.d/privoxy start                                              
+
+-------------------------------------------------------------------------------
+
+5.2. SuSE
+
+We use a script. It will use the file /etc/privoxy/config as its main
+configuration file. Note that SuSE starts Privoxy upon booting your PC.
+
+ # rcprivoxy start                                                             
+
+-------------------------------------------------------------------------------
+
+5.3. Windows
+
+Click on the Privoxy Icon to start Privoxy. If no configuration file is
+specified on the command line, Privoxy will look for a file named config.txt.
+Note that Windows will automatically start Privoxy upon booting you PC.
+
+-------------------------------------------------------------------------------
+
+5.4. Solaris, NetBSD, FreeBSD, HP-UX and others
+
+Example Unix startup command:
+
+ # /usr/sbin/privoxy /etc/privoxy/config                                       
+
+-------------------------------------------------------------------------------
+
+5.5. OS/2
+
+FIXME.
+
+-------------------------------------------------------------------------------
+
+5.6. MAX OSX
+
+FIXME.
+
+-------------------------------------------------------------------------------
+
+5.7. AmigaOS
+
+FIXME.
+
+-------------------------------------------------------------------------------
+
+5.8. Command Line Options
+
+Privoxy may be invoked with the following command-line options:
+
+  * --version
+   
+    Print version info and exit. Unix only.
+   
+  * --help
+   
+    Print short usage info and exit. Unix only.
+   
+  * --no-daemon
+   
+    Don't become a daemon, i.e. don't fork and become process group leader, and
+    don't detach from controlling tty. Unix only.
+   
+  * --pidfile FILE
+   
+    On startup, write the process ID to FILE. Delete the FILE on exit. Failure
+    to create or delete the FILE is non-fatal. If no FILE option is given, no
+    PID file will be used. Unix only.
+   
+  * --user USER[.GROUP]
+   
+    After (optionally) writing the PID file, assume the user ID of USER, and if
+    included the GID of GROUP. Exit if the privileges are not sufficient to do
+    so. Unix only.
+   
+  * configfile
+   
+    If no configfile is included on the command line, Privoxy will look for a
+    file named "config" in the current directory (except on Win32 where it will
+    look for "config.txt" instead). Specify full path to avoid confusion. If no
+    config file is found, Privoxy will fail to start.
+   
+-------------------------------------------------------------------------------
+
+6. Privoxy Configuration
+
+All Privoxy configuration is stored in text files. These files can be edited
+with a text editor. Many important aspects of Privoxy can also be controlled
+easily with a web browser.
+
+-------------------------------------------------------------------------------
+
+6.1. Controlling Privoxy with Your Web Browser
+
+Privoxy's user interface can be reached through the special URL http://
+config.privoxy.org/ (shortcut: http://p.p/), which is a built-in page and works
+without Internet access. You will see the following section: 
+
+ Privoxy Menu                                                                  
+        ?  View & change the current configuration                             
+        ?  View the source code version numbers                                
+        ?  View the request headers.                                           
+        ?  Look up which actions apply to a URL and why                        
+        ?  Toggle Privoxy on or off                                            
+                                                                               
+
+This should be self-explanatory. Note the first item leads to an editor for the
+actions files, which is where the ad, banner, cookie, and URL blocking magic is
+configured as well as other advanced features of Privoxy. This is an easy way
+to adjust various aspects of Privoxy configuration. The actions file, and other
+configuration files, are explained in detail below.
+
+"Toggle Privoxy On or Off" is handy for sites that might have problems with
+your current actions and filters. You can in fact use it as a test to see
+whether it is Privoxy causing the problem or not. Privoxy continues to run as a
+proxy in this case, but all manipulation is disabled, i.e. Privoxy acts like a
+normal forwarding proxy. There is even a toggle Bookmarklet offered, so that
+you can toggle Privoxy with one click from your browser.
+
+-------------------------------------------------------------------------------
+
+6.2. Configuration Files Overview
+
+For Unix, *BSD and Linux, all configuration files are located in /etc/privoxy/
+by default. For MS Windows, OS/2, and AmigaOS these are all in the same
+directory as the Privoxy executable. The name and number of configuration files
+has changed from previous versions, and is subject to change as development
+progresses.
+
+The installed defaults provide a reasonable starting point, though some
+settings may be aggressive by some standards. For the time being, the principle
+configuration files are:
+
+  * The main configuration file is named config on Linux, Unix, BSD, OS/2, and
+    AmigaOS and config.txt on Windows. This is a required file.
+   
+  * default.action (the main actions file) is used to define which "actions"
+    relating to banner-blocking, images, pop-ups, content modification, cookie
+    handling etc should be applied by default. It also defines many exceptions
+    (both positive and negative) from this default set of actions that enable
+    Privoxy to selectively eliminate the junk, and only the junk, on as many
+    websites as possible.
+   
+    Multiple actions files may be defined in config. These are processed in the
+    order they are defined. Local customizations and locally preferred
+    exceptions to the default policies as defined in default.action (which you
+    will most probably want to define sooner or later) are probably best
+    applied in user.action, where you can preserve them across upgrades.
+    standard.action is for Privoxy's internal use.
+   
+    There is also a web based editor that can be accessed from http://
+    config.privoxy.org/show-status (Shortcut: http://p.p/show-status) for the
+    various actions files.
+   
+  * default.filter (the filter file) can be used to re-write the raw page
+    content, including viewable text as well as embedded HTML and JavaScript,
+    and whatever else lurks on any given web page. The filtering jobs are only
+    pre-defined here; whether to apply them or not is up to the actions files.
+   
+All files use the "#" character to denote a comment (the rest of the line will
+be ignored) and understand line continuation through placing a backslash ("\")
+as the very last character in a line. If the # is preceded by a backslash, it
+looses its special function. Placing a # in front of an otherwise valid
+configuration line to prevent it from being interpreted is called "commenting
+out" that line.
+
+The actions files and default.filter can use Perl style regular expressions for
+maximum flexibility.
+
+After making any changes, there is no need to restart Privoxy in order for the
+changes to take effect. Privoxy detects such changes automatically. Note,
+however, that it may take one or two additional requests for the change to take
+effect. When changing the listening address of Privoxy, these "wake up"
+requests must obviously be sent to the old listening address.
+
+While under development, the configuration content is subject to change. The
+below documentation may not be accurate by the time you read this. Also, what
+constitutes a "default" setting, may change, so please check all your
+configuration files on important issues.
+
+-------------------------------------------------------------------------------
+
+7. The Main Configuration File
+
+Again, the main configuration file is named config on Linux/Unix/BSD and OS/2,
+and config.txt on Windows. Configuration lines consist of an initial keyword
+followed by a list of values, all separated by whitespace (any number of spaces
+or tabs). For example:
+
+  confdir /etc/privoxy
+
+Assigns the value /etc/privoxy to the option confdir and thus indicates that
+the configuration directory is named "/etc/privoxy/".
+
+All options in the config file except for confdir and logdir are optional.
+Watch out in the below description for what happens if you leave them unset.
+
+The main config file controls all aspects of Privoxy's operation that are not
+location dependent (i.e. they apply universally, no matter where you may be
+surfing).
+
+-------------------------------------------------------------------------------
+
+7.1. Configuration and Log File Locations
+
+Privoxy can (and normally does) use a number of other files for additional
+configuration, help and logging. This section of the configuration file tells
+Privoxy where to find those other files.
+
+The user running Privoxy, must have read permission for all configuration
+files, and write permission to any files that would be modified, such as log
+files.
+
+-------------------------------------------------------------------------------
+
+7.1.1. confdir
+
+Specifies:
+   
+    The directory where the other configuration files are located
+   
+Type of value:
+   
+    Path name
+   
+Default value:
+   
+    /etc/privoxy (Unix) or Privoxy installation dir (Windows)
+   
+Effect if unset:
+   
+    Mandatory
+   
+Notes:
+   
+    No trailing "/", please
+   
+    When development goes modular and multi-user, the blocker, filter, and
+    per-user config will be stored in subdirectories of "confdir". For now, the
+    configuration directory structure is flat, except for confdir/templates,
+    where the HTML templates for CGI output reside (e.g. Privoxy's 404 error
+    page).
+   
+-------------------------------------------------------------------------------
+
+7.1.2. logdir
+
+Specifies:
+   
+    The directory where all logging takes place (i.e. where logfile and jarfile
+    are located)
+   
+Type of value:
+   
+    Path name
+   
+Default value:
+   
+    /var/log/privoxy (Unix) or Privoxy installation dir (Windows)
+   
+Effect if unset:
+   
+    Mandatory
+   
+Notes:
+   
+    No trailing "/", please
+   
+-------------------------------------------------------------------------------
+
+7.1.3. actionsfile
+
+Specifies:
+   
+    The actions file(s) to use
+   
+Type of value:
+   
+    File name, relative to confdir, without the .action suffix
+   
+Default values:
+   
+      standard     # Internal purposes, no editing recommended
+                                                              
+      default      # Main actions file                        
+                                                              
+      user         # User customizations                      
+   
+Effect if unset:
+   
+    No actions are taken at all. Simple neutral proxying.
+   
+Notes:
+   
+    Multiple actionsfile lines are permitted, and are in fact recommended!
+   
+    The default values include standard.action, which is used for internal
+    purposes and should be loaded, default.action, which is the "main" actions
+    file maintained by the developers, and user.action, where you can make your
+    personal additions.
+   
+    Actions files are where all the per site and per URL configuration is done
+    for ad blocking, cookie management, privacy considerations, etc. There is
+    no point in using Privoxy without at least one actions file.
+   
+-------------------------------------------------------------------------------
+
+7.1.4. filterfile
+
+Specifies:
+   
+    The filter file to use
+   
+Type of value:
+   
+    File name, relative to confdir
+   
+Default value:
+   
+    default.filter (Unix) or default.filter.txt (Windows)
+   
+Effect if unset:
+   
+    No textual content filtering takes place, i.e. all +filter{name} actions in
+    the actions files are turned neutral.
+   
+Notes:
+   
+    The filter file contains content modification rules that use regular
+    expressions. These rules permit powerful changes on the content of Web
+    pages, e.g., you could disable your favorite JavaScript annoyances,
+    re-write the actual displayed text, or just have some fun replacing
+    "Microsoft" with "MicroSuck" wherever it appears on a Web page.
+   
+    The +filter{name} actions rely on the relevant filter (name) to be defined
+    in the filter file!
+   
+    A pre-defined filter file called default.filter that contains a bunch of
+    handy filters for common problems is included in the distribution. See the
+    section on the filter action for a list.
+   
+-------------------------------------------------------------------------------
+
+7.1.5. logfile
+
+Specifies:
+   
+    The log file to use
+   
+Type of value:
+   
+    File name, relative to logdir
+   
+Default value:
+   
+    logfile (Unix) or privoxy.log (Windows)
+   
+Effect if unset:
+   
+    No log file is used, all log messages go to the console (stderr).
+   
+Notes:
+   
+    The windows version will additionally log to the console.
+   
+    The logfile is where all logging and error messages are written. The level
+    of detail and number of messages are set with the debug option (see below).
+    The logfile can be useful for tracking down a problem with Privoxy (e.g.,
+    it's not blocking an ad you think it should block) but in most cases you
+    probably will never look at it.
+   
+    Your logfile will grow indefinitely, and you will probably want to
+    periodically remove it. On Unix systems, you can do this with a cron job
+    (see "man cron"). For Red Hat, a logrotate script has been included.
+   
+    On SuSE Linux systems, you can place a line like "/var/log/privoxy.* +1024k
+    644 nobody.nogroup" in /etc/logfiles, with the effect that cron.daily will
+    automatically archive, gzip, and empty the log, when it exceeds 1M size.
+   
+    Any log files must be writable by whatever user Privoxy is being run as
+    (default on UNIX, user id is "privoxy").
+   
+-------------------------------------------------------------------------------
+
+7.1.6. jarfile
+
+Specifies:
+   
+    The file to store intercepted cookies in
+   
+Type of value:
+   
+    File name, relative to logdir
+   
+Default value:
+   
+    jarfile (Unix) or privoxy.jar (Windows)
+   
+Effect if unset:
+   
+    Intercepted cookies are not stored at all.
+   
+Notes:
+   
+    The jarfile may grow to ridiculous sizes over time.
+   
+-------------------------------------------------------------------------------
+
+7.1.7. trustfile
+
+Specifies:
+   
+    The trust file to use
+   
+Type of value:
+   
+    File name, relative to confdir
+   
+Default value:
+   
+    Unset (commented out). When activated: trust (Unix) or trust.txt (Windows)
+   
+Effect if unset:
+   
+    The whole trust mechanism is turned off.
+   
+Notes:
+   
+    The trust mechanism is an experimental feature for building white-lists and
+    should be used with care. It is NOT recommended for the casual user.
+   
+    If you specify a trust file, Privoxy will only allow access to sites that
+    are named in the trustfile. You can also mark sites as trusted referrers
+    (with +), with the effect that access to untrusted sites will be granted,
+    if a link from a trusted referrer was used. The link target will then be
+    added to the "trustfile". Possible applications include limiting Internet
+    access for children.
+   
+    If you use + operator in the trust file, it may grow considerably over
+    time.
+   
+-------------------------------------------------------------------------------
+
+7.2. Local Set-up Documentation
+
+If you intend to operate Privoxy for more users than just yourself, it might be
+a good idea to let them know how to reach you, what you block and why you do
+that, your policies, etc.
+
+-------------------------------------------------------------------------------
+
+7.2.1. user-manual
+
+Specifies:
+   
+    Location of the Privoxy User Manual.
+   
+Type of value:
+   
+    A fully qualified URI
+   
+Default value:
+   
+    Unset
+   
+Effect if unset:
+   
+    http://www.privoxy.org/version/user-manual/ will be used, where version is
+    the Privoxy version.
+   
+Notes:
+   
+    The User Manual URI is used for help links from some of the internal CGI
+    pages. The manual itself is normally packaged with the binary
+    distributions, so you probably want to set this to a locally installed
+    copy. For multi-user setups, you could provide a copy on a local webserver
+    for all your users and use the corresponding URL here.
+   
+    Examples:
+   
+    Unix, in local filesystem:
+   
+    user-manual  file:///usr/share/doc/privoxy-2.9.15/user-manual/     
+   
+    Any platform, on local webserver (called "local-webserver"):
+   
+    user-manual  http://local-webserver/privoxy-user-manual/           
+   
+    +-----------------------------------------------------------------+
+    |                             Warning                             |
+    |-----------------------------------------------------------------|
+    |If set, this option should be the first option in the config     |
+    |file, because it is used while the config file is being read.    |
+    +-----------------------------------------------------------------+
+
+-------------------------------------------------------------------------------
+
+7.2.2. trust-info-url
+
+Specifies:
+   
+    A URL to be displayed in the error page that users will see if access to an
+    untrusted page is denied.
+   
+Type of value:
+   
+    URL
+   
+Default value:
+   
+    Two example URL are provided
+   
+Effect if unset:
+   
+    No links are displayed on the "untrusted" error page.
+   
+Notes:
+   
+    The value of this option only matters if the experimental trust mechanism
+    has been activated. (See trustfile above.)
+   
+    If you use the trust mechanism, it is a good idea to write up some on-line
+    documentation about your trust policy and to specify the URL(s) here. Use
+    multiple times for multiple URLs.
+   
+    The URL(s) should be added to the trustfile as well, so users don't end up
+    locked out from the information on why they were locked out in the first
+    place!
+   
+-------------------------------------------------------------------------------
+
+7.2.3. admin-address
+
+Specifies:
+   
+    An email address to reach the proxy administrator.
+   
+Type of value:
+   
+    Email address
+   
+Default value:
+   
+    Unset
+   
+Effect if unset:
+   
+    No email address is displayed on error pages and the CGI user interface.
+   
+Notes:
+   
+    If both admin-address and proxy-info-url are unset, the whole "Local
+    Privoxy Support" box on all generated pages will not be shown.
+   
+-------------------------------------------------------------------------------
+
+7.2.4. proxy-info-url
+
+Specifies:
+   
+    A URL to documentation about the local Privoxy setup, configuration or
+    policies.
+   
+Type of value:
+   
+    URL
+   
+Default value:
+   
+    Unset
+   
+Effect if unset:
+   
+    No link to local documentation is displayed on error pages and the CGI user
+    interface.
+   
+Notes:
+   
+    If both admin-address and proxy-info-url are unset, the whole "Local
+    Privoxy Support" box on all generated pages will not be shown.
+   
+    This URL shouldn't be blocked ;-)
+   
+-------------------------------------------------------------------------------
+
+7.3. Debugging
+
+These options are mainly useful when tracing a problem. Note that you might
+also want to invoke Privoxy with the --no-daemon command line option when
+debugging.
+
+-------------------------------------------------------------------------------
+
+7.3.1. debug
+
+Specifies:
+   
+    Key values that determine what information gets logged to the logfile.
+   
+Type of value:
+   
+    Integer values
+   
+Default value:
+   
+    12289 (i.e.: URLs plus informational and warning messages)
+   
+Effect if unset:
+   
+    Nothing gets logged.
+   
+Notes:
+   
+    The available debug levels are:
+   
+      debug         1 # show each GET/POST/CONNECT request             
+      debug         2 # show each connection status                    
+      debug         4 # show I/O status                                
+      debug         8 # show header parsing                            
+      debug        16 # log all data into the logfile                  
+      debug        32 # debug force feature                            
+      debug        64 # debug regular expression filter                
+      debug       128 # debug fast redirects                           
+      debug       256 # debug GIF de-animation                         
+      debug       512 # Common Log Format                              
+      debug      1024 # debug kill pop-ups                             
+      debug      4096 # Startup banner and warnings.                   
+      debug      8192 # Non-fatal errors                               
+   
+    To select multiple debug levels, you can either add them or use multiple
+    debug lines.
+   
+    A debug level of 1 is informative because it will show you each request as
+    it happens. 1, 4096 and 8192 are highly recommended so that you will notice
+    when things go wrong. The other levels are probably only of interest if you
+    are hunting down a specific problem. They can produce a hell of an output
+    (especially 16).
+   
+    The reporting of fatal errors (i.e. ones which crash Privoxy) is always on
+    and cannot be disabled.
+   
+    If you want to use CLF (Common Log Format), you should set "debug 512" ONLY
+    and not enable anything else.
+   
+-------------------------------------------------------------------------------
+
+7.3.2. single-threaded
+
+Specifies:
+   
+    Whether to run only one server thread
+   
+Type of value:
+   
+    None
+   
+Default value:
+   
+    Unset
+   
+Effect if unset:
+   
+    Multi-threaded (or, where unavailable: forked) operation, i.e. the ability
+    to serve multiple requests simultaneously.
+   
+Notes:
+   
+    This option is only there for debug purposes and you should never need to
+    use it. It will drastically reduce performance.
+   
+-------------------------------------------------------------------------------
+
+7.4. Access Control and Security
+
+This section of the config file controls the security-relevant aspects of
+Privoxy's configuration.
+
+-------------------------------------------------------------------------------
+
+7.4.1. listen-address
+
+Specifies:
+   
+    The IP address and TCP port on which Privoxy will listen for client
+    requests.
+   
+Type of value:
+   
+    [IP-Address]:Port
+   
+Default value:
+   
+    127.0.0.1:8118
+   
+Effect if unset:
+   
+    Bind to 127.0.0.1 (localhost), port 8118. This is suitable and recommended
+    for home users who run Privoxy on the same machine as their browser.
+   
+Notes:
+   
+    You will need to configure your browser(s) to this proxy address and port.
+   
+    If you already have another service running on port 8118, or if you want to
+    serve requests from other machines (e.g. on your local network) as well,
+    you will need to override the default.
+   
+    If you leave out the IP address, Privoxy will bind to all interfaces
+    (addresses) on your machine and may become reachable from the Internet. In
+    that case, consider using access control lists (ACL's) (see "ACLs" below),
+    or a firewall.
+   
+Example:
+   
+    Suppose you are running Privoxy on a machine which has the address
+    192.168.0.1 on your local private network (192.168.0.0) and has another
+    outside connection with a different address. You want it to serve requests
+    from inside only:
+   
+      listen-address  192.168.0.1:8118                                 
+   
+-------------------------------------------------------------------------------
+
+7.4.2. toggle
+
+Specifies:
+   
+    Initial state of "toggle" status
+   
+Type of value:
+   
+    1 or 0
+   
+Default value:
+   
+    1
+   
+Effect if unset:
+   
+    Act as if toggled on
+   
+Notes:
+   
+    If set to 0, Privoxy will start in "toggled off" mode, i.e. behave like a
+    normal, content-neutral proxy where all ad blocking, filtering, etc are
+    disabled. See enable-remote-toggle below. This is not really useful
+    anymore, since toggling is much easier via the web interface than via
+    editing the conf file.
+   
+    The windows version will only display the toggle icon in the system tray if
+    this option is present.
+   
+-------------------------------------------------------------------------------
+
+7.4.3. enable-remote-toggle
+
+Specifies:
+   
+    Whether or not the web-based toggle feature may be used
+   
+Type of value:
+   
+    0 or 1
+   
+Default value:
+   
+    1
+   
+Effect if unset:
+   
+    The web-based toggle feature is disabled.
+   
+Notes:
+   
+    When toggled off, Privoxy acts like a normal, content-neutral proxy, i.e.
+    it acts as if none of the actions applied to any URL.
+   
+    For the time being, access to the toggle feature can not be controlled
+    separately by "ACLs" or HTTP authentication, so that everybody who can
+    access Privoxy (see "ACLs" and listen-address above) can toggle it for all
+    users. So this option is not recommended for multi-user environments with
+    untrusted users.
+   
+    Note that you must have compiled Privoxy with support for this feature,
+    otherwise this option has no effect.
+   
+-------------------------------------------------------------------------------
+
+7.4.4. enable-edit-actions
+
+Specifies:
+   
+    Whether or not the web-based actions file editor may be used
+   
+Type of value:
+   
+    0 or 1
+   
+Default value:
+   
+    1
+   
+Effect if unset:
+   
+    The web-based actions file editor is disabled.
+   
+Notes:
+   
+    For the time being, access to the editor can not be controlled separately
+    by "ACLs" or HTTP authentication, so that everybody who can access Privoxy
+    (see "ACLs" and listen-address above) can modify its configuration for all
+    users. So this option is not recommended for multi-user environments with
+    untrusted users.
+   
+    Note that you must have compiled Privoxy with support for this feature,
+    otherwise this option has no effect.
+   
+-------------------------------------------------------------------------------
+
+7.4.5. ACLs: permit-access and deny-access
+
+Specifies:
+   
+    Who can access what.
+   
+Type of value:
+   
+    src_addr[/src_masklen] [dst_addr[/dst_masklen]]
+   
+    Where src_addr and dst_addr are IP addresses in dotted decimal notation or
+    valid DNS names, and src_masklen and dst_masklen are subnet masks in CIDR
+    notation, i.e. integer values from 2 to 30 representing the length (in
+    bits) of the network address. The masks and the whole destination part are
+    optional.
+   
+Default value:
+   
+    Unset
+   
+Effect if unset:
+   
+    Don't restrict access further than implied by listen-address
+   
+Notes:
+   
+    Access controls are included at the request of ISPs and systems
+    administrators, and are not usually needed by individual users. For a
+    typical home user, it will normally suffice to ensure that Privoxy only
+    listens on the localhost (127.0.0.1) or internal (home) network address by
+    means of the listen-address option.
+   
+    Please see the warnings in the FAQ that this proxy is not intended to be a
+    substitute for a firewall or to encourage anyone to defer addressing basic
+    security weaknesses.
+   
+    Multiple ACL lines are OK. If any ACLs are specified, then the Privoxy
+    talks only to IP addresses that match at least one permit-access line and
+    don't match any subsequent deny-access line. In other words, the last match
+    wins, with the default being deny-access.
+   
+    If Privoxy is using a forwarder (see forward below) for a particular
+    destination URL, the dst_addr that is examined is the address of the
+    forwarder and NOT the address of the ultimate target. This is necessary
+    because it may be impossible for the local Privoxy to determine the IP
+    address of the ultimate target (that's often what gateways are used for).
+   
+    You should prefer using IP addresses over DNS names, because the address
+    lookups take time. All DNS names must resolve! You can not use domain
+    patterns like "*.org" or partial domain names. If a DNS name resolves to
+    multiple IP addresses, only the first one is used.
+   
+    Denying access to particular sites by ACL may have undesired side effects
+    if the site in question is hosted on a machine which also hosts other
+    sites.
+   
+Examples:
+   
+    Explicitly define the default behavior if no ACL and listen-address are
+    set: "localhost" is OK. The absence of a dst_addr implies that all
+    destination addresses are OK:
+   
+      permit-access  localhost                                         
+   
+    Allow any host on the same class C subnet as www.privoxy.org access to
+    nothing but www.example.com:
+   
+      permit-access  www.privoxy.org/24 www.example.com/32             
+   
+    Allow access from any host on the 26-bit subnet 192.168.45.64 to anywhere,
+    with the exception that 192.168.45.73 may not access
+    www.dirty-stuff.example.com:
+   
+      permit-access  192.168.45.64/26                                  
+      deny-access    192.168.45.73    www.dirty-stuff.example.com      
+   
+-------------------------------------------------------------------------------
+
+7.4.6. buffer-limit
+
+Specifies:
+   
+    Maximum size of the buffer for content filtering.
+   
+Type of value:
+   
+    Size in Kbytes
+   
+Default value:
+   
+    4096
+   
+Effect if unset:
+   
+    Use a 4MB (4096 KB) limit.
+   
+Notes:
+   
+    For content filtering, i.e. the +filter and +deanimate-gif actions, it is
+    necessary that Privoxy buffers the entire document body. This can be
+    potentially dangerous, since a server could just keep sending data
+    indefinitely and wait for your RAM to exhaust -- with nasty consequences.
+    Hence this option.
+   
+    When a document buffer size reaches the buffer-limit, it is flushed to the
+    client unfiltered and no further attempt to filter the rest of the document
+    is made. Remember that there may be multiple threads running, which might
+    require up to buffer-limit Kbytes each, unless you have enabled
+    "single-threaded" above.
+   
+-------------------------------------------------------------------------------
+
+7.5. Forwarding
+
+This feature allows routing of HTTP requests through a chain of multiple
+proxies. It can be used to better protect privacy and confidentiality when
+accessing specific domains by routing requests to those domains through an
+anonymous public proxy (see e.g. http://www.multiproxy.org/anon_list.htm) Or to
+use a caching proxy to speed up browsing. Or chaining to a parent proxy may be
+necessary because the machine that Privoxy runs on has no direct Internet
+access.
+
+Also specified here are SOCKS proxies. Privoxy supports the SOCKS 4 and SOCKS
+4A protocols.
+
+-------------------------------------------------------------------------------
+
+7.5.1. forward
+
+Specifies:
+   
+    To which parent HTTP proxy specific requests should be routed.
+   
+Type of value:
+   
+    target_domain[:port] http_parent[/port]
+   
+    Where target_domain is a domain name pattern (see the chapter on domain
+    matching in the default.action file), http_parent is the address of the
+    parent HTTP proxy as an IP addresses in dotted decimal notation or as a
+    valid DNS name (or "." to denote "no forwarding", and the optional port
+    parameters are TCP ports, i.e. integer values from 1 to 64535
+   
+Default value:
+   
+    Unset
+   
+Effect if unset:
+   
+    Don't use parent HTTP proxies.
+   
+Notes:
+   
+    If http_parent is ".", then requests are not forwarded to another HTTP
+    proxy but are made directly to the web servers.
+   
+    Multiple lines are OK, they are checked in sequence, and the last match
+    wins.
+   
+Examples:
+   
+    Everything goes to an example anonymizing proxy, except SSL on port 443
+    (which it doesn't handle):
+   
+      forward   .*     anon-proxy.example.org:8080                     
+      forward   :443   .                                               
+   
+    Everything goes to our example ISP's caching proxy, except for requests to
+    that ISP's sites:
+   
+      forward   .*.                caching-proxy.example-isp.net:8000  
+      forward   .example-isp.net   .                                   
+   
+-------------------------------------------------------------------------------
+
+7.5.2. forward-socks4 and forward-socks4a
+
+Specifies:
+   
+    Through which SOCKS proxy (and to which parent HTTP proxy) specific
+    requests should be routed.
+   
+Type of value:
+   
+    target_domain[:port] socks_proxy[/port] http_parent[/port]
+   
+    Where target_domain is a domain name pattern (see the chapter on domain
+    matching in the default.action file), http_parent and socks_proxy are IP
+    addresses in dotted decimal notation or valid DNS names (http_parent may be
+    "." to denote "no HTTP forwarding"), and the optional port parameters are
+    TCP ports, i.e. integer values from 1 to 64535
+   
+Default value:
+   
+    Unset
+   
+Effect if unset:
+   
+    Don't use SOCKS proxies.
+   
+Notes:
+   
+    Multiple lines are OK, they are checked in sequence, and the last match
+    wins.
+   
+    The difference between forward-socks4 and forward-socks4a is that in the
+    SOCKS 4A protocol, the DNS resolution of the target hostname happens on the
+    SOCKS server, while in SOCKS 4 it happens locally.
+   
+    If http_parent is ".", then requests are not forwarded to another HTTP
+    proxy but are made (HTTP-wise) directly to the web servers, albeit through
+    a SOCKS proxy.
+   
+Examples:
+   
+    From the company example.com, direct connections are made to all "internal"
+    domains, but everything outbound goes through their ISP's proxy by way of
+    example.com's corporate SOCKS 4A gateway to the Internet.
+   
+      forward-socks4a   .*.            socks-gw.example.com:1080  www-cache.example-isp.net:8080 
+      forward           .example.com   .                                                         
+   
+    A rule that uses a SOCKS 4 gateway for all destinations but no HTTP parent
+    looks like this:
+   
+      forward-socks4   .*.            socks-gw.example.com:1080  .     
+   
+-------------------------------------------------------------------------------
+
+7.5.3. Advanced Forwarding Examples
+
+If you have links to multiple ISPs that provide various special content only to
+their subscribers, you can configure multiple Privoxies which have connections
+to the respective ISPs to act as forwarders to each other, so that your users
+can see the internal content of all ISPs.
+
+Assume that host-a has a PPP connection to isp-a.net. And host-b has a PPP
+connection to isp-b.net. Both run Privoxy. Their forwarding configuration can
+look like this:
+
+host-a:
+
+  forward    .*.         .                                                     
+  forward    .isp-b.net  host-b:8118                                           
+
+host-b:
+
+  forward    .*.         .                                                     
+  forward    .isp-a.net  host-a:8118                                           
+
+Now, your users can set their browser's proxy to use either host-a or host-b
+and be able to browse the internal content of both isp-a and isp-b.
+
+If you intend to chain Privoxy and squid locally, then chain as browser ->
+squid -> privoxy is the recommended way.
+
+Assuming that Privoxy and squid run on the same box, your squid configuration
+could then look like this:
+
+  # Define Privoxy as parent proxy (without ICP)                               
+  cache_peer 127.0.0.1 parent 8118 7 no-query                                  
+                                                                               
+  # Define ACL for protocol FTP                                                
+  acl ftp proto FTP                                                            
+                                                                               
+  # Do not forward FTP requests to Privoxy                                     
+  always_direct allow ftp                                                      
+                                                                               
+  # Forward all the rest to Privoxy                                            
+  never_direct allow all                                                       
+
+You would then need to change your browser's proxy settings to squid's address
+and port. Squid normally uses port 3128. If unsure consult http_port in
+squid.conf.
+
+-------------------------------------------------------------------------------
+
+7.6. Windows GUI Options
+
+Privoxy has a number of options specific to the Windows GUI interface:
+
+If "activity-animation" is set to 1, the Privoxy icon will animate when
+"Privoxy" is active. To turn off, set to 0.
+
+  activity-animation 1
+   
+
+If "log-messages" is set to 1, Privoxy will log messages to the console window:
+
+  log-messages 1
+   
+
+If "log-buffer-size" is set to 1, the size of the log buffer, i.e. the amount
+of memory used for the log messages displayed in the console window, will be
+limited to "log-max-lines" (see below).
+
+Warning: Setting this to 0 will result in the buffer to grow infinitely and eat
+up all your memory!
+
+  log-buffer-size 1
+   
+
+log-max-lines is the maximum number of lines held in the log buffer. See above.
+
+  log-max-lines 200
+   
+
+If "log-highlight-messages" is set to 1, Privoxy will highlight portions of the
+log messages with a bold-faced font:
+
+  log-highlight-messages 1
+   
+
+The font used in the console window:
+
+  log-font-name Comic Sans MS
+   
+
+Font size used in the console window:
+
+  log-font-size 8
+   
+
+"show-on-task-bar" controls whether or not Privoxy will appear as a button on
+the Task bar when minimized:
+
+  show-on-task-bar 0
+   
+
+If "close-button-minimizes" is set to 1, the Windows close button will minimize
+Privoxy instead of closing the program (close with the exit option on the File
+menu).
+
+  close-button-minimizes 1
+   
+
+The "hide-console" option is specific to the MS-Win console version of Privoxy.
+If this option is used, Privoxy will disconnect from and hide the command
+console.
+
+  #hide-console
+   
+
+-------------------------------------------------------------------------------
+
+8. Actions Files
+
+The actions files are used to define what actions Privoxy takes for which URLs,
+and thus determine how ad images, cookies and various other aspects of HTTP
+content and transactions are handled, and on which sites (or even parts
+thereof). There are three such files included with Privoxy (as of version
+2.9.15), with differing purposes:
+
+  * default.action - is the primary action file that sets the initial values
+    for all actions. It is intended to provide a base level of functionality
+    for Privoxy's array of features. So it is a set of broad rules that should
+    work reasonably well for users everywhere. This is the file that the
+    developers are keeping updated, and making available to users.
+   
+  * user.action - is intended to be for local site preferences and exceptions.
+    As an example, if your ISP or your bank has specific requirements, and need
+    special handling, this kind of thing should go here. This file will not be
+    upgraded.
+   
+  * standard.action - is used by the web based editor, to set various
+    pre-defined sets of rules for the default actions section in
+    default.action. These have increasing levels of aggressiveness and have no
+    influence on your browsing unless you select them explicitly in the editor.
+    It is not recommend to edit this file.
+   
+The list of actions files to be used are defined in the main configuration
+file, and are processed in the order they are defined. The content of these can
+all be viewed and edited from http://config.privoxy.org/show-status.
+
+An actions file typically has multiple sections. If you want to use "aliases"
+in an actions file, you have to place the (optional) alias section at the top
+of that file. Then comes the default set of rules which will apply universally
+to all sites and pages (be very careful with using such a universal set in
+user.action or any other actions file after default.action, because it will
+override the result from consulting any previous file). And then below that,
+exceptions to the defined universal policies. You can regard user.action as an
+appendix to default.action, with the advantage that is a separate file, which
+makes preserving your personal settings across Privoxy upgrades easier.
+
+Actions can be used to block anything you want, including ads, banners, or just
+some obnoxious URL that you would rather not see. Cookies can be accepted or
+rejected, or accepted only during the current browser session (i.e. not written
+to disk), content can be modified, JavaScripts tamed, user-tracking fooled, and
+much more. See below for a complete list of actions.
+
+-------------------------------------------------------------------------------
+
+8.1. Finding the Right Mix
+
+Note that some actions, like cookie suppression or script disabling, may render
+some sites unusable that rely on these techniques to work properly. Finding the
+right mix of actions is not always easy and certainly a matter of personal
+taste. In general, it can be said that the more "aggressive" your default
+settings (in the top section of the actions file) are, the more exceptions for
+"trusted" sites you will have to make later. If, for example, you want to kill
+popup windows per default, you'll have to make exceptions from that rule for
+sites that you regularly use and that require popups for actually useful
+content, like maybe your bank, favorite shop, or newspaper.
+
+We have tried to provide you with reasonable rules to start from in the
+distribution actions files. But there is no general rule of thumb on these
+things. There just are too many variables, and sites are constantly changing.
+Sooner or later you will want to change the rules (and read this chapter again
+:).
+
+-------------------------------------------------------------------------------
+
+8.2. How to Edit
+
+The easiest way to edit the actions files is with a browser by using our
+browser-based editor, which can be reached from http://config.privoxy.org/
+show-status. The editor allows both fine-grained control over every single
+feature on a per-URL basis, and easy choosing from wholesale sets of defaults
+like "Cautious", "Medium" or "Advanced".
+
+If you prefer plain text editing to GUIs, you can of course also directly edit
+the the actions files. Look at default.action which is richly commented.
+
+-------------------------------------------------------------------------------
+
+8.3. How Actions are Applied to URLs
+
+Actions files are divided into sections. There are special sections, like the "
+alias" sections which will be discussed later. For now let's concentrate on
+regular sections: They have a heading line (often split up to multiple lines
+for readability) which consist of a list of actions, separated by whitespace
+and enclosed in curly braces. Below that, there is a list of URL patterns, each
+on a separate line.
+
+To determine which actions apply to a request, the URL of the request is
+compared to all patterns in each action file file. Every time it matches, the
+list of applicable actions for the URL is incrementally updated, using the
+heading of the section in which the pattern is located. If multiple matches for
+the same URL set the same action differently, the last match wins. If not, the
+effects are aggregated (e.g. a URL might match both the "+handle-as-image" and 
+"+block" actions).
+
+You can trace this process for any given URL by visiting http://
+config.privoxy.org/show-url-info.
+
+More detail on this is provided in the Appendix, Anatomy of an Action.
+
+-------------------------------------------------------------------------------
+
+8.4. Patterns
+
+Generally, a pattern has the form <domain>/<path>, where both the <domain> and
+<path> are optional. (This is why the pattern / matches all URLs).
+
+www.example.com/
+   
+    is a domain-only pattern and will match any request to www.example.com,
+    regardless of which document on that server is requested.
+   
+www.example.com
+   
+    means exactly the same. For domain-only patterns, the trailing / may be
+    omitted.
+   
+www.example.com/index.html
+   
+    matches only the single document /index.html on www.example.com.
+   
+/index.html
+   
+    matches the document /index.html, regardless of the domain, i.e. on any web
+    server.
+   
+index.html
+   
+    matches nothing, since it would be interpreted as a domain name and there
+    is no top-level domain called .html.
+   
+-------------------------------------------------------------------------------
+
+8.4.1. The Domain Pattern
+
+The matching of the domain part offers some flexible options: if the domain
+starts or ends with a dot, it becomes unanchored at that end. For example:
+
+.example.com
+   
+    matches any domain that ENDS in .example.com
+   
+www.
+   
+    matches any domain that STARTS with www.
+   
+.example.
+   
+    matches any domain that CONTAINS .example. (Correctly speaking: It matches
+    any FQDN that contains example as a domain.)
+   
+Additionally, there are wild-cards that you can use in the domain names
+themselves. They work pretty similar to shell wild-cards: "*" stands for zero
+or more arbitrary characters, "?" stands for any single character, you can
+define character classes in square brackets and all of that can be freely
+mixed:
+
+ad*.example.com
+   
+    matches "adserver.example.com", "ads.example.com", etc but not
+    "sfads.example.com"
+   
+*ad*.example.com
+   
+    matches all of the above, and then some.
+   
+.?pix.com
+   
+    matches www.ipix.com, pictures.epix.com, a.b.c.d.e.upix.com etc.
+   
+www[1-9a-ez].example.c*
+   
+    matches www1.example.com, www4.example.cc, wwwd.example.cy,
+    wwwz.example.com etc., but not wwww.example.com.
+   
+-------------------------------------------------------------------------------
+
+8.4.2. The Path Pattern
+
+Privoxy uses Perl compatible regular expressions (through the PCRE library) for
+matching the path.
+
+There is an Appendix with a brief quick-start into regular expressions, and
+full (very technical) documentation on PCRE regex syntax is available on-line
+at http://www.pcre.org/man.txt. You might also find the Perl man page on
+regular expressions (man perlre) useful, which is available on-line at http://
+www.perldoc.com/perl5.6/pod/perlre.html.
+
+Note that the path pattern is automatically left-anchored at the "/", i.e. it
+matches as if it would start with a "^" (regular expression speak for the
+beginning of a line).
+
+Please also note that matching in the path is case INSENSITIVE by default, but
+you can switch to case sensitive at any point in the pattern by using the "(?
+-i)" switch: www.example.com/(?-i)PaTtErN.* will match only documents whose
+path starts with PaTtErN in exactly this capitalization.
+
+-------------------------------------------------------------------------------
+
+8.5. Actions
+
+All actions are disabled by default, until they are explicitly enabled
+somewhere in an actions file. Actions are turned on if preceded with a "+", and
+turned off if preceded with a "-". So a +action means "do that action", e.g.
++block means "please block URLs that match the following patterns", and -block
+means "don't block URLs that match the following patterns, even if +block
+previously applied." 
+
+Again, actions are invoked by placing them on a line, enclosed in curly braces
+and separated by whitespace, like in {+some-action -some-other-action
+{some-parameter}}, followed by a list of URL patterns, one per line, to which
+they apply. Together, the actions line and the following pattern lines make up
+a section of the actions file.
+
+There are three classes of actions:
+
+  * Boolean, i.e the action can only be "enabled" or "disabled". Syntax:
+   
+      +name        # enable action name                                
+      -name        # disable action name                               
+   
+    Example: +block
+   
+  * Parameterized, where some value is required in order to enable this type of
+    action. Syntax:
+   
+      +name{param}  # enable action and set parameter to param,             
+                   # overwriting parameter from previous match if necessary 
+      -name         # disable action. The parameter can be omitted          
+   
+    Note that if the URL matches multiple positive forms of a parameterized
+    action, the last match wins, i.e. the params from earlier matches are
+    simply ignored.
+   
+    Example: +hide-user-agent{ Mozilla 1.0 }
+   
+  * Multi-value. These look exactly like parameterized actions, but they behave
+    differently: If the action applies multiple times to the same URL, but with
+    different parameters, all the parameters from all matches are remembered.
+    This is used for actions that can be executed for the same request
+    repeatedly, like adding multiple headers, or filtering through multiple
+    filters. Syntax:
+   
+      +name{param}   # enable action and add param to the list of parameters                 
+      -name{param}   # remove the parameter param from the list of parameters                
+                    # If it was the last one left, disable the action.                       
+      -name          # disable this action completely and remove all parameters from the list
+   
+    Examples: +add-header{X-Fun-Header: Some text} and +filter{html-annoyances}
+   
+If nothing is specified in any actions file, no "actions" are taken. So in this
+case Privoxy would just be a normal, non-blocking, non-anonymizing proxy. You
+must specifically enable the privacy and blocking features you need (although
+the provided default actions files will give a good starting point).
+
+Later defined actions always over-ride earlier ones. So exceptions to any rules
+you make, should come in the latter part of the file (or in a file that is
+processed later when using multiple actions files). For multi-valued actions,
+the actions are applied in the order they are specified. Actions files are
+processed in the order they are defined in config (the default installation has
+three actions files). It also quite possible for any given URL pattern to match
+more than one pattern and thus more than one set of actions!
+
+The list of valid Privoxy actions are:
+
+-------------------------------------------------------------------------------
+
+8.5.1. add-header
+
+Typical use:
+   
+    Confuse log analysis, custom applications
+   
+Effect:
+   
+    Sends a user defined HTTP header to the web server.
+   
+Type:
+   
+    Multi-value.
+   
+Parameter:
+   
+    Any string value is possible. Validity of the defined HTTP headers is not
+    checked. It is recommended that you use the "X-" prefix for custom headers.
+   
+Notes:
+   
+    This action may be specified multiple times, in order to define multiple
+    headers. This is rarely needed for the typical user. If you don't know what
+    "HTTP headers" are, you definitely don't need to worry about this one.
+   
+Example usage:
+   
+    +add-header{X-User-Tracking: sucks}                                
+   
+-------------------------------------------------------------------------------
+
+8.5.2. block
+
+Typical use:
+   
+    Block ads or other obnoxious content
+   
+Effect:
+   
+    Requests for URLs to which this action applies are blocked, i.e. the
+    requests are not forwarded to the remote server, but answered locally with
+    a substitute page or image, as determined by the handle-as-image and 
+    set-image-blocker actions.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    Privoxy sends a special "BLOCKED" page for requests to blocked pages. This
+    page contains links to find out why the request was blocked, and a
+    click-through to the blocked content (the latter only if compiled with the
+    force feature enabled). The "BLOCKED" page adapts to the available screen
+    space -- it displays full-blown if space allows, or miniaturized and
+    text-only if loaded into a small frame or window. If you are using Privoxy
+    right now, you can take a look at the "BLOCKED" page.
+   
+    A very important exception occurs if both block and handle-as-image, apply
+    to the same request: it will then be replaced by an image. If 
+    set-image-blocker (see below) also applies, the type of image will be
+    determined by its parameter, if not, the standard checkerboard pattern is
+    sent.
+   
+    It is important to understand this process, in order to understand how
+    Privoxy deals with ads and other unwanted content.
+   
+    The filter action can perform a very similar task, by "blocking" banner
+    images and other content through rewriting the relevant URLs in the
+    document's HTML source, so they don't get requested in the first place.
+    Note that this is a totally different technique, and it's easy to confuse
+    the two.
+   
+Example usage (section):
+   
+    {+block}      # Block and replace with "blocked" page              
+    .nasty-stuff.example.com                                           
+                                                                       
+    {+block +handle-as-image} # Block and replace with image           
+    .ad.doubleclick.net                                                
+    .ads.r.us                                                          
+   
+-------------------------------------------------------------------------------
+
+8.5.3. crunch-incoming-cookies
+
+Typical use:
+   
+    Prevent the web server from setting any cookies on your system
+   
+Effect:
+   
+    Deletes any "Set-Cookie:" HTTP headers from server replies.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    This action is only concerned with incoming cookies. For outgoing cookies,
+    use crunch-outgoing-cookies. Use both to disable cookies completely.
+   
+    It makes no sense at all to use this action in conjunction with the 
+    session-cookies-only action, since it would prevent the session cookies
+    from being set.
+   
+Example usage:
+   
+    +crunch-incoming-cookies                                           
+   
+-------------------------------------------------------------------------------
+
+8.5.4. crunch-outgoing-cookies
+
+Typical use:
+   
+    Prevent the web server from reading any cookies from your system
+   
+Effect:
+   
+    Deletes any "Cookie:" HTTP headers from client requests.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    This action is only concerned with outgoing cookies. For incoming cookies,
+    use crunch-incoming-cookies. Use both to disable cookies completely.
+   
+    It makes no sense at all to use this action in conjunction with the 
+    session-cookies-only action, since it would prevent the session cookies
+    from being read.
+   
+Example usage:
+   
+    +crunch-outgoing-cookies                                           
+   
+-------------------------------------------------------------------------------
+
+8.5.5. deanimate-gifs
+
+Typical use:
+   
+    Stop those annoying, distracting animated GIF images.
+   
+Effect:
+   
+    De-animate GIF animations, i.e. reduce them to their first or last image.
+   
+Type:
+   
+    Parameterized.
+   
+Parameter:
+   
+    "last" or "first"
+   
+Notes:
+   
+    This will also shrink the images considerably (in bytes, not pixels!). If
+    the option "first" is given, the first frame of the animation is used as
+    the replacement. If "last" is given, the last frame of the animation is
+    used instead, which probably makes more sense for most banner animations,
+    but also has the risk of not showing the entire last frame (if it is only a
+    delta to an earlier frame).
+   
+    You can safely use this action with patterns that will also match non-GIF
+    objects, because no attempt will be made at anything that doesn't look like
+    a GIF.
+   
+Example usage:
+   
+    +deanimate-gifs{last}                                              
+   
+-------------------------------------------------------------------------------
+
+8.5.6. downgrade-http-version
+
+Typical use:
+   
+    Work around (very rare) problems with HTTP/1.1
+   
+Effect:
+   
+    Downgrades HTTP/1.1 client requests and server replies to HTTP/1.0.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    This is a left-over from the time when Privoxy didn't support important
+    HTTP/1.1 features well. It is left here for the unlikely case that you
+    experience HTTP/1.1 related problems with some server out there. Not all
+    (optional) HTTP/1.1 features are supported yet, so there is a chance you
+    might need this action.
+   
+Example usage (section):
+   
+    {+downgrade-http-version}                                          
+    problem-host.example.com                                           
+   
+-------------------------------------------------------------------------------
+
+8.5.7. fast-redirects
+
+Typical use:
+   
+    Fool some click-tracking scripts and speed up indirect links
+   
+Effect:
+   
+    Cut off all but the last valid URL from requests.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    Many sites, like yahoo.com, don't just link to other sites. Instead, they
+    will link to some script on their own servers, giving the destination as a
+    parameter, which will then redirect you to the final target. URLs resulting
+    from this scheme typically look like: http://some.place/click-tracker.cgi?
+    target=http://some.where.else.
+   
+    Sometimes, there are even multiple consecutive redirects encoded in the
+    URL. These redirections via scripts make your web browsing more traceable,
+    since the server from which you follow such a link can see where you go to.
+    Apart from that, valuable bandwidth and time is wasted, while your browser
+    ask the server for one redirect after the other. Plus, it feeds the
+    advertisers.
+   
+    This feature is currently not very smart and is scheduled for improvement.
+    It is likely to break some sites. You should expect to need possibly many
+    exceptions to this action, if it is enabled by default in default.action.
+    Some sites just don't work without it.
+   
+Example usage:
+   
+    {+fast-redirects}                                                  
+   
+-------------------------------------------------------------------------------
+
+8.5.8. filter
+
+Typical use:
+   
+    Get rid of HTML and JavaScript annoyances, banner advertisements (by size),
+    do fun text replacements, etc.
+   
+Effect:
+   
+    Text documents, including HTML and JavaScript, to which this action
+    applies, are filtered on-the-fly through the specified regular expression
+    based substitutions.
+   
+Type:
+   
+    Parameterized.
+   
+Parameter:
+   
+    The name of a filter, as defined in the filter file (typically
+    default.filter, set by the filterfile option in the config file)
+   
+Notes:
+   
+    For your convenience, there are a bunch of pre-defined filters available in
+    the distribution filter file that you can use. See the example below for a
+    list.
+   
+    This is potentially a very powerful feature! But "rolling your own" filters
+    requires a knowledge of regular expressions and HTML.
+   
+    Filtering requires buffering the page content, which may appear to slow
+    down page rendering since nothing is displayed until all content has passed
+    the filters. (It does not really take longer, but seems that way since the
+    page is not incrementally displayed.) This effect will be more noticeable
+    on slower connections.
+   
+    At this time, Privoxy cannot (yet!) uncompress compressed documents. If you
+    want filtering to work on all documents, even those that would normally be
+    sent compressed, use the prevent-compression action in conjunction with
+    filter.
+   
+    Filtering can achieve some of the effects as the block action, i.e. it can
+    be used to block ads and banners.
+   
+    Feedback with suggestions for new or improved filters is particularly
+    welcome!
+   
+Example usage (with filters from the distribution default.filter file):
+   
+    +filter{html-annoyances}     # Get rid of particularly annoying HTML abuse.
+   
+    +filter{js-annoyances}       # Get rid of particularly annoying JavaScript abuse
+   
+    +filter{banners-by-size}     # Kill banners by size (very efficient!)
+   
+    +filter{content-cookies}     # Kill cookies that come sneaking in the HTML or JS content
+   
+    +filter{popups}              # Kill all popups in JS and HTML      
+   
+    +filter{webbugs}             # Squish WebBugs (1x1 invisible GIFs used for user tracking)
+   
+    +filter{fun}                 # Text replacements for subversive browsing fun!
+   
+    +filter{frameset-borders}    # Give frames a border and make them resizeable
+   
+    +filter{refresh-tags}        # Kill automatic refresh tags (for dial-on-demand setups)
+   
+    +filter{nimda}               # Remove Nimda (virus) code.          
+   
+    +filter{shockwave-flash}     # Kill embedded Shockwave Flash objects
+   
+    +filter{crude-parental}      # Kill all web pages that contain the words "sex" or "warez"
+   
+-------------------------------------------------------------------------------
+
+8.5.9. handle-as-image
+
+Typical use:
+   
+    Mark URLs as belonging to images (so they'll be replaced by images if they
+    get blocked)
+   
+Effect:
+   
+    This action alone doesn't do anything noticeable. It just marks URLs as
+    images. If the block action also applies, the presence or absence of this
+    mark decides whether an HTML "blocked" page, or a replacement image (as
+    determined by the set-image-blocker action) will be sent to the client as a
+    substitute for the blocked content.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    The below generic example section is actually part of default.action. It
+    marks all URLs with well-known image file name extensions as images and
+    should be left intact.
+   
+    Users will probably only want to use the handle-as-image action in
+    conjunction with block, to block sources of banners, whose URLs don't
+    reflect the file type, like in the second example section.
+   
+    Note that you cannot treat HTML pages as images in most cases. For
+    instance, (inline) ad frames require an HTML page to be sent, or they won't
+    display properly. Forcing handle-as-image in this situation will not
+    replace the ad frame with an image, but lead to error messages.
+   
+Example usage (sections):
+   
+    # Generic image extensions:                                        
+    #                                                                  
+    {+handle-as-image}                                                 
+    /.*\.(gif|jpg|jpeg|png|bmp|ico)$                                   
+                                                                       
+    # These don't look like images, but they're banners and should be  
+    # blocked as images:                                               
+    #                                                                  
+    {+block +handle-as-image}                                          
+    some.nasty-banner-server.com/junk.cgi?output=trash                 
+                                                                       
+    # Banner source! Who cares if they also have non-image content?    
+    ad.doubleclick.net                                                 
+   
+-------------------------------------------------------------------------------
+
+8.5.10. hide-forwarded-for-headers
+
+Typical use:
+   
+    Improve privacy by hiding the true source of the request
+   
+Effect:
+   
+    Deletes any existing "X-Forwarded-for:" HTTP header from client requests,
+    and prevents adding a new one.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    It is fairly safe to leave this on.
+   
+    This action is scheduled for improvement: It should be able to generate
+    forged "X-Forwarded-for:" headers using random IP addresses from a
+    specified network, to make successive requests from the same client look
+    like requests from a pool of different users sharing the same proxy.
+   
+Example usage:
+   
+    +hide-forwarded-for-headers                                        
+   
+-------------------------------------------------------------------------------
+
+8.5.11. hide-from-header
+
+Typical use:
+   
+    Keep your (old and ill) browser from telling web servers your email address
+   
+Effect:
+   
+    Deletes any existing "From:" HTTP header, or replaces it with the specified
+    string.
+   
+Type:
+   
+    Parameterized.
+   
+Parameter:
+   
+    Keyword: "block", or any user defined value.
+   
+Notes:
+   
+    The keyword "block" will completely remove the header (not to be confused
+    with the block action).
+   
+    Alternately, you can specify any value you prefer to be sent to the web
+    server. If you do, it is a matter of fairness not to use any address that
+    is actually used by a real person.
+   
+    This action is rarely needed, as modern web browsers don't send "From:"
+    headers anymore.
+   
+Example usage:
+   
+    +hide-from-header{block}                                           
+   
+    or
+   
+    +hide-from-header{spam-me-senseless@sittingduck.example.com}       
+   
+-------------------------------------------------------------------------------
+
+8.5.12. hide-referrer
+
+Typical use:
+   
+    Conceal which link you followed to get to a particular site
+   
+Effect:
+   
+    Deletes the "Referer:" (sic) HTTP header from the client request, or
+    replaces it with a forged one.
+   
+Type:
+   
+    Parameterized.
+   
+Parameter:
+   
+      + "block" to delete the header completely.
+       
+      + "forge" to pretend to be coming from the homepage of the server we are
+        talking to.
+       
+      + Any other string to set a user defined referrer.
+       
+Notes:
+   
+    "forge" is the preferred option here, since some servers will not send
+    images back otherwise, in an attempt to prevent their valuable content from
+    being embedded elsewhere (and hence, without being surrounded by their
+    banners).
+   
+    hide-referer is an alternate spelling of hide-referrer and the two can be
+    can be freely substituted with each other. ("referrer" is the correct
+    English spelling, however the HTTP specification has a bug - it requires it
+    to be spelled as "referer".)
+   
+Example usage:
+   
+    +hide-referrer{forge}                                              
+   
+    or
+   
+    +hide-referrer{http://www.yahoo.com/}                              
+   
+-------------------------------------------------------------------------------
+
+8.5.13. hide-user-agent
+
+Typical use:
+   
+    Conceal your type of browser and client operating system
+   
+Effect:
+   
+    Replaces the value of the "User-Agent:" HTTP header in client requests with
+    the specified value.
+   
+Type:
+   
+    Parameterized.
+   
+Parameter:
+   
+    Any user-defined string.
+   
+Notes:
+   
+    +-----------------------------------------------------------------+
+    |                             Warning                             |
+    |-----------------------------------------------------------------|
+    |This breaks many web sites that depend on looking at this header |
+    |in order to customize their content for different browsers       |
+    |(which, by the way, is NOT a smart way to do that!).             |
+    +-----------------------------------------------------------------+
+   
+    Using this action in multi-user setups or wherever different types of
+    browsers will access the same Privoxy is not recommended. In single-user,
+    single-browser setups, you might use it to delete your OS version
+    information from the headers, because it is an invitation to exploit known
+    bugs for your OS. It is also occasionally useful to forge this in order to
+    access sites that won't let you in otherwise (though there may be a good
+    reason in some cases). Example of this: some MSN sites will not let Mozilla
+    enter, yet forging to a Netscape 6.1 user-agent works just fine. (Must be
+    just a silly MS goof, I'm sure :-).
+   
+    This action is scheduled for improvement.
+   
+Example usage:
+   
+    +hide-user-agent{Netscape 6.1 (X11; I; Linux 2.4.18 i686)}         
+   
+-------------------------------------------------------------------------------
+
+8.5.14. kill-popups
+
+Typical use:
+   
+    Eliminate those annoying pop-up windows
+   
+Effect:
+   
+    While loading the document, replace JavaScript code that opens pop-up
+    windows with (syntactically neutral) dummy code on the fly.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    This action is easily confused with the built-in, hardwired filter action,
+    but there are important differences: For kill-popups, the document need not
+    be buffered, so it can be incrementally rendered while downloading. But
+    kill-popups doesn't catch as many pop-ups as filter{popups} does.
+   
+    Think of it as a fast and efficient replacement for a filter that you can
+    use if you don't want any filtering at all. Note that it doesn't make sense
+    to combine it with any filter action, since as soon as one filter applies,
+    the whole document needs to be buffered anyway, which destroys the
+    advantage of the kill-popups action over its filter equivalent.
+   
+    Killing all pop-ups is a dangerous business. Many shops and banks rely on
+    pop-ups to display forms, shopping carts etc, and killing only the unwanted
+    pop-ups would require artificial intelligence in Privoxy. If the only kind
+    of pop-ups that you want to kill are exit consoles (those really nasty
+    windows that appear when you close an other one), you might want to use 
+    filter{js-annoyances} instead.
+   
+Example usage:
+   
+    +kill-popups                                                       
+   
+-------------------------------------------------------------------------------
+
+8.5.15. limit-connect
+
+Typical use:
+   
+    Prevent abuse of Privoxy as a TCP proxy relay
+   
+Effect:
+   
+    Specifies to which ports HTTP CONNECT requests are allowable.
+   
+Type:
+   
+    Parameterized.
+   
+Parameter:
+   
+    A comma-separated list of ports or port ranges (the latter using dashes,
+    with the minimum defaulting to 0 and the maximum to 65K).
+   
+Notes:
+   
+    By default, i.e. if no limit-connect action applies, Privoxy only allows
+    HTTP CONNECT requests to port 443 (the standard, secure HTTPS port). Use
+    limit-connect if more fine-grained control is desired for some or all
+    destinations.
+   
+    The CONNECT methods exists in HTTP to allow access to secure websites
+    ("https://" URLs) through proxies. It works very simply: the proxy connects
+    to the server on the specified port, and then short-circuits its
+    connections to the client and to the remote server. This can be a big
+    security hole, since CONNECT-enabled proxies can be abused as TCP relays
+    very easily.
+   
+    If you don't know what any of this means, there probably is no reason to
+    change this one, since the default is already very restrictive.
+   
+Example usages:
+   
+    +limit-connect{443}                   # This is the default and need not be specified.        
+    +limit-connect{80,443}                # Ports 80 and 443 are OK.                              
+    +limit-connect{-3, 7, 20-100, 500-}   # Ports less than 3, 7, 20 to 100 and above 500 are OK. 
+    +limit-connect{-}                     # All ports are OK (gaping security hole!)              
+   
+-------------------------------------------------------------------------------
+
+8.5.16. prevent-compression
+
+Typical use:
+   
+    Ensure that servers send the content uncompressed, so it can be passed
+    through filters
+   
+Effect:
+   
+    Adds a header to the request that asks for uncompressed transfer.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    More and more websites send their content compressed by default, which is
+    generally a good idea and saves bandwidth. But for the filter, 
+    deanimate-gifs and kill-popups actions to work, Privoxy needs access to the
+    uncompressed data. Unfortunately, Privoxy can't yet(!) uncompress, filter,
+    and re-compress the content on the fly. So if you want to ensure that all
+    websites, including those that normally compress, can be filtered, you need
+    to use this action.
+   
+    This will slow down transfers from those websites, though. If you use any
+    of the above-mentioned actions, you will typically want to use
+    prevent-compression in conjunction with them.
+   
+    Note that some (rare) ill-configured sites don't handle requests for
+    uncompressed documents correctly (they send an empty document body). If you
+    use prevent-compression per default, you'll have to add exceptions for
+    those sites. See the example for how to do that.
+   
+Example usage (sections):
+   
+    # Set default:                                                     
+    #                                                                  
+    {+prevent-compression}                                             
+    / # Match all sites                                                
+                                                                       
+    # Make exceptions for ill sites:                                   
+    #                                                                  
+    {-prevent-compression}                                             
+    www.debianhelp.org                                                 
+    www.pclinuxonline.com                                              
+   
+-------------------------------------------------------------------------------
+
+8.5.17. send-vanilla-wafer
+
+Typical use:
+   
+    Feed log analysis scripts with useless data.
+   
+Effect:
+   
+    Sends a cookie with each request stating that you do not accept any
+    copyright on cookies sent to you, and asking the site operator not to track
+    you.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    The vanilla wafer is a (relatively) unique header and could conceivably be
+    used to track you.
+   
+    This action is rarely used and not enabled in the default configuration.
+   
+Example usage:
+   
+    +send-vanilla-wafer                                                
+   
+-------------------------------------------------------------------------------
+
+8.5.18. send-wafer
+
+Typical use:
+   
+    Send custom cookies or feed log analysis scripts with even more useless
+    data.
+   
+Effect:
+   
+    Sends a custom, user-defined cookie with each request.
+   
+Type:
+   
+    Multi-value.
+   
+Parameter:
+   
+    A string of the form "name=value".
+   
+Notes:
+   
+    Being multi-valued, multiple instances of this action can apply to the same
+    request, resulting in multiple cookies being sent.
+   
+    This action is rarely used and not enabled in the default configuration.
+   
+Example usage (section):
+   
+    {+send-wafer{UsingPrivoxy=true}}                                   
+    my-internal-testing-server.void                                    
+   
+-------------------------------------------------------------------------------
+
+8.5.19. session-cookies-only
+
+Typical use:
+   
+    Allow only temporary "session" cookies (for the current browser session
+    only).
+   
+Effect:
+   
+    Deletes the "expires" field from "Set-Cookie:" server headers. Most
+    browsers will not store such cookies permanently and forget them in between
+    sessions.
+   
+Type:
+   
+    Boolean.
+   
+Parameter:
+   
+    N/A
+   
+Notes:
+   
+    This is less strict than crunch-incoming-cookies / crunch-outgoing-cookies
+    and allows you to browse websites that insist or rely on setting cookies,
+    without compromising your privacy too badly.
+   
+    Most browsers will not permanently store cookies that have been processed
+    by session-cookies-only and will forget about them between sessions. This
+    makes profiling cookies useless, but won't break sites which require
+    cookies so that you can log in for transactions. This is generally turned
+    on for all sites, and is the recommended setting.
+   
+    It makes no sense at all to use session-cookies-only together with 
+    crunch-incoming-cookies or crunch-outgoing-cookies. If you do, cookies will
+    be plainly killed.
+   
+    Note that it is up to the browser how it handles such cookies without an
+    "expires" field. If you use an exotic browser, you might want to try it out
+    to be sure.
+   
+Example usage:
+   
+    +session-cookies-only                                              
+   
+-------------------------------------------------------------------------------
+
+8.5.20. set-image-blocker
+
+Typical use:
+   
+    Choose the replacement for blocked images
+   
+Effect:
+   
+    This action alone doesn't do anything noticeable. If both block and 
+    handle-as-image also apply, i.e. if the request is to be blocked as an
+    image, then the parameter of this action decides what will be sent as a
+    replacement.
+   
+Type:
+   
+    Parameterized.
+   
+Parameter:
+   
+      + "pattern" to send a built-in checkerboard pattern image. The image is
+        visually decent, scales very well, and makes it obvious where banners
+        were busted.
+       
+      + "blank" to send a built-in transparent image. This makes banners
+        disappear completely, but makes it hard to detect where Privoxy has
+        blocked images on a given page and complicates troubleshooting if
+        Privoxy has blocked innocent images, like navigation icons.
+       
+      + "target-url" to send a redirect to target-url. You can redirect to any
+        image anywhere, even in your local filesystem (via "file:///" URL).
+       
+        A good application of redirects is to use special Privoxy-built-in
+        URLs, which send the built-in images, as target-url. This has the same
+        visual effect as specifying "blank" or "pattern" in the first place,
+        but enables your browser to cache the replacement image, instead of
+        requesting it over and over again.
+       
+Notes:
+   
+    The URLs for the built-in images are "http://config.privoxy.org/
+    send-banner?type=type", where type is either "blank" or "pattern".
+   
+    There is a third (advanced) type, called "auto". It is NOT to be used in
+    set-image-blocker, but meant for use from filters. Auto will select the
+    type of image that would have applied to the referring page, had it been an
+    image.
+   
+Example usage:
+   
+    Built-in pattern:
+   
+    +set-image-blocker{pattern}                                        
+   
+    Redirect to the BSD devil:
+   
+    +set-image-blocker{http://www.freebsd.org/gifs/dae_up3.gif}        
+   
+    Redirect to the built-in pattern for better caching:
+   
+    +set-image-blocker{http://config.privoxy.org/send-banner?type=pattern}
+   
+-------------------------------------------------------------------------------
+
+8.5.21. Summary
+
+Note that many of these actions have the potential to cause a page to
+misbehave, possibly even not to display at all. There are many ways a site
+designer may choose to design his site, and what HTTP header content, and other
+criteria, he may depend on. There is no way to have hard and fast rules for all
+sites. See the Appendix for a brief example on troubleshooting actions.
+
+-------------------------------------------------------------------------------
+
+8.6. Aliases
+
+Custom "actions", known to Privoxy as "aliases", can be defined by combining
+other actions. These can in turn be invoked just like the built-in actions.
+Currently, an alias name can contain any character except space, tab, "=", "{"
+and "}", but we strongly recommend that you only use "a" to "z", "0" to "9",
+"+", and "-". Alias names are not case sensitive, and are not required to start
+with a "+" or "-" sign, since they are merely textually expanded.
+
+Aliases can be used throughout the actions file, but they must be defined in a
+special section at the top of the file! And there can only be one such section
+per actions file. Each actions file may have its own alias section, and the
+aliases defined in it are only visible within that file.
+
+There are two main reasons to use aliases: One is to save typing for frequently
+used combinations of actions, the other one is a gain in flexibility: If you
+decide once how you want to handle shops by defining an alias called "shop",
+you can later change your policy on shops in one place, and your changes will
+take effect everywhere in the actions file where the "shop" alias is used.
+Calling aliases by their purpose also makes your actions files more readable.
+
+Currently, there is one big drawback to using aliases, though: Privoxy's
+built-in web-based action file editor honors aliases when reading the actions
+files, but it expands them before writing. So the effects of your aliases are
+of course preserved, but the aliases themselves are lost when you edit sections
+that use aliases with it. This is likely to change in future versions of
+Privoxy.
+
+Now let's define some aliases...
+
+ # Useful custom aliases we can use later.                                                   
+ #                                                                                           
+ # Note the (required!) section header line and that this section                            
+ # must be at the top of the actions file!                                                   
+ #                                                                                           
+ {{alias}}                                                                                   
+                                                                                             
+ # These aliases just save typing later:                                                     
+ # (Note that some already use other aliases!)                                               
+ #                                                                                           
+ +crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies                     
+ -crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies                     
+ block-as-image      = +block +handle-as-image                                               
+ mercy-for-cookies   = -crunch-all-cookies -session-cookies-only                             
+                                                                                             
+ # These aliases define combinations of actions                                              
+ # that are useful for certain types of sites:                                               
+ #                                                                                           
+ fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups 
+ shop        = -crunch-all-cookies -filter{popups} -kill-popups                              
+                                                                                             
+ # Short names for other aliases, for really lazy people ;-)                                 
+ #                                                                                           
+ c0 = +crunch-all-cookies                                                                    
+ c1 = -crunch-all-cookies                                                                    
+
+...and put them to use. These sections would appear in the lower part of an
+actions file and define exceptions to the default actions (as specified further
+up for the "/" pattern):
+
+ # These sites are either very complex or very keen on                         
+ # user data and require minimal interference to work:                         
+ #                                                                             
+ {fragile}                                                                     
+ .office.microsoft.com                                                         
+ .windowsupdate.microsoft.com                                                  
+ .nytimes.com                                                                  
+                                                                               
+ # Shopping sites:                                                             
+ # Allow cookies (for setting and retrieving your customer data)               
+ #                                                                             
+ {shop}                                                                        
+ .quietpc.com                                                                  
+ .worldpay.com   # for quietpc.com                                             
+ .scan.co.uk                                                                   
+                                                                               
+ # These shops require pop-ups:                                                
+ #                                                                             
+ {shop -kill-popups -filter{popups}}                                           
+  .dabs.com                                                                    
+  .overclockers.co.uk                                                          
+
+Aliases like "shop" and "fragile" are often used for "problem" sites that
+require some actions to be disabled in order to function properly.
+
+-------------------------------------------------------------------------------
+
+8.7. Actions Files Tutorial
+
+The above chapters have shown which actions files there are and how they are
+organized, how actions are specified and applied to URLs, how patterns work,
+and how to define and use aliases. Now, let's look at an example default.action
+and user.action file and see how all these pieces come together:
+
+-------------------------------------------------------------------------------
+
+8.7.1. default.action
+
+Every config file should start with a short comment stating its purpose:
+
+# Sample default.action file <developers@privoxy.org>                          
+
+Then, since this is the default.action file, the first section is a special
+section for internal use that you needn't change or worry about:
+
+##########################################################################     
+# Settings -- Don't change! For internal Privoxy use ONLY.                     
+##########################################################################     
+                                                                               
+{{settings}}                                                                   
+for-privoxy-version=3.0                                                        
+
+After that comes the (optional) alias section. We'll use the example section
+from the above chapter on aliases, that also explains why and how aliases are
+used:
+
+##########################################################################                  
+# Aliases                                                                                   
+##########################################################################                  
+{{alias}}                                                                                   
+                                                                                            
+# These aliases just save typing later:                                                     
+# (Note that some already use other aliases!)                                               
+#                                                                                           
++crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies                     
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies                     
+block-as-image      = +block +handle-as-image                                               
+mercy-for-cookies   = -crunch-all-cookies -session-cookies-only                             
+                                                                                            
+# These aliases define combinations of actions                                              
+# that are useful for certain types of sites:                                               
+#                                                                                           
+fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups 
+shop        = mercy-for-cookies -filter{popups} -kill-popups                                
+
+Now come the regular sections, i.e. sets of actions, accompanied by URL
+patterns to which they apply. Remember all actions are disabled when matching
+starts, so we have to explicitly enable the ones we want.
+
+The first regular section is probably the most important. It has only one
+pattern, "/", but this pattern matches all URLs.. Therefore, the set of actions
+used in this "default" section will be applied to all requests as a start. It
+can be partly or wholly overridden by later matches further down this file, or
+in user.action, but it will still be largely responsible for your overall
+browsing experience.
+
+Again, at the start of matching, all actions are disabled, so there is no real
+need to disable any actions here, but we will do that nonetheless, to have a
+complete listing for your reference. (Remember: A "+" preceding the action name
+enables the action, a "-" disables!). Also note how this long line has been
+made more readable by splitting it into multiple lines with line continuation.
+
+##########################################################################     
+# "Defaults" section:                                                          
+##########################################################################     
+ { \                                                                           
+ -add-header \                                                                 
+ -block \                                                                      
+ -crunch-incoming-cookies \                                                    
+ -crunch-outgoing-cookies \                                                    
+ +deanimate-gifs \                                                             
+ -downgrade-http-version \                                                     
+ +fast-redirects \                                                             
+ +filter{html-annoyances} \                                                    
+ +filter{js-annoyances} \                                                      
+ -filter{content-cookies} \                                                    
+ +filter{popups} \                                                             
+ +filter{webbugs} \                                                            
+ -filter{refresh-tags} \                                                       
+ -filter{fun} \                                                                
+ +filter{nimda} \                                                              
+ +filter{banners-by-size} \                                                    
+ -filter{shockwave-flash} \                                                    
+ -filter{crude-parental} \                                                     
+ -handle-as-image \                                                            
+ +hide-forwarded-for-headers \                                                 
+ +hide-from-header{block} \                                                    
+ +hide-referrer{forge} \                                                       
+ -hide-user-agent \                                                            
+ -kill-popups \                                                                
+ -limit-connect \                                                              
+ +prevent-compression \                                                        
+ -send-vanilla-wafer \                                                         
+ -send-wafer \                                                                 
+ +session-cookies-only \                                                       
+ +set-image-blocker{pattern} \                                                 
+ }                                                                             
+ / # forward slash will match *all* potential URL patterns.                    
+
+The default behavior is now set. Note that some actions, like not hiding the
+user agent, are part of a "general policy" that applies universally and won't
+get any exceptions defined later. Other choices, like not blocking (which is
+understandably the default!) need exceptions, i.e. we need to specify
+explicitly what we want to block in later sections. We will also want to make
+exceptions from our general pop-up-killing, and use our defined aliases for
+that.
+
+The first of our specialized sections is concerned with "fragile" sites, i.e.
+sites that require minimum interference, because they are either very complex
+or very keen on tracking you (and have mechanisms in place that make them
+unusable for people who avoid being tracked). We will simply use our
+pre-defined fragile alias instead of stating the list of actions explicitly:
+
+##########################################################################     
+# Exceptions for sites that'll break under the default action set:             
+##########################################################################     
+                                                                               
+# "Fragile" Use a minimum set of actions for these sites (see alias above):    
+#                                                                              
+{ fragile }                                                                    
+.office.microsoft.com           # surprise, surprise!                          
+.windowsupdate.microsoft.com                                                   
+
+Shopping sites are not as fragile, but they typically require cookies to log
+in, and pop-up windows for shopping carts or item details. Again, we'll use a
+pre-defined alias:
+
+# Shopping sites:                                                              
+#                                                                              
+{ shop }                                                                       
+.quietpc.com                                                                   
+.worldpay.com   # for quietpc.com                                              
+.jungle.com                                                                    
+.scan.co.uk                                                                    
+
+Then, there are sites which rely on pop-up windows (yuck!) to work. Since we
+made pop-up-killing our default above, we need to make exceptions now. Mozilla
+users, who can turn on smart handling of unwanted pop-ups in their browsers,
+can safely choose -filter{popups} (and -kill-popups) above and hence don't need
+this section. Anyway, disabling an already disabled action doesn't hurt, so
+we'll define our exceptions regardless of what was chosen in the defaults
+section:
+
+# These sites require pop-ups too :(                                           
+#                                                                              
+{ -kill-popups -filter{popups} }                                               
+.dabs.com                                                                      
+.overclockers.co.uk                                                            
+.deutsche-bank-24.de                                                           
+
+The fast-redirects action, which we enabled per default above, breaks some
+sites. So disable it for popular sites where we know it misbehaves:
+
+{ -fast-redirects }                                                            
+login.yahoo.com                                                                
+edit.*.yahoo.com                                                               
+.google.com                                                                    
+.altavista.com/.*(like|url|link):http                                          
+.altavista.com/trans.*urltext=http                                             
+.nytimes.com                                                                   
+
+It is important that Privoxy knows which URLs belong to images, so that if they
+are to be blocked, a substitute image can be sent, rather than an HTML page.
+Contacting the remote site to find out is not an option, since it would destroy
+the loading time advantage of banner blocking, and it would feed the
+advertisers (in terms of money and information). We can mark any URL as an
+image with the handle-as-image action, and marking all URLs that end in a known
+image file extension is a good start:
+
+##########################################################################     
+# Images:                                                                      
+##########################################################################     
+                                                                               
+# Define which file types will be treated as images, in case they get          
+# blocked further down this file:                                              
+#                                                                              
+{ +handle-as-image }                                                           
+/.*\.(gif|jpe?g|png|bmp|ico)$                                                  
+
+And then there are known banner sources. They often use scripts to generate the
+banners, so it won't be visible from the URL that the request is for an image.
+Hence we block them and mark them as images in one go, with the help of our
+block-as-image alias defined above. (We could of course just as well use +block
++handle-as-image here.) Remember that the type of the replacement image is
+chosen by the set-image-blocker action. Since all URLs have matched the default
+section with its +set-image-blocker{pattern} action before, it still applies
+and needn't be repeated:
+
+# Known ad generators:                                                         
+#                                                                              
+{ block-as-image }                                                             
+ar.atwola.com                                                                  
+.ad.doubleclick.net                                                            
+.ad.*.doubleclick.net                                                          
+.a.yimg.com/(?:(?!/i/).)*$                                                     
+.a[0-9].yimg.com/(?:(?!/i/).)*$                                                
+bs*.gsanet.com                                                                 
+bs*.einets.com                                                                 
+.qkimg.net                                                                     
+
+One of the most important jobs of Privoxy is to block banners. A huge bunch of
+them are already "blocked" by the filter{banners-by-size} action, which we
+enabled above, and which deletes the references to banner images from the pages
+while they are loaded, so the browser doesn't request them anymore, and hence
+they don't need to be blocked here. But this naturally doesn't catch all
+banners, and some people choose not to use filters, so we need a comprehensive
+list of patterns for banner URLs here, and apply the block action to them.
+
+First comes a bunch of generic patterns, which do most of the work, by matching
+typical domain and path name components of banners. Then comes a list of
+individual patterns for specific sites, which is omitted here to keep the
+example short:
+
+##########################################################################     
+# Block these fine banners:                                                    
+##########################################################################     
+{ +block }                                                                     
+                                                                               
+# Generic patterns:                                                            
+#                                                                              
+ad*.                                                                           
+.*ads.                                                                         
+banner?.                                                                       
+count*.                                                                        
+/.*count(er)?\.(pl|cgi|exe|dll|asp|php[34]?)                                   
+/(?:.*/)?(publicite|werbung|rekla(ma|me|am)|annonse|maino(kset|nta|s)?)/       
+                                                                               
+# Site-specific patterns (abbreviated):                                        
+#                                                                              
+.hitbox.com                                                                    
+
+You wouldn't believe how many advertisers actually call their banner servers
+ads.company.com, or call the directory in which the banners are stored simply
+"banners". So the above generic patterns are surprisingly effective.
+
+But being very generic, they necessarily also catch URLs that we don't want to
+block. The pattern .*ads. e.g. catches "nasty-ads.nasty-corp.com" as intended,
+but also "downloads.sourcefroge.net" or "adsl.some-provider.net." So here come
+some well-known exceptions to the +block section above.
+
+Note that these are exceptions to exceptions from the default! Consider the URL
+"downloads.sourcefroge.net": Initially, all actions are deactivated, so it
+wouldn't get blocked. Then comes the defaults section, which matches the URL,
+but just deactivates the block action once again. Then it matches .*ads., an
+exception to the general non-blocking policy, and suddenly +block applies. And
+now, it'll match .*loads., where -block applies, so (unless it matches again
+further down) it ends up with no block action applying.
+
+##########################################################################     
+# Save some innocent victims of the above generic block patterns:              
+##########################################################################     
+                                                                               
+# By domain:                                                                   
+#                                                                              
+{ -block }                                                                     
+adv[io]*.  # (for advogato.org and advice.*)                                   
+adsl.      # (has nothing to do with ads)                                      
+ad[ud]*.   # (adult.* and add.*)                                               
+.edu       # (universities don't host banners (yet!))                          
+.*loads.   # (downloads, uploads etc)                                          
+                                                                               
+# By path:                                                                     
+#                                                                              
+/.*loads/                                                                      
+                                                                               
+# Site-specific:                                                               
+#                                                                              
+www.globalintersec.com/adv # (adv = advanced)                                  
+www.ugu.com/sui/ugu/adv                                                        
+
+Filtering source code can have nasty side effects, so make an exception for our
+friends at sourceforge.net, and all paths with "cvs" in them. Note that -filter
+disables all filters in one fell swoop!
+
+# Don't filter code!                                                           
+#                                                                              
+{ -filter }                                                                    
+/.*cvs                                                                         
+.sourceforge.net                                                               
+
+The actual default.action is of course more comprehensive, but we hope this
+example made clear how it works.
+
+-------------------------------------------------------------------------------
+
+8.7.2. user.action
+
+So far we are painting with a broad brush by setting general policies, which
+would be a reasonable starting point for many people. Now, you'd maybe want to
+be more specific and have customized rules that are more suitable to your
+personal habits and preferences. These would be for narrowly defined situations
+like your ISP or your bank, and should be placed in user.action, which is
+parsed after all other actions files and hence has the last word, over-riding
+any previously defined actions. user.action is also a safe place for your
+personal settings, since default.action is actively maintained by the Privoxy
+developers and you'll probably want to install updated versions from time to
+time.
+
+So let's look at a few examples of things that one might typically do in
+user.action:
+
+# My user.action file. <fred@foobar.com>                                       
+
+As aliases are local to the actions file that they are defined in, you can't
+use the ones from default.action, unless you repeat them here:
+
+# (Re-)define aliases for this file:                                                        
+#                                                                                           
+{{alias}}                                                                                   
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies                     
+mercy-for-cookies   = -crunch-all-cookies -session-cookies-only                             
+fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups 
+shop        = mercy-for-cookies -filter{popups} -kill-popups                                
+allow-ads   = -block -filter{banners-by-size} # (see below)                                 
+
+Say you have accounts on some sites that you visit regularly, and you don't
+want to have to log in manually each time. So you'd like to allow persistent
+cookies for these sites. The mercy-for-cookies alias defined above does exactly
+that, i.e. it disables crunching of cookies in any direction, and processing of
+cookies to make them temporary.
+
+{ mercy-for-cookies }                                                          
+sunsolve.sun.com                                                               
+slashdot.org                                                                   
+.yahoo.com                                                                     
+.msdn.microsoft.com                                                            
+.redhat.com                                                                    
+
+Your bank needs popups and is allergic to some filter, but you don't know
+which, so you disable them all:
+
+{ -filter -kill-popups }                                                       
+.your-home-banking-site.com                                                    
+
+While browsing the web with Privoxy you noticed some ads that sneaked through,
+but you were too lazy to report them through our fine and easy feedback system,
+so you have added them here:
+
+{ +block }                                                                     
+www.a-popular-site.com/some/unobvious/path                                     
+another.popular.site.net/more/junk/here/                                       
+
+Note that, assuming the banners in the above example have regular image
+extensions (most do), +handle-as-image need not be specified, since all URLs
+ending in these extensions will already have been tagged as images in the
+relevant section of default.action by now.
+
+Then you noticed that the default configuration breaks Forbes Magazine, but you
+were too lazy to find out which action is the culprit, and you were again too
+lazy to give feedback, so you just used the fragile alias on the site, and --
+whoa! -- it worked:
+
+{ fragile }                                                                    
+.forbes.com                                                                    
+
+You like the "fun" text replacements in default.filter, but it is disabled in
+the distributed actions file. (My colleagues on the team just don't have a
+sense of humour, that's why! ;-). So you'd like to turn it on in your private,
+update-safe config, once and for all:
+
+{ +filter{fun} }                                                               
+/ # For ALL sites!                                                             
+
+Note that the above is not really a good idea: There are exceptions to the
+filters in default.action for things that really shouldn't be filtered, like
+code on CVS->Web interfaces. Since user.action has the last word, these
+exceptions won't be valid for the "fun" filtering specified here.
+
+Finally, you might think about how your favourite free websites are funded, and
+find that they rely on displaying banner advertisements to survive. So you
+might want to specifically allow banners for those sites that you feel provide
+value to you:
+
+{ allow-ads }                                                                  
+.sourceforge.net                                                               
+.slashdot.org                                                                  
+.osdn.net                                                                      
+
+Note that allow-ads has been aliased to -block -filter{banners-by-size} above.
+
+-------------------------------------------------------------------------------
+
+9. The Filter File
+
+All text substitutions that can be invoked through the filter action must first
+be defined in the filter file, which is typically called default.filter and
+which can be selected through the filterfile config option.
+
+Typical reasons for doing such substitutions are to eliminate common annoyances
+in HTML and JavaScript, such as pop-up windows, exit consoles, crippled windows
+without navigation tools, the infamous <BLINK> tag etc, to suppress images with
+certain width and height attributes (standard banner sizes or web-bugs), or
+just to have fun. The possibilities are endless.
+
+Filtering works on any text-based document type, including plain text, HTML,
+JavaScript, CSS etc. (all text/* MIME types). Substitutions are made at the
+source level, so if you want to "roll your own" filters, you should be familiar
+with HTML syntax.
+
+Just like the actions files, the filter file is organized in sections, which
+are called filters here. Each filter consists of a heading line, that starts
+with the keyword FILTER:, followed by the filter's name, and a short (one line)
+description of what it does. Below that line come the jobs, i.e. lines that
+define the actual text substitutions. By convention, the name of a filter
+should describe what the filter eliminates. The comment is used in the 
+web-based user interface.
+
+Once a filter called name has been defined in the filter file, it can be
+invoked by using an action of the form +filter{name} in any actions file.
+
+A filter header line for a filter called "foo" could look like this:
+
+FILTER: foo Replace all "foo" with "bar"                                       
+
+Below that line, and up to the next header line, come the jobs that define what
+text replacements the filter executes. They are specified in a syntax that
+imitates Perl's s/// operator. If you are familiar with Perl, you will find
+this to be quite intuitive, and may want to look at the PCRS man page for the
+subtle differences to Perl behaviour. Most notably, the non-standard option
+letter U is supported, which turns the default to ungreedy matching.
+
+If you are new to regular expressions, you might want to take a look at the 
+Appendix on regular expressions, and see the Perl manual for the s///
+operator's syntax and Perl-style regular expressions in general. The below
+examples might also help to get you started.
+
+-------------------------------------------------------------------------------
+
+9.1. Filter File Tutorial
+
+Now, let's complete our "foo" filter. We have already defined the heading, but
+the jobs are still missing. Since all it does is to replace "foo" with "bar",
+there is only one (trivial) job needed:
+
+s/foo/bar/                                                                     
+
+But wait! Didn't the comment say that all occurrences of "foo" should be
+replaced? Our current job will only take care of the first "foo" on each page.
+For global substitution, we'll need to add the g option:
+
+s/foo/bar/g                                                                    
+
+Our complete filter now looks like this:
+
+FILTER: foo Replace all "foo" with "bar"                                       
+s/foo/bar/g                                                                    
+
+Let's look at some real filters for more interesting examples. Here you see a
+filter that protects against some common annoyances that arise from JavaScript
+abuse. Let's look at its jobs one after the other:
+
+FILTER: js-annoyances Get rid of particularly annoying JavaScript abuse                         
+                                                                                                
+# Get rid of JavaScript referrer tracking. Test page: http://www.randomoddness.com/untitled.htm 
+#                                                                                               
+s|(<script.*)document\.referrer(.*</script>)|$1"Not Your Business!"$2|Usg                       
+
+Following the header line and a comment, you see the job. Note that it uses |
+as the delimiter instead of /, because the pattern contains a forward slash,
+which would otherwise have to be escaped by a backslash (\).
+
+Now, let's examine the pattern: it starts with the text <script.* enclosed in
+parentheses. Since the dot matches any character, and * means: "Match an
+arbitrary number of the element left of myself", this matches "<script",
+followed by any text, i.e. it matches the whole page, from the start of the
+first <script> tag.
+
+That's more than we want, but the pattern continues: document\.referrer matches
+only the exact string "document.referrer". The dot needed to be escaped, i.e.
+preceded by a backslash, to take away its special meaning as a joker, and make
+it just a regular dot. So far, the meaning is: Match from the start of the
+first <script> tag in a the page, up to, and including, the text
+"document.referrer", if both are present in the page (and appear in that
+order).
+
+But there's still more pattern to go. The next element, again enclosed in
+parentheses, is .*</script>. You already know what .* means, so the whole
+pattern translates to: Match from the start of the first <script> tag in a page
+to the end of the last <script> tag, provided that the text "document.referrer"
+appears somewhere in between.
+
+This is still not the whole story, since we have ignored the options and the
+parentheses: The portions of the page matched by sub-patterns that are enclosed
+in parentheses, will be remembered and be available through the variables $1,
+$2, ... in the substitute. The U option switches to ungreedy matching, which
+means that the first .* in the pattern will only "eat up" all text in between "
+<script" and the first occurrence of "document.referrer", and that the second .
+* will only span the text up to the first "</script>" tag. Furthermore, the s
+option says that the match may span multiple lines in the page, and the g
+option again means that the substitution is global.
+
+So, to summarize, the pattern means: Match all scripts that contain the text
+"document.referrer". Remember the parts of the script from (and including) the
+start tag up to (and excluding) the string "document.referrer" as $1, and the
+part following that string, up to and including the closing tag, as $2.
+
+Now the pattern is deciphered, but wasn't this about substituting things? So
+lets look at the substitute: $1"Not Your Business!"$2 is easy to read: The text
+remembered as $1, followed by "Not Your Business!" (including the quotation
+marks!), followed by the text remembered as $2. This produces an exact copy of
+the original string, with the middle part (the "document.referrer") replaced by
+"Not Your Business!".
+
+The whole job now reads: Replace "document.referrer" by "Not Your Business!"
+wherever it appears inside a <script> tag. Note that this job won't break
+JavaScript syntax, since both the original and the replacement are
+syntactically valid string objects. The script just won't have access to the
+referrer information anymore.
+
+We'll show you two other jobs from the JavaScript taming department, but this
+time only point out the constructs of special interest:
+
+# The status bar is for displaying link targets, not pointless blahblah        
+#                                                                              
+s/window\.status\s*=\s*['"].*?['"]/dUmMy=1/ig                                  
+
+\s stands for whitespace characters (space, tab, newline, carriage return, form
+feed), so that \s* means: "zero or more whitespace". The ? in .*? makes this
+matching of arbitrary text ungreedy. (Note that the U option is not set). The
+['"] construct means: "a single or a double quote".
+
+So what does this job do? It replaces assignments of single- or double-quoted
+strings to the "window.status" object with a dummy assignment (using a variable
+name that is hopefully odd enough not to conflict with real variables in
+scripts). Thus, it catches many cases where e.g. pointless descriptions are
+displayed in the status bar instead of the link target when you move your mouse
+over links.
+
+# Kill OnUnload popups. Yummy. Test: http://www.zdnet.com/zdsubs/yahoo/tree/yfs.html 
+#                                                                                    
+s/(<body .*)onunload(.*>)/$1never$2/iU                                               
+
+Including the OnUnload event binding in the HTML DOM was a CRIME. When I close
+a browser window, I want it to close and die. Basta. This job replaces the
+"onunload" attribute in "<body>" tags with the dummy word never. Note that the
+i option makes the pattern matching case-insensitive.
+
+The last example is from the fun department:
+
+FILTER: fun Fun text replacements                                              
+                                                                               
+# Spice the daily news:                                                        
+#                                                                              
+s/microsoft(?!\.com)/MicroSuck/ig                                              
+
+Note the (?!\.com) part (a so-called negative lookahead) in the job's pattern,
+which means: Don't match, if the string ".com" appears directly following
+"microsoft" in the page. This prevents links to microsoft.com from being
+messed, while still replacing the word everywhere else.
+
+# Buzzword Bingo (example for extended regex syntax)                           
+#                                                                              
+s* industry[ -]leading \                                                       
+|  cutting[ -]edge \                                                           
+|  award[ -]winning # Comments are OK, too! \                                  
+|  high[ -]performance \                                                       
+|  solutions[ -]based \                                                        
+|  unmatched \                                                                 
+|  unparalleled \                                                              
+|  unrivalled \                                                                
+*<font color="red"><b>BINGO!</b></font> \                                      
+*igx                                                                           
+
+The x option in this job turns on extended syntax, and allows for e.g. the
+liberal use of (non-interpreted!) whitespace for nicer formatting.
+
+You get the idea?
+
+-------------------------------------------------------------------------------
+
+10. Templates
+
+All Privoxy built-in pages, i.e. error pages such as the "404 - No Such Domain"
+error page, the "BLOCKED" page and all pages of its web-based user interface,
+are generated from templates. (Privoxy must be running for the above links to
+work as intended)
+
+These templates are stored in a subdirectory of the configuration directory
+called templates. On unixish platforms, this is typically /etc/privoxy/
+templates/.
+
+The templates are basically normal HTML files, but with place-holders (called
+symbols or exports), which Privoxy fills at run time. You can edit the
+templates with a normal text editor, should you want to customize them. (Not
+recommended for the casual user). Note that just like in configuration files,
+lines starting with # are ignored when the templates are filled in.
+
+The place-holders are of the form @name@, and you will find a list of available
+symbols, which vary from template to template, in the comments at the start of
+each file. Note that these comments are not always accurate, and that it's
+probably best to look at the existing HTML code to find out which symbols are
+supported and what they are filled in with.
+
+A special application of this substitution mechanism is to make whole blocks of
+HTML code disappear when a specific symbol is set. We use this for many
+purposes, one of them being to include the beta warning in all our user
+interface (CGI) pages when Privoxy in in an alpha or beta development stage:
+
+<!-- @if-unstable-start -->                                                    
+                                                                               
+  ... beta warning HTML code goes here ...                                     
+                                                                               
+<!-- if-unstable-end@ -->                                                      
+
+If the "unstable" symbol is set, everything in between and including
+@if-unstable-start and if-unstable-end@ will disappear, leaving nothing but an
+empty comment:
+
+<!--  -->                                                                      
+
+There's also an if-then-else construct and an #include mechanism, but you'll
+sure find out if you are inclined to edit the templates ;-)
+
+All templates refer to a style located at http://config.privoxy.org/
+send-stylesheet. This is, of course, locally served by Privoxy and the source
+for it can be found and edited in the cgi-style.css template.
+
+-------------------------------------------------------------------------------
+
+11. Contacting the Developers, Bug Reporting and Feature Requests
+
+We value your feedback. In fact, we rely on it to improve Privoxy and its
+configuration. However, please note the following hints, so we can provide you
+with the best support:
+
+-------------------------------------------------------------------------------
+
+11.1. Get Support
+
+For casual users, our support forum at SourceForge is probably best suited: 
+http://sourceforge.net/tracker/?group_id=11118&atid=211118
+
+All users are of course welcome to discuss their issues on the users mailing
+list, where the developers also hang around.
+
+-------------------------------------------------------------------------------
+
+11.2. Report Bugs
+
+Please report all bugs only through our bug tracker: http://sourceforge.net/
+tracker/?group_id=11118&atid=111118.
+
+Before doing so, please make sure that the bug has not already been submitted
+and observe the aditional hints at the top of the submit form.
+
+Please try to verify that it is a Privoxy bug, and not a browser or site bug
+first. If unsure, try toggling off Privoxy, and see if the problem persists.
+The appendix of the user manual also has helpful information on action
+debugging. If you are using your own custom configuration, please try the stock
+configs to see if the problem is configuration related.
+
+If not using the latest version, chances are that the bug has been found and
+fixed in the meantime. We would appreciate if you could take the time to 
+upgrade to the latest version (or even the latest CVS snapshot) and verify your
+bug, but this is not required for reporting.
+
+-------------------------------------------------------------------------------
+
+11.3. Request New Features
+
+You are welcome to submit ideas on new features or other proposals for
+improvement through our feature request tracker at http://sourceforge.net/
+tracker/?atid=361118&group_id=11118.
+
+-------------------------------------------------------------------------------
+
+11.4. Report Ads or Other Actions-Related Problems
+
+Please send feedback on ads that slipped through, innocent images that were
+blocked, and any other problems relating to the default.action file through our
+actions feedback mechanism located at http://www.privoxy.org/actions/. On this
+page, you will also find a bookmark which will take you back there from any
+troubled site and even pre-fill the form!
+
+New, improved default.action files will occasionally be made available based on
+your feedback. These will be announced on the ijbswa-announce list and
+available from our project page.
+
+-------------------------------------------------------------------------------
+
+11.5. Other
+
+For any other issues, feel free to use the mailing lists. Technically
+interested users and people who wish to contribute to the project are also
+welcome on the developers list! You can find an overview of all Prixoxy-related
+mailing lists, including list archives, at: http://sourceforge.net/mail/?
+group_id=11118.
+
+-------------------------------------------------------------------------------
+
+12. Privoxy Copyright, License and History
+
+Copyright Â© 2001, 2002 by Privoxy Developers <developers@privoxy.org>
+
+Some source code is based on code Copyright Â© 1997 by Anonymous Coders and
+Junkbusters, Inc. and licensed under the GNU General Public License.
+
+-------------------------------------------------------------------------------
+
+12.1. License
+
+Privoxy is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License, version 2, as published by the Free
+Software Foundation.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details, which
+is available from the Free Software Foundation, Inc, 59 Temple Place - Suite
+330, Boston, MA 02111-1307, USA.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the
+
+ Free Software
+ Foundation, Inc. 59 Temple Place - Suite 330
+ Boston, MA 02111-1307
+ USA 
+
+-------------------------------------------------------------------------------
+
+12.2. History
+
+In the beginning, there was the Internet Junkbuster, by Anonymous Coders and 
+Junkbusters Corporation. It saved many users a lot of pain in the early days of
+web advertising and user tracking.
+
+But the web, its protocols and standards, and with it, the techniques for
+forcing users to consume ads, give up autonomy over their browsing, and for
+spying on them, kept evolving. Unfortunately, the Internet Junkbuster did not.
+Version 2.0.2, published in 1998, was (and is) the last official release
+available from Junkbusters Corporation. Fortunately, it had been released under
+the GNU GPL, which allowed further development by others.
+
+So Stefan Waldherr started maintaining an improved version of the software, to
+which eventually a number of people contributed patches. It could already
+replace banners with a transparent image, and had a first version of pop-up
+killing, but it was still very closely based on the original, with all its
+limitations, such as the lack of HTTP/1.1 support, flexible per-site
+configuration, or content modification. The last release from this effort was
+version 2.0.2-10, published in 2000.
+
+Then, some developers picked up the thread, and started turning the software
+inside out, upside down, and then reassembled it, adding many new features
+along the way.
+
+The result of this is Privoxy, whose first stable release, 3.0, is due in May
+2002.
+
+-------------------------------------------------------------------------------
+
+12.3. Authors
+
+Current Project Developers:
+
+ Jon Foster
+ Andreas Oesterhelt
+ Stefan Waldherr
+ Thomas Steudten
+ Rodney Stromlund
+
+Current Project Contributors:
+
+ Rodrigo Barbosa (RPM specfiles)
+ Hal Burgiss (docs)
+ Alexander Lazic
+ Gábor Lipták
+ Guy
+ Haroon Rafique
+ David Schmidt (OS/2, Mac OSX ports)
+ Joerg Strohmayer
+ Sarantis Paskalis
+
+Originally developed by:
+
+ Junkbusters Corp.
+ Anonymous Coders
+
+Thanks to the many people who have tested Privoxy, reported bugs, or made
+suggestions. These include (in alphabetical order):
+
+ Ken Arromdee
+ Reiner Buehl
+ Andrew J. Caines
+ Clifford Caoile
+ Peter E
+ Aaron Hamid
+ Magnus Holmgren
+ Paul Lieverse
+ Roberto Ragusa
+ Bart Schelstraete
+ Darren Wiebe
+
+-------------------------------------------------------------------------------
+
+13. See Also
+
+Other references and sites of interest to Privoxy users:
+
+http://www.privoxy.org/, the Privoxy Home page.
+
+http://www.privoxy.org/faq/, the Privoxy FAQ.
+
+http://sourceforge.net/projects/ijbswa/, the Project Page for Privoxy on       
+SourceForge.                                                                   
+
+http://config.privoxy.org/, the web-based user interface. Privoxy must be      
+running for this to work. Shortcut: http://p.p/                                
+
+http://www.privoxy.org/actions/, to submit "misses" to the developers.
+
+http://www.junkbusters.com/ht/en/cookies.html, an explanation how cookies are  
+used to track web users.                                                       
+
+http://www.junkbusters.com/ijb.html, the original Internet Junkbuster.
+
+http://www.waldherr.org/junkbuster/, Stefan Waldherr's version of Junkbuster,  
+from which Privoxy was derived.                                                
+
+http://privacy.net/analyze/, a useful site to check what information about you 
+is leaked while you browse the web.                                            
+
+http://www.squid-cache.org/, a very popular caching proxy, which is often used 
+together with Privoxy.                                                         
+
+http://www.privoxy.org/developer-manual/, the Privoxy developer manual.
+
+-------------------------------------------------------------------------------
+
+14. Appendix
+
+14.1. Regular Expressions
+
+Privoxy uses Perl-style "regular expressions" in its actions files and filter
+file, through the PCRE and PCRS libraries.
+
+If you are reading this, you probably don't understand what "regular
+expressions" are, or what they can do. So this will be a very brief
+introduction only. A full explanation would require a book ;-)
+
+Regular expressions provide a language to describe patterns that can be run
+against strings of characters (letter, numbers, etc), to see if they match the
+string or not. The patterns are themselves (sometimes complex) strings of
+literal characters, combined with wild-cards, and other special characters,
+called meta-characters. The "meta-characters" have special meanings and are
+used to build complex patterns to be matched against. Perl Compatible Regular
+Expressions are an especially convenient "dialect" of the regular expression
+language.
+
+To make a simple analogy, we do something similar when we use wild-card
+characters when listing files with the dir command in DOS. *.* matches all
+filenames. The "special" character here is the asterisk which matches any and
+all characters. We can be more specific and use ? to match just individual
+characters. So "dir file?.text" would match "file1.txt", "file2.txt", etc. We
+are pattern matching, using a similar technique to "regular expressions"!
+
+Regular expressions do essentially the same thing, but are much, much more
+powerful. There are many more "special characters" and ways of building complex
+patterns however. Let's look at a few of the common ones, and then some
+examples:
+
+. - Matches any single character, e.g. "a", "A", "4", ":", or "@".
+
+? - The preceding character or expression is matched ZERO or ONE times. Either/
+or.                                                                            
+
++ - The preceding character or expression is matched ONE or MORE times.
+
+* - The preceding character or expression is matched ZERO or MORE times.
+
+\ - The "escape" character denotes that the following character should be taken
+literally. This is used where one of the special characters (e.g. ".") needs to
+be taken literally and not as a special meta-character. Example: "example      
+\.com", makes sure the period is recognized only as a period (and not expanded 
+to its meta-character meaning of any single character).                        
+
+[] - Characters enclosed in brackets will be matched if any of the enclosed    
+characters are encountered. For instance, "[0-9]" matches any numeric digit    
+(zero through nine). As an example, we can combine this with "+" to match any  
+digit one of more times: "[0-9]+".                                             
+
+() - parentheses are used to group a sub-expression, or multiple               
+sub-expressions.                                                               
+
+| - The "bar" character works like an "or" conditional statement. A match is   
+successful if the sub-expression on either side of "|" matches. As an example: 
+"/(this|that) example/" uses grouping and the bar character and would match    
+either "this example" or "that example", and nothing else.                     
+
+These are just some of the ones you are likely to use when matching URLs with
+Privoxy, and is a long way from a definitive list. This is enough to get us
+started with a few simple examples which may be more illuminating:
+
+/.*/banners/.* - A simple example that uses the common combination of "." and "
+*" to denote any character, zero or more times. In other words, any string at
+all. So we start with a literal forward slash, then our regular expression
+pattern (".*") another literal forward slash, the string "banners", another
+forward slash, and lastly another ".*". We are building a directory path here.
+This will match any file with the path that has a directory named "banners" in
+it. The ".*" matches any characters, and this could conceivably be more forward
+slashes, so it might expand into a much longer looking path. For example, this
+could match: "/eye/hate/spammers/banners/annoy_me_please.gif", or just "/
+banners/annoying.html", or almost an infinite number of other possible
+combinations, just so it has "banners" in the path somewhere.
+
+A now something a little more complex:
+
+/.*/adv((er)?ts?|ertis(ing|ements?))?/ - We have several literal forward
+slashes again ("/"), so we are building another expression that is a file path
+statement. We have another ".*", so we are matching against any conceivable
+sub-path, just so it matches our expression. The only true literal that must
+match our pattern is adv, together with the forward slashes. What comes after
+the "adv" string is the interesting part.
+
+Remember the "?" means the preceding expression (either a literal character or
+anything grouped with "(...)" in this case) can exist or not, since this means
+either zero or one match. So "((er)?ts?|ertis(ing|ements?))" is optional, as
+are the individual sub-expressions: "(er)", "(ing|ements?)", and the "s". The "
+|" means "or". We have two of those. For instance, "(ing|ements?)", can expand
+to match either "ing" OR "ements?". What is being done here, is an attempt at
+matching as many variations of "advertisement", and similar, as possible. So
+this would expand to match just "adv", or "advert", or "adverts", or
+"advertising", or "advertisement", or "advertisements". You get the idea. But
+it would not match "advertizements" (with a "z"). We could fix that by changing
+our regular expression to: "/.*/adv((er)?ts?|erti(s|z)(ing|ements?))?/", which
+would then match either spelling.
+
+/.*/advert[0-9]+\.(gif|jpe?g) - Again another path statement with forward
+slashes. Anything in the square brackets "[]" can be matched. This is using
+"0-9" as a shorthand expression to mean any digit one through nine. It is the
+same as saying "0123456789". So any digit matches. The "+" means one or more of
+the preceding expression must be included. The preceding expression here is
+what is in the square brackets -- in this case, any digit one through nine.
+Then, at the end, we have a grouping: "(gif|jpe?g)". This includes a "|", so
+this needs to match the expression on either side of that bar character also. A
+simple "gif" on one side, and the other side will in turn match either "jpeg"
+or "jpg", since the "?" means the letter "e" is optional and can be matched
+once or not at all. So we are building an expression here to match image GIF or
+JPEG type image file. It must include the literal string "advert", then one or
+more digits, and a "." (which is now a literal, and not a special character,
+since it is escaped with "\"), and lastly either "gif", or "jpeg", or "jpg".
+Some possible matches would include: "//advert1.jpg", "/nasty/ads/
+advert1234.gif", "/banners/from/hell/advert99.jpg". It would not match
+"advert1.gif" (no leading slash), or "/adverts232.jpg" (the expression does not
+include an "s"), or "/advert1.jsp" ("jsp" is not in the expression anywhere).
+
+We are barely scratching the surface of regular expressions here so that you
+can understand the default Privoxy configuration files, and maybe use this
+knowledge to customize your own installation. There is much, much more that can
+be done with regular expressions. Now that you know enough to get started, you
+can learn more on your own :/
+
+More reading on Perl Compatible Regular expressions: http://www.perldoc.com/
+perl5.6/pod/perlre.html
+
+For information on regular expression based substititions and their
+applications in filters, please see the filter file tutorial in this manual.
+
+-------------------------------------------------------------------------------
+
+14.2. Privoxy's Internal Pages
+
+Since Privoxy proxies each requested web page, it is easy for Privoxy to trap
+certain special URLs. In this way, we can talk directly to Privoxy, and see how
+it is configured, see how our rules are being applied, change these rules and
+other configuration options, and even turn Privoxy's filtering off, all with a
+web browser. 
+
+The URLs listed below are the special ones that allow direct access to Privoxy.
+Of course, Privoxy must be running to access these. If not, you will get a
+friendly error message. Internet access is not necessary either.
+
+  * Privoxy main page:
+   
+        http://config.privoxy.org/
+       
+    There is a shortcut: http://p.p/ (But it doesn't provide a fallback to a
+    real page, in case the request is not sent through Privoxy)
+   
+  * Show information about the current configuration, including viewing and
+    editing of actions files:
+   
+        http://config.privoxy.org/show-status
+       
+  * Show the source code version numbers:
+   
+        http://config.privoxy.org/show-version
+       
+  * Show the browser's request headers:
+   
+        http://config.privoxy.org/show-request
+       
+  * Show which actions apply to a URL and why:
+   
+        http://config.privoxy.org/show-url-info
+       
+  * Toggle Privoxy on or off. In this case, "Privoxy" continues to run, but
+    only as a pass-through proxy, with no actions taking place:
+   
+        http://config.privoxy.org/toggle
+       
+    Short cuts. Turn off, then on:
+   
+        http://config.privoxy.org/toggle?set=disable
+       
+        http://config.privoxy.org/toggle?set=enable
+       
+These may be bookmarked for quick reference. See next. 
+
+-------------------------------------------------------------------------------
+
+14.2.1. Bookmarklets
+
+Below are some "bookmarklets" to allow you to easily access a "mini" version of
+some of Privoxy's special pages. They are designed for MS Internet Explorer,
+but should work equally well in Netscape, Mozilla, and other browsers which
+support JavaScript. They are designed to run directly from your bookmarks - not
+by clicking the links below (although that should work for testing).
+
+To save them, right-click the link and choose "Add to Favorites" (IE) or "Add
+Bookmark" (Netscape). You will get a warning that the bookmark "may not be
+safe" - just click OK. Then you can run the Bookmarklet directly from your
+favorites/bookmarks. For even faster access, you can put them on the "Links"
+bar (IE) or the "Personal Toolbar" (Netscape), and run them with a single
+click.
+
+  * Privoxy - Enable
+   
+  * Privoxy - Disable
+   
+  * Privoxy - Toggle Privoxy (Toggles between enabled and disabled)
+   
+  * Privoxy- View Status
+   
+  * Privoxy - Submit Actions File Feedback
+   
+Credit: The site which gave us the general idea for these bookmarklets is 
+www.bookmarklets.com. They have more information about bookmarklets.
+
+-------------------------------------------------------------------------------
+
+14.3. Chain of Events
+
+Let's take a quick look at the basic sequence of events when a web page is
+requested by your browser and Privoxy is on duty:
+
+  * First, your web browser requests a web page. The browser knows to send the
+    request to Privoxy, which will in turn, relay the request to the remote web
+    server after passing the following tests:
+   
+  * Privoxy traps any request for its own internal CGI pages (e.g http://p.p/)
+    and sends the CGI page back to the browser.
+   
+  * Next, Privoxy checks to see if the URL matches any "+block" patterns. If
+    so, the URL is then blocked, and the remote web server will not be
+    contacted. "+handle-as-image" is then checked and if it does not match, an
+    HTML "BLOCKED" page is sent back. Otherwise, if it does match, an image is
+    returned. The type of image depends on the setting of "+set-image-blocker"
+    (blank, checkerboard pattern, or an HTTP redirect to an image elsewhere).
+   
+  * Untrusted URLs are blocked. If URLs are being added to the trust file, then
+    that is done.
+   
+  * If the URL pattern matches the "+fast-redirects" action, it is then
+    processed. Unwanted parts of the requested URL are stripped.
+   
+  * Now the rest of the client browser's request headers are processed. If any
+    of these match any of the relevant actions (e.g. "+hide-user-agent", etc.),
+    headers are suppressed or forged as determined by these actions and their
+    parameters.
+   
+  * Now the web server starts sending its response back (i.e. typically a web
+    page and related data).
+   
+  * First, the server headers are read and processed to determine, among other
+    things, the MIME type (document type) and encoding. The headers are then
+    filtered as deterimed by the "+crunch-incoming-cookies", 
+    "+session-cookies-only", and "+downgrade-http-version" actions.
+   
+  * If the "+kill-popups" action applies, and it is an HTML or JavaScript
+    document, the popup-code in the response is filtered on-the-fly as it is
+    received.
+   
+  * If a "+filter" or "+deanimate-gifs" action applies (and the document type
+    fits the action), the rest of the page is read into memory (up to a
+    configurable limit). Then the filter rules (from default.filter) are
+    processed against the buffered content. Filters are applied in the order
+    they are specified in the default.filter file. Animated GIFs, if present,
+    are reduced to either the first or last frame, depending on the action
+    setting.The entire page, which is now filtered, is then sent by Privoxy
+    back to your browser.
+   
+    If neither "+filter" or "+deanimate-gifs" matches, then Privoxy passes the
+    raw data through to the client browser as it becomes available.
+   
+  * As the browser receives the now (probably filtered) page content, it reads
+    and then requests any URLs that may be embedded within the page source,
+    e.g. ad images, stylesheets, JavaScript, other HTML documents (e.g.
+    frames), sounds, etc. For each of these objects, the browser issues a new
+    request. And each such request is in turn processed as above. Note that a
+    complex web page may have many such embedded URLs.
+   
+-------------------------------------------------------------------------------
+
+14.4. Anatomy of an Action
+
+The way Privoxy applies actions and filters to any given URL can be complex,
+and not always so easy to understand what is happening. And sometimes we need
+to be able to see just what Privoxy is doing. Especially, if something Privoxy
+is doing is causing us a problem inadvertently. It can be a little daunting to
+look at the actions and filters files themselves, since they tend to be filled
+with regular expressions whose consequences are not always so obvious.
+
+One quick test to see if Privoxy is causing a problem or not, is to disable it
+temporarily. This should be the first troubleshooting step. See the
+Bookmarklets section on a quick and easy way to do this (be sure to flush
+caches afterward!).
+
+Privoxy also provides the http://config.privoxy.org/show-url-info page that can
+show us very specifically how actions are being applied to any given URL. This
+is a big help for troubleshooting.
+
+First, enter one URL (or partial URL) at the prompt, and then Privoxy will tell
+us how the current configuration will handle it. This will not help with
+filtering effects (i.e. the "+filter" action) from the default.filter file
+since this is handled very differently and not so easy to trap! It also will
+not tell you about any other URLs that may be embedded within the URL you are
+testing. For instance, images such as ads are expressed as URLs within the raw
+page source of HTML pages. So you will only get info for the actual URL that is
+pasted into the prompt area -- not any sub-URLs. If you want to know about
+embedded URLs like ads, you will have to dig those out of the HTML source. Use
+your browser's "View Page Source" option for this. Or right click on the ad,
+and grab the URL.
+
+Let's try an example, google.com, and look at it one section at a time:
+
+ Matches for http://google.com:                                                
+                                                                               
+ In file: default.action [ View ] [ Edit ]                                     
+                                                                               
+{-add-header                                                                   
+ -block                                                                        
+ -crunch-outgoing-cookies                                                      
+ -crunch-incoming-cookies                                                      
+ +deanimate-gifs{last}                                                         
+ -downgrade-http-version                                                       
+ +fast-redirects                                                               
+ -filter{popups}                                                               
+ -filter{fun}                                                                  
+ -filter{shockwave-flash}                                                      
+ -filter{crude-parental}                                                       
+ +filter{html-annoyances}                                                      
+ +filter{js-annoyances}                                                        
+ +filter{content-cookies}                                                      
+ +filter{webbugs}                                                              
+ +filter{refresh-tags}                                                         
+ +filter{nimda}                                                                
+ +filter{banners-by-size}                                                      
+ +hide-forwarded-for-headers                                                   
+ +hide-from-header{block}                                                      
+ +hide-referer{forge}                                                          
+ -hide-user-agent                                                              
+ -handle-as-image                                                              
+ -kill-popups                                                                  
+ -limit-connect                                                                
+ +prevent-compression                                                          
+ -send-vanilla-wafer                                                           
+ -send-wafer                                                                   
+ +session-cookies-only                                                         
+ +set-image-blocker{pattern} }                                                 
+/                                                                              
+                                                                               
+ { -session-cookies-only }                                                     
+ .google.com                                                                   
+                                                                               
+ { -fast-redirects }                                                           
+ .google.com                                                                   
+                                                                               
+In file: user.action [ View ] [ Edit ]                                         
+(no matches in this file)                                                      
+
+This tells us how we have defined our "actions", and which ones match for our
+example, "google.com". The first listing is any matches for the standard.action
+file. No hits at all here on "standard". Then next is "default", or our
+default.action file. The large, multi-line listing, is how the actions are set
+to match for all URLs, i.e. our default settings. If you look at your "actions"
+file, this would be the section just below the "aliases" section near the top.
+This will apply to all URLs as signified by the single forward slash at the end
+of the listing -- "/".
+
+But we can define additional actions that would be exceptions to these general
+rules, and then list specific URLs (or patterns) that these exceptions would
+apply to. Last match wins. Just below this then are two explicit matches for
+".google.com". The first is negating our previous cookie setting, which was for
+"+session-cookies-only" (i.e. not persistent). So we will allow persistent
+cookies for google. The second turns off any "+fast-redirects" action, allowing
+this to take place unmolested. Note that there is a leading dot here --
+".google.com". This will match any hosts and sub-domains, in the google.com
+domain also, such as "www.google.com". So, apparently, we have these two
+actions defined somewhere in the lower part of our default.action file, and
+"google.com" is referenced somewhere in these latter sections.
+
+Then, for our user.action file, we again have no hits.
+
+And finally we pull it all together in the bottom section and summarize how
+Privoxy is applying all its "actions" to "google.com": 
+
+ Final results:                                                                
+                                                                               
+ -add-header                                                                   
+ -block                                                                        
+ -crunch-outgoing-cookies                                                      
+ -crunch-incoming-cookies                                                      
+ +deanimate-gifs{last}                                                         
+ -downgrade-http-version                                                       
+ -fast-redirects                                                               
+ -filter{popups}                                                               
+ -filter{fun}                                                                  
+ -filter{shockwave-flash}                                                      
+ -filter{crude-parental}                                                       
+ +filter{html-annoyances}                                                      
+ +filter{js-annoyances}                                                        
+ +filter{content-cookies}                                                      
+ +filter{webbugs}                                                              
+ +filter{refresh-tags}                                                         
+ +filter{nimda}                                                                
+ +filter{banners-by-size}                                                      
+ +hide-forwarded-for-headers                                                   
+ +hide-from-header{block}                                                      
+ +hide-referer{forge}                                                          
+ -hide-user-agent                                                              
+ -handle-as-image                                                              
+ -kill-popups                                                                  
+ -limit-connect                                                                
+ +prevent-compression                                                          
+ -send-vanilla-wafer                                                           
+ -send-wafer                                                                   
+ -session-cookies-only                                                         
+ +set-image-blocker{pattern}                                                   
+
+Notice the only difference here to the previous listing, is to "fast-redirects"
+and "session-cookies-only".
+
+Now another example, "ad.doubleclick.net":
+
+ { +block +handle-as-image }                                                   
+  .ad.doubleclick.net                                                          
+                                                                               
+ { +block +handle-as-image }                                                   
+  ad*.                                                                         
+                                                                               
+ { +block +handle-as-image }                                                   
+  .doubleclick.net                                                             
+
+We'll just show the interesting part here, the explicit matches. It is matched
+three different times. Each as an "+block +handle-as-image", which is the
+expanded form of one of our aliases that had been defined as: "+imageblock". (
+"Aliases" are defined in the first section of the actions file and typically
+used to combine more than one action.)
+
+Any one of these would have done the trick and blocked this as an unwanted
+image. This is unnecessarily redundant since the last case effectively would
+also cover the first. No point in taking chances with these guys though ;-)
+Note that if you want an ad or obnoxious URL to be invisible, it should be
+defined as "ad.doubleclick.net" is done here -- as both a "+block" and an 
+"+handle-as-image". The custom alias "+imageblock" just simplifies the process
+and make it more readable.
+
+One last example. Let's try "http://www.rhapsodyk.net/adsl/HOWTO/". This one is
+giving us problems. We are getting a blank page. Hmmm...
+
+ Matches for http://www.rhapsodyk.net/adsl/HOWTO/:                             
+                                                                               
+ In file: default.action [ View ] [ Edit ]                                     
+                                                                               
+ {-add-header                                                                  
+  -block                                                                       
+  -crunch-incoming-cookies                                                     
+  -crunch-outgoing-cookies                                                     
+  +deanimate-gifs                                                              
+  -downgrade-http-version                                                      
+  +fast-redirects                                                              
+  +filter{html-annoyances}                                                     
+  +filter{js-annoyances}                                                       
+  +filter{kill-popups}                                                         
+  +filter{webbugs}                                                             
+  +filter{nimda}                                                               
+  +filter{banners-by-size}                                                     
+  +filter{hal}                                                                 
+  +filter{fun}                                                                 
+  +hide-forwarded-for-headers                                                  
+  +hide-from-header{block}                                                     
+  +hide-referer{forge}                                                         
+  -hide-user-agent                                                             
+  -handle-as-image                                                             
+  +kill-popups                                                                 
+  +prevent-compression                                                         
+  -send-vanilla-wafer                                                          
+  -send-wafer                                                                  
+  +session-cookies-only                                                        
+  +set-image-blocker{blank} }                                                  
+   /                                                                           
+                                                                               
+ { +block +handle-as-image }                                                   
+  /ads                                                                         
+
+Ooops, the "/adsl/" is matching "/ads"! But we did not want this at all! Now we
+see why we get the blank page. We could now add a new action below this that
+explicitly does not block ("{-block}") paths with "adsl". There are various
+ways to handle such exceptions. Example:
+
+ { -block }                                                                    
+  /adsl                                                                        
+
+Now the page displays ;-) Be sure to flush your browser's caches when making
+such changes. Or, try using Shift+Reload.
+
+But now what about a situation where we get no explicit matches like we did
+with:
+
+ { +block +handle-as-image }                                                   
+ /ads                                                                          
+
+That actually was very telling and pointed us quickly to where the problem was.
+If you don't get this kind of match, then it means one of the default rules in
+the first section is causing the problem. This would require some guesswork,
+and maybe a little trial and error to isolate the offending rule. One likely
+cause would be one of the "{+filter}" actions. Try adding the URL for the site
+to one of aliases that turn off "+filter":
+
+ {shop}                                                                        
+ .quietpc.com                                                                  
+ .worldpay.com   # for quietpc.com                                             
+ .jungle.com                                                                   
+ .scan.co.uk                                                                   
+ .forbes.com                                                                   
+
+"{shop}" is an "alias" that expands to "{ -filter -session-cookies-only }". Or
+you could do your own exception to negate filtering: 
+
+ {-filter}                                                                     
+ .forbes.com                                                                   
+
+This would probably be most appropriately put in user.action, for local site
+exceptions.
+
+"{fragile}" is an alias that disables most actions. This can be used as a last
+resort for problem sites. Remember to flush caches! If this still does not
+work, you will have to go through the remaining actions one by one to find
+which one(s) is causing the problem.
+
diff --git a/doc/webserver/.htaccess b/doc/webserver/.htaccess
new file mode 100644 (file)
index 0000000..e2c3e3d
--- /dev/null
@@ -0,0 +1,26 @@
+# http://privoxy.org/.htaccess
+#
+# By Jon Foster
+#
+# Intercepts requests for these servers:
+#    http://ijbswa.sourceforge.net/
+#    http://privoxy.com/
+#    http://www.privoxy.com/
+#    http://privoxy.org/
+#
+# And redirects all requests to the canonical web server:
+#    http://www.privoxy.org/
+#
+#
+# Uses Apache's mod_rewrite
+# See http://httpd.apache.org/docs/mod/mod_rewrite.html
+#
+
+# Enable mod_rewrite
+RewriteEngine on
+
+
+RewriteCond %{HTTP_HOST}   !^www\.privoxy\.org\.?$ [NC]
+RewriteCond %{HTTP_HOST}   !^$
+RewriteRule ^(.*)$         http://www\.privoxy.org/$1 [R,L]
+
diff --git a/doc/webserver/README.txt b/doc/webserver/README.txt
new file mode 100644 (file)
index 0000000..4221e3a
--- /dev/null
@@ -0,0 +1,9 @@
+All files contained in this directory should eventually be
+on the project's homepage 
+
+   ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+
+which is indeed http://ijbswa.sourceforge.net 
+and http://www.privoxy.org/.
+
+-Stefan, April 2002
\ No newline at end of file
diff --git a/doc/webserver/actions/index.php b/doc/webserver/actions/index.php
new file mode 100755 (executable)
index 0000000..660f7be
--- /dev/null
@@ -0,0 +1,303 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <!--
+
+  File :  $Source: /cvsroot/ijbswa/current/doc/webserver/actions/index.php,v $
+
+  Purpose  :  Submit form for actions file feedback (step 1)
+              This file belongs in
+              ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+
+  $Id: index.php,v 1.24 2002/04/28 16:56:47 swa Exp $
+
+  $Log: index.php,v $
+  Revision 1.24  2002/04/28 16:56:47  swa
+  bookmarklet text
+
+  Revision 1.23  2002/04/13 14:13:19  oes
+  Require exact AF version; Added hint where to go for BRs, FRs and SRs
+
+  Revision 1.22  2002/04/11 10:11:04  oes
+  Actionsfile Version 1.2
+
+  Revision 1.21  2002/04/10 13:51:19  oes
+  Updated to new Bookmarklet
+
+  Revision 1.20  2002/04/10 00:07:35  oes
+  Moved window sizing and positioning code to Bookmarklet
+
+  Revision 1.19  2002/04/09 13:06:29  oes
+  Resize and jump to the right on load
+
+  Revision 1.18  2002/04/08 17:03:29  oes
+   - Fixed problem with spaces in URLs
+   - Adapt to unified stylesheet
+
+  Revision 1.17  2002/04/08 10:32:00  oes
+  cosmetics again
+
+  Revision 1.16  2002/04/08 08:11:04  oes
+  Bumped up actions file number
+
+  Revision 1.15  2002/04/07 17:13:08  oes
+  Ooops: fixing submit target url
+
+  Revision 1.14  2002/04/07 15:10:12  oes
+  Restoring CVS history
+
+  Revision 1.13  2002/04/06 15:19:35  oes
+  Clean-up, smarter handling of unreachable URLs
+
+  Revision 1.12  2002/04/06 11:34:44  oes
+  Cosmetics
+
+  Revision 1.11  2002/04/04 19:48:11  oes
+  Reactivating the scripts ,-)
+
+  Revision 1.10  2002/04/03 19:36:04  swa
+  consistent look
+
+  Revision 1.9  2002/04/02 19:32:45  oes
+  Adding temporary fix for missing curl support on SF (step 2 + 3 on oesterhelt.org)
+
+  Revision 1.8  2002/04/02 08:45:22  oes
+  Made script location indepandant
+
+  Revision 1.7  2002/04/02 07:21:34  oes
+  Using relative link for step2
+
+  Revision 1.6  2002/04/02 06:14:22  oes
+  Fixed bookmarklet
+
+  Revision 1.5  2002/04/01 19:13:47  oes (based on 1.2)
+  Extended, fixed bugs, beefed up design, made IE-safe
+
+  Revision 1.4  2002/03/30 20:44:44  swa
+  have consistent look and feel. part 2.
+  use correct urls.
+
+  Revision 1.3  2002/03/30 19:49:34  swa
+  have consistent look and feel
+
+  Revision 1.2  2002/03/30 03:35:48  oes
+  Updated bookmarklet
+
+  Revision 1.1  2002/03/30 03:20:30  oes
+  Added Feedback mechanism for actions file
+
+
+  Copyright (C) 2002 the SourceForge Privoxy team. 
+  http://www.privoxy.org/
+
+  Written by Andreas Oesterhelt
+
+  This program is free software; you can redistribute it
+  and/or modify it under the terms of the GNU General
+  Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at
+  your option) any later version.
+
+  This program is distributed in the hope that it will
+  be useful, but WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  The GNU General Public License should be included with
+  this file.  If not, you can view it at
+  http://www.gnu.org/copyleft/gpl.html
+  or write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ -->
+
+ <head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <link rel="stylesheet" type="text/css" href="../privoxy.css">
+  <link rel="stylesheet" type="text/css" href="../p_feedback.css">
+
+<?php
+
+/*
+ * Config:
+ */
+$required_actions_file_version = "1.2";
+$required_privoxy_version = "2.9.14";
+$actions_file_download = "http://www.privoxy.org/actions/testdrive.action";
+$submit_target = "http://www.oesterhelt.org/actions/step2.php";
+
+
+/*
+ * Debug:
+ */
+//phpinfo();
+//error_reporting(E_ALL);
+error_reporting(E_NONE);
+
+/*
+ * Function: error_abort
+ * Purpose:  Return an error page with $title and $message
+ */
+function error_abort($title, $message)
+{
+   if ($title == "invalid") /* shortcut */
+   {
+      $title = "Invalid Feedback Submission";
+   }
+
+   echo ("  <title>Privoxy: $title</title>
+           </head>
+           <body>
+            <div class=\"title\">
+             <h1>
+              <a href=\"http://www.privoxy.org/\">Privoxy</a>: $title
+              </h1>
+             </div>
+            <center>
+             <div class=\"warning\">
+              $message
+             </div>
+            </center>
+            <p>Valid <a href=\"http://validator.w3.org/\">HTML 4.01 Transitional</a></p>
+           </body>
+          </html>\n");
+   exit; 
+}
+
+
+/*
+ * Bookmarklet that leads here:
+ */
+$my_address = "http://" . $HTTP_SERVER_VARS["HTTP_HOST"] . $PHP_SELF;
+$bookmarklet = "javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('$my_address?url='+escape(location.href)," .
+               "'Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no," .
+               "copyhistory=no').focus());";
+
+/* 
+ * Provide default if URL unset
+ */
+if (!isset($url))
+{
+   $url = "http://www.example.com/";
+}
+else
+{
+   $url = strtr($url, " ", "+");
+}
+
+/* 
+ * Deny feedback which is not based on our latest
+ * distribution:
+ */
+$headers = getallheaders();
+
+if (!isset($headers["X-Actions-File-Version"]) || $headers["X-Actions-File-Version"] != $required_actions_file_version)
+{
+
+   error_abort("invalid", "<p>As much as we welcome your feedback, please note that
+               we can only accept problem reports based on:
+               </p>
+               <ul>
+                <li><a href=\"http://www.privoxy.org/\" target=\"_blank\">Privoxy</a> version $required_privoxy_version or later</li>
+                <li><a href=\"$actions_file_download\">Actionsfile</a> version  version $required_actions_file_version</li>
+               </ul>
+               <p>We hope you will understand that we feel unable to maintain concurrent versions of the file.</p>
+               <p><i>Hint: To upgrade your actions file, just right-click the above link, then save as default.action in
+                  your Privoxy config directory</i>
+               </p>");
+}
+
+?>
+
+  <title>Privoxy Action List Feedback - Step 1 of 2</title>
+ </head>
+
+ <body>
+  <div class="title">
+    <h1>
+      <a href="http://www.privoxy.org" target="_blank">Privoxy</a> Action List Feedback - Step 1 of 2
+    </h1>
+  </div>
+
+  <div class="box">
+   <p>
+    <b>Thank you for reporting a missing or invalid action!</b> 
+   </p>
+
+   <p>
+    The Privoxy team relies on <b>your</b> feedback to maintain an efficient actions file!
+    <br>Please fill the below form and click to proceed to step 2.
+   </p>
+
+   <p>
+    Please keep in mind that this is <b>not</b> the place for
+    <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=211118" target="_blank">support requests</a>,
+    <br><a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=111118" target="_blank">bug reports</a> or
+    <a href="http://sourceforge.net/tracker/?atid=361118&amp;group_id=11118" target="_blank">feature requests</a>.
+   </p>
+
+  </div>
+
+  <div class="box">
+   <form action="<?php echo($submit_target); ?>" method="post">
+
+    <table border="0" cellpadding="0" cellspacing="4">
+
+     <tr>
+      <td align="right">URL:</td>
+      <td>
+       <input name="referrer_url" value="<?php echo($url); ?>" type="text" size="45" maxlength="255">
+      </td>
+     </tr>
+
+     <tr>
+      <td align="right">Nature of the problem:</td>
+      <td>
+       <select name="problem" size="1">
+        <option selected value="INVALID">Please select...</option>
+        <option value="P1">An advertisment was NOT blocked</option>
+        <option value="P2">An innocent image WAS blocked</option>
+        <option value="P3">The whole page was erraneously blocked</option>
+        <option value="P4">The page needs popups but they don't work</option>
+        <option value="P5">Other problem</option>
+       </select>
+      </td>
+     </tr>
+
+     <tr>
+      <td>&nbsp;</td>
+      <td>
+       <input type=submit value="Proceed to step 2">
+      </td>
+     </tr>
+
+    </table>
+   </form>
+  </div>
+
+  <center>
+   <div class="info">
+    <h2>Using <a href="http://www.bookmarklets.com" target="_blank">Bookmarklets</a> for Feedback</h2>
+    <p>
+     To make it even easier for you, we provide a bookmarklet which will not only take you here from
+     any troubled page you might be surfing, but also pre-fill the form!
+    </p>
+    <p>
+     Please right-click the following link and choose "Add to Favorites" (IE) or "Add Bookmark for Link" (Netscape): 
+     <a href="<?php echo($bookmarklet); ?>">Privoxy - Submit Actions File Feedback</a>
+    </p>
+
+    <p>
+     <i>You might get a warning that the bookmark "may not be safe" (IE) - just click OK.
+     For even faster access, you can put it on the "Links" bar (IE) or the "Personal Toolbar" (Netscape),
+     and submit feedback with a single click!</i>
+    </p>
+   </div>
+  </center>
+
+  <p>Valid <a href="http://validator.w3.org/">HTML 4.01 Transitional</a></p>
+
+ </body>
+</html>
diff --git a/doc/webserver/actions/results/.htaccess b/doc/webserver/actions/results/.htaccess
new file mode 100644 (file)
index 0000000..210ca5c
--- /dev/null
@@ -0,0 +1,11 @@
+# http://privoxy.org/actions/results/.htaccess
+#
+# Keeps user feedback confidential by
+# denying access to everybody.
+#
+# To view the feedback use:
+# ssh ijbswa.sf.net cat /home/groups/i/ij/ijbswa/htdocs/actions/results/actions-feedback.txt
+#
+<Limit GET>
+  Deny from all
+</Limit>
diff --git a/doc/webserver/actions/results/actions-feedback.txt b/doc/webserver/actions/results/actions-feedback.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/doc/webserver/actions/step2.php b/doc/webserver/actions/step2.php
new file mode 100644 (file)
index 0000000..bdc08cd
--- /dev/null
@@ -0,0 +1,518 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <!--
+
+  File :  $Source: /cvsroot/ijbswa/current/doc/webserver/actions/step2.php,v $
+
+  Purpose  :  Submit form for actions file feedback (step 2)
+              This file belongs in
+              ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+
+  $Id: step2.php,v 1.13 2002/04/09 13:08:21 oes Exp $
+
+  $Log: step2.php,v $
+  Revision 1.13  2002/04/09 13:08:21  oes
+  declare script type
+
+  Revision 1.12  2002/04/08 17:04:05  oes
+  Adapt to unified stylesheet
+
+  Revision 1.11  2002/04/07 15:00:20  oes
+  Descand into framesets to harvest all image URLs
+
+  Revision 1.10  2002/04/06 15:19:35  oes
+  Cosmetics   Clean-up, smarter handling of unreachable URLs
+
+  Revision 1.9  2002/04/06 11:34:44  oes
+  Reactivating the scripts ,-)   Cosmetics
+
+  Revision 1.7  2002/04/03 19:36:04  swa
+  consistent look
+
+  Revision 1.6  2002/04/02 07:22:19  oes
+  Elimnating duplicate images; using relative link for step3
+
+  Revision 1.5  2002/04/02 06:14:47  oes
+  Follow redirects  
+
+  Revision 1.4  2002/04/01 19:13:47  oes (based on 1.2)
+  Extended, fixed bugs, beefed up design, made IE-safe
+
+  Revision 1.3  2002/03/30 20:44:46  swa
+  have consistent look and feel. part 2.
+  use correct urls. 
+
+  Revision 1.2  2002/03/30 19:49:34  swa
+  have consistent look and feel
+
+  Revision 1.1  2002/03/30 03:20:30  oes
+  Added Feedback mechanism for actions file
+
+
+  Copyright (C) 2002 the SourceForge Privoxy team.
+  http://www.privoxy.org/
+
+  Written by Andreas Oesterhelt
+
+  This program is free software; you can redistribute it
+  and/or modify it under the terms of the GNU General
+  Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at
+  your option) any later version.
+
+  This program is distributed in the hope that it will
+  be useful, but WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  The GNU General Public License should be included with
+  this file.  If not, you can view it at
+  http://www.gnu.org/copyleft/gpl.html
+  or write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ -->
+
+ <head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <link rel="stylesheet" type="text/css" href="../privoxy.css">
+  <link rel="stylesheet" type="text/css" href="../p_feedback.css">
+
+  <script language="javascript" type="text/javascript">
+  <!--
+   //
+   // Could be as easy as style="max-wdith: 300px; max-height..." inside the
+   // <img> tag, but IE doesn't understand that. Setting the values directly also
+   // screws IE for some weird reason. All praise MS.
+   //
+
+   function prettyscale(image)
+   {
+      newwidth = 0
+      newheight = 0
+
+      if (image.width > 300)
+      {
+         newwidth = 300
+      }
+
+      if (image.height > 50)
+      {
+         newheight = 50
+      }
+
+      if (image.width < 20)
+      {
+         newwidth = 20
+      }
+
+      if (image.height < 20)
+      {
+         newheight = 20
+      }
+
+      if (newwidth != 0)
+      {
+         image.width = newwidth
+      }
+
+      if (newheight != 0)
+      {
+         image.height = newheight
+      }
+   }
+  //-->
+  </script>
+
+<?php
+
+/*
+ * For testing: 
+ */
+//phpinfo();
+//error_reporting(E_ALL);
+error_reporting(E_NONE);
+
+/*
+ * Function: link_to_absolute
+ * Purpose:  Make $link from $base absolute
+ */
+function link_to_absolute($base, $link)
+{
+   /*
+    * If $link already is absolute, we're done:
+    */
+   if (!strncmp("http://", $link, 7) || !strncmp("https://", $link, 8))
+   {
+      return $link;
+   }
+
+   /*
+    * Cut the base to it's proto://host/ or to its proto://host/dir/,
+    * depending whether $link is host-relative or path-relative.
+    */
+   if ($link{0} == "/")
+   {
+      /*
+       * host-relative:
+       */
+       preg_match('|^(https?://[^/]+)|i', $base, $results);
+       $base = $results[1];
+   }
+   else
+   {
+      /*
+       * path-relative:
+       */
+      if (strpos($base, '/') != strlen($base))
+      {
+         preg_match('|(.*/)|i', $base, $results);
+         $base = $results[1];
+      }
+   }
+   return $base.$link;
+}
+
+
+/*
+ * Function: slurp_page
+ *
+ * Purpose:  Retrieve a URL with curl, and return the contents
+ *           or "FAILED" if it fails.
+ */
+
+function slurp_page($url)
+{
+   $ch = curl_init ($url);
+
+   curl_setopt ($ch, CURLOPT_HEADER, 0);
+   curl_setopt ($ch, CURLOPT_FAILONERROR, 1);
+   curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
+   curl_setopt ($ch, CURLOPT_TIMEOUT, 20);            
+
+   ob_start();
+   $success = curl_exec ($ch);
+   $page = ob_get_contents();
+   ob_end_clean();
+
+   curl_close ($ch);
+
+   return $success ? $page : "FAILED";
+}
+
+/*
+ * Function: get_image_urls_sp
+ * 
+ * Purpose:  Return the image URLs from a single page
+ */
+function get_image_urls_sp($page, $url)
+{
+   preg_match_all('|<img\s+[^>]*?src=[\'"]?(.*?)[\'" >]|i', $page, $matches);
+   
+   foreach (array_unique($matches[1]) as $image_link)
+   {
+      $result[] = link_to_absolute($url, $image_link); 
+   }
+
+   return count($result) ? $result : 0;
+}
+
+/*
+ * Function: get_image_urls
+ * 
+ * Purpose:  If the page is a frameset, rerurn the image URLs from all
+ *           its frame SRCes, else from the page itself.
+ */
+function get_image_urls($page, $url)
+{
+
+   preg_match_all('|<frame\s+[^>]*?src=[\'"]?(.*?)[\'" >]|i', $page, $matches);
+
+   if (count($matches[1]))
+   {
+      foreach(array_unique($matches[1]) as $frame_link)
+      {
+         $framebuf = slurp_page(link_to_absolute($url, $frame_link));
+         $result = array_merge($result, get_image_urls_sp($framebuf, link_to_absolute($url, $frame_link)));
+      }
+   }
+   else
+   {
+      $result = get_image_urls_sp($page, $url);
+   }
+
+   return array_values(array_unique($result));
+}
+
+
+/*
+ * Function: error_abort
+ * Purpose:  Return an error page with $title and $message
+ */
+function error_abort($title, $message)
+{
+   if ($title == "invalid") /* shortcut */
+   {
+      $title = "Invalid Feedback Submission";
+   }
+
+   echo ("  <title>Privoxy: $title</title>
+           </head>
+           <body>
+            <div class=\"title\">
+             <h1>
+              <a href=\"http://www.privoxy.org/\">Privoxy</a>: $title
+              </h1>
+             </div>
+            <center>
+             <div class=\"warning\">
+              $message
+             </div>
+            </center>
+            <p>Valid <a href=\"http://validator.w3.org/\">HTML 4.01 Transitional</a></p>
+           </body>
+          </html>\n");
+   exit; 
+}
+
+/* 
+ * Cannot start with step 2:
+ */
+if (!isset($referrer_url))
+{
+   error_abort("invalid", "When submitting your feedback please start with
+                <a href=\"index.php\">step 1</a>.");
+}
+
+
+/* 
+ * Cannot work on unknown problem:
+ */
+if (!isset($problem) || $problem == "INVALID")
+{
+   error_abort("invalid", "You need to select the nature of the problem in
+                <a href=\"javascript:history.back();\">step 1</a>.");
+}
+
+
+/*
+ * If the protocol is missing from $referrer_url, prepend "http://"
+ */
+if (!preg_match('|^https?://|i', $referrer_url, $dummy))
+{
+   $referrer_url = "http://" . $referrer_url;
+}
+
+
+/*
+ * Check if URL really exists and buffer its contents:
+ */
+if (($page = slurp_page($referrer_url)) == "FAILED")
+{
+   $url_confirm = "
+     <dt>
+      <p><b>Confirm the URL:</b></p>
+     </dt>
+     <dd>
+      <p>
+       The URL that you entered could not be retrieved. Please make sure that
+      </p>
+      <p class=\"important\">
+       <a href=\"$referrer_url\">$referrer_url</a>
+      </p>
+      <p>
+       is correct and publicly accssible.
+      </p>
+      <p>
+       <input type=\"checkbox\" name=\"url_confirmed\" value=\"user\"> Yes, I'm sure.
+      </p>
+     </dd>";
+}
+else
+{
+   $url_confirm = "<input type=\"hidden\" name=\"url_confirmed\" value=\"automatic\">";
+}
+
+/* 
+ * Create description from problem code:
+ */
+switch($problem)
+{
+   case "P1": $problem_description="an advertisment was not blocked"; break;
+   case "P2": $problem_description="an innocent image was blocked"; break;
+   case "P3": $problem_description="the whole page was erraneously blocked"; break;
+   case "P4": $problem_description="the page needs popups but they don't work"; break;
+   case "P5": $problem_description="a problem occured"; break;
+   default: $problem_description="AN UNPROCESSABLE PROBLEM OCCURED";
+}
+
+?>
+
+  <title>Privoxy Action List Feedback - Step 2 of 2</title>
+ </head>
+ <body>
+
+  <div class="title">
+   <h1>
+     <a href="http://www.privoxy.org" target="_blank">Privoxy</a> Action List Feedback - Step 2 of 2
+   </h1>
+  </div>
+
+  <div class="box">
+   <b>You are about to report that <?php echo ($problem_description) ?> on
+   <a href="<?php echo ($referrer_url) ?>"><?php echo ($referrer_url) ?></a>.</b>
+  </div>
+
+  <div class="box">
+   <form action="step3.php" method="post">
+    <p>
+     <input type="hidden" name="problem" value="<?php echo ($problem) ?>">
+     <input type="hidden" name="referrer_url" value="<?php echo ($referrer_url) ?>">
+    </p>
+
+    <dl>
+
+<?php
+
+/*
+ * Include the confirmation for an unretrievable URL if
+ * necessary
+ */
+echo ($url_confirm);
+
+/*
+ * Create / suppress form elements depending on type of
+ * problem
+ */
+if ($problem != "P1")
+{
+   echo ("<!--");
+}
+else
+{
+   $image_urls = get_image_urls($page, $referrer_url);
+   $count = count($image_urls);
+
+   if ($count > 0)
+   {
+      /*
+       * Open section in <dl>; Open table:
+       */
+      echo ("     <dt><b>Choose the images you want blocked from the following list:</b></dt>
+                  <dd>
+                   <p>
+                    <input type=\"hidden\" name=\"num_images\" value=\"$count\">
+                    <table border=\"0\" cellpadding=\"0\" cellspacing=\"4\">\n");
+      /*
+       * Print one table row for each image found:
+       */
+      for ($i=0; $i< $count; $i++)
+      {
+         $image_url = link_to_absolute($referrer_url, $image_urls[$i]);
+
+         /*
+          * Print the row(s):
+          */
+         echo ("       <tr>
+                        <td rowspan=\"2\">
+                         <input type=\"checkbox\" name=\"block_image[$i]\" value=\"off\">
+                        </td>
+                        <td>
+                         <a href=\"$image_url\">$image_url</a>:
+                        </td>
+                        <td>
+                         <input type=\"hidden\" name=\"image_url[$i]\" value=\"$image_url\">
+                        </td>
+                       </tr>
+                       <tr>
+                        <td>
+                         <img onload=\"prettyscale(this);\" src=\"$image_url\" alt=\"banner or not?\">
+                        </td>
+                       </tr>\n");
+      }
+      echo ("      </table>
+                  </dd>
+
+                  <dt>
+                   <b>If the banner that you saw is not listed above, enter the URL here</b>\n");
+   }
+   else
+   {
+      echo ("     <dt>
+                   <b>URL of the advertisment image:</b>\n");
+   }
+}
+
+?>
+
+      <br><i>Hint: right-click the image, select "Copy image location" and paste the URL here.</i>
+     </dt>
+     <dd>
+      <p>
+       <input name="manual_image_url" type="text" size="45" maxlength="255">
+      </p>
+     </dd>
+
+<?php if($problem != "P1") echo ("-->") ?>
+
+<?php if($problem != "P2") echo ("<!--") ?>
+
+     <dt>
+      <p><b>URL of the innocent image:</b>
+       <br><i>Hint: right-click the image, select "Copy image location" and paste the URL here.
+       <br>This may not work if the image was blocked by size or if +image-blocker is set to redirect.</i>
+      </p>
+     </dt>
+     <dd>
+      <p>
+       <input name="image_url" value="unknown" type="text" size="45" maxlength="255">
+      </p>
+     </dd>
+
+<?php if($problem != "P2") echo ("-->") ?>
+
+     <dt><b>Severity:</b></dt>
+     <dd>
+      <p>
+       <select name="severity">
+        <option value="3">drives me crazy</option>
+        <option selected value="2">normal</option>
+        <option value="1">cosmetic</option>
+       </select>
+      </p>
+     </dd>
+
+     <dt>
+      <b>Remarks:</b> <i>(optional)</i>
+     </dt>
+     <dd>
+      <p>
+       <textarea wrap="hard" style="font-size: 10px" name="remarks" cols="35" rows="3">None.</textarea>
+      </p>
+     </dd>
+
+     <dt>
+      <b>Your Name:</b> <i>(optional, public)</i>
+     </dt>
+     <dd>
+      <p>
+       <input name="name" size="45">
+      </p>
+     </dd>
+
+     <dt>&nbsp;</dt>
+     <dd>
+      <input type="submit" value="Submit">
+     </dd>
+
+    </dl>
+   </form>
+  </div>
+
+  <p>Valid <a href="http://validator.w3.org/">HTML 4.01 Transitional</a></p>
+
+ </body>
+</html>
diff --git a/doc/webserver/actions/step3.php b/doc/webserver/actions/step3.php
new file mode 100644 (file)
index 0000000..d3b6068
--- /dev/null
@@ -0,0 +1,345 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <!--
+
+  File :  $Source: /cvsroot/ijbswa/current/doc/webserver/actions/step3.php,v $
+
+  Purpose  :  Submit form for actions file feedback (step 1)
+              This file belongs in
+              ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+
+  $Id: step3.php,v 1.15 2002/04/09 15:08:10 oes Exp $
+
+  $Log: step3.php,v $
+  Revision 1.15  2002/04/09 15:08:10  oes
+  Restoring lost text change
+
+  Revision 1.14  2002/04/08 17:04:05  oes
+  Adapt to unified stylesheet
+
+  Revision 1.13  2002/04/07 17:11:40  oes
+  Tracker submit via curl (no need for user to see), fixing problems, removing monster comments
+
+  Revision 1.12  2002/04/06 18:57:38  swa
+  first version of the script that writes the
+  logfile with all submissions and additionally
+  submits the entries to our tracker.
+
+  Revision 1.11  2002/04/06 15:54:08  swa
+  prework: list of what needs to
+  be submitted to the tracker.
+
+  Revision 1.10  2002/04/06 15:19:35  oes
+  Clean-up, smarter handling of unreachable URLs
+
+  Revision 1.9  2002/04/06 11:34:44  oes
+  Cosmetics
+
+  Revision 1.8  2002/04/04 19:48:11  oes
+  Reactivating the scripts ,-)
+
+  Revision 1.7  2002/04/04 10:29:58  oes
+  Keeping feedback confidential
+
+  Revision 1.6  2002/04/03 19:36:04  swa
+  consistent look
+
+  Revision 1.5  2002/04/02 07:22:43  oes
+  Cosmetics
+
+  Revision 1.4  2002/04/01 19:13:47  oes
+  Extended, fixed bugs, beefed up design, made IE-safe
+
+  Revision 1.3  2002/03/30 20:44:46  swa
+  have consistent look and feel. part 2.
+  use correct urls.
+
+  Revision 1.2  2002/03/30 19:49:34  swa
+  have consistent look and feel
+
+  Revision 1.1  2002/03/30 03:20:30  oes
+  Added Feedback mechanism for actions file
+
+
+  Copyright (C) 2002 the SourceForge Privoxy team.
+  http://www.privoxy.org/
+
+  Written by Andreas Oesterhelt
+
+  This program is free software; you can redistribute it
+  and/or modify it under the terms of the GNU General
+  Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at
+  your option) any later version.
+
+  This program is distributed in the hope that it will
+  be useful, but WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  The GNU General Public License should be included with
+  this file.  If not, you can view it at
+  http://www.gnu.org/copyleft/gpl.html
+  or write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ -->
+
+ <head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <link rel="stylesheet" type="text/css" href="../privoxy.css">
+  <link rel="stylesheet" type="text/css" href="../p_feedback.css">
+
+<?php
+
+/* 
+ * Config:
+ */
+$logfile = "results/actions-feedback.txt";
+
+
+/* 
+ * Debug:
+ */
+//phpinfo();
+//error_reporting(E_ALL);
+error_reporting(E_NONE);
+
+/*
+ * Function: error_abort
+ * Purpose:  Return an error page with $title and $message
+ */
+function error_abort($title, $message)
+{
+   if ($title == "invalid") /* shortcut */
+   {
+      $title = "Invalid Feedback Submission";
+   }
+
+   echo ("  <title>Privoxy: $title</title>
+           </head>
+           <body>
+            <div class=\"title\">
+             <h1>
+              <a href=\"http://www.privoxy.org/\">Privoxy</a>: $title
+              </h1>
+             </div>
+            <center>
+             <div class=\"warning\">
+              $message
+             </div>
+            </center>
+            <p>Valid <a href=\"http://validator.w3.org/\">HTML 4.01 Transitional</a></p>
+           </body>
+          </html>\n");
+   exit; 
+}
+
+
+/* 
+ * Cannot start with step 3:
+ */
+if (!isset($referrer_url))
+{
+   error_abort("invalid", "When submitting your feedback please start with <a href=\"index.php\">step 1</a>.");
+}
+
+
+/* 
+ * Cannot work on unknown problem:
+ */
+if (!isset($problem))
+{
+   error_abort("invalid", "You need to select the nature of the problem in <a href=\"index.php\">step 1</a>.");
+}
+
+
+/* 
+ * Don't accept unconfirmed URLs
+ */
+if (!isset($url_confirmed))
+{
+   error_abort("invalid", "When submitting URLs that this script can't retrieve, you need to check \"Yes, I'm sure\"
+                <a href=\"javascript:history.back();\">step 2</a>.");
+}
+
+
+/*
+ * Handle optional text fields:
+ */
+if (!isset($name) || ($name == ""))
+{
+   $name = "anonymous";
+}
+
+/*
+ * Assign unique ID:
+ */
+$item_id = date("U");
+
+
+/* 
+ * Open the logfile or fail:
+ */
+$fp = fopen($logfile, "a");
+
+if(!$fp)
+{
+   echo ("  <title>Internal Script Error</title>
+           </head>
+           <body>
+            <div class=\"title\">
+              <h1><a href=\"http://www.privoxy.org/\">Privoxy</a>: Internal Script Error</h1>
+            </div>
+            <center>
+             <div class=\"warning\">
+              <p>
+               This script was unable to open its logfile.
+              </p>
+              <p>
+               Please <a href=\"mailto:info@privoxy.org?SUBJECT=Feedback-Script-Broken\">mail its owner</a>!
+              </p>
+             </div>
+            </center>
+           </body>
+          </html>");
+   exit; 
+}
+
+
+/*
+ * Write Head (type, severity, user, client-ip)
+ * and remarks field:
+ */
+fwrite($fp, "\n#FEEDBACK ID $item_id TYPE $problem SEVERITY $severity FROM $name ON $REMOTE_ADDR VERIFIED $url_confirmed TIME " . date("r") ."\n");
+if (isset($remarks))
+{
+   $lines = explode("\n", $remarks);
+   foreach ($lines as $line)
+   {
+      fwrite($fp, "#REMARKS: $line\n");
+   }
+}
+
+
+/*
+ * Depending on the type of problem reported,
+ * we need to write additional data:
+ */
+switch ($problem)
+{
+   /*
+    * Banner not blocked:
+    */
+   case "P1":
+      fwrite($fp, "#BLOCK-REFERRER: $referrer_url\n");
+      if (isset($num_images))
+      {
+         for($i=0; $i < $num_images; $i++)
+         {
+             if (isset($block_image[$i]))
+             {
+                fwrite($fp, "#BLOCK-URL: $image_url[$i]\n");
+                $trackertext .= "Block image: $image_url[$i]\n\n";
+             }
+         }
+      }
+      if (isset($manual_image_url) && ($manual_image_url != ""))
+      {
+         fwrite($fp, "#BLOCK-URL: $manual_image_url\n");
+         $trackertext .= "Block image: $manual_image_url\n\n";
+      }
+      break;
+
+   /*
+    * Innocent image blocked:
+    */
+   case "P2":
+      fwrite($fp, "#UNBLOCK-REFERRER: $referrer_url\n");
+      if (isset($image_url) && ($image_url != ""))
+      {
+         fwrite($fp, "#UNBLOCK-URL: $image_url\n");
+         $trackertext .= "Unblock image: $image_url\n\n";
+      }
+      break;
+
+   /*
+    * All other problems:
+    */
+   default:
+      fwrite($fp, "#PROBLEM-URL: $referrer_url\n");
+      break;
+}        
+            
+fclose($fp);
+
+/*
+ * Notify our SF tracker that new data is waiting to be
+ * processed
+ */
+switch($problem)
+{
+   case "P1": $category_id="412811"; $summary = "Ad not blocked "; break;
+   case "P2": $category_id="412810"; $summary = "Image blocked ";break;
+   case "P3": $category_id="412812"; $summary = "Page plocked ";break;
+   case "P4": $category_id="412813"; $summary = "Popups blocked ";break;
+   case "P5": $category_id="412814"; $summary = "Other problem ";break;
+   default:   $category_id="412814"; $summary = "IMPOSSIBLE ";break;
+}
+
+$summary .= "on " . $referrer_url . " (" .$item_id . ")";
+$priority = 3 * $severity;
+
+$details = urlencode("On " . date("r") . " new data was received from $name:\n\n"
+                    ."URL: $referrer_url\n\n$trackertext\nRemarks:\n$remarks");
+
+$postfields = ( "group_id=11118&atid=460288&func=postadd&category_id=$category_id&artifact_group_id=195890" .
+                "&priority=$priority&summary=$summary&details=$details" );
+
+$ch = curl_init ("http://sourceforge.net/tracker/index.php");
+curl_setopt($ch, CURLOPT_HEADER, 0);
+curl_setopt($ch, CURLOPT_FAILONERROR, 1);
+curl_setopt($ch, CURLOPT_TIMEOUT, 20);            
+curl_setopt($ch, CURLOPT_POST, 1);
+curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
+
+ob_start();
+curl_exec($ch);
+ob_end_clean();
+
+curl_close ($ch);
+
+?>
+
+  <title>Privoxy Action List Feedback - Result</title>
+ </head>
+
+ <body>
+  <div class="title">
+   <h1>
+    <a href="http://www.privoxy.org" target="_blank">Privoxy</a> Action List Feedback - Result
+   </h1>
+  </div>
+
+  <div class="box">
+   <p>
+    <b>Thank you very much for taking the time to submit your feedback!</b>
+   </p>
+
+   <p>
+    The developers will review and use your submission to improve the
+    distribution actions file.
+   </p>
+   
+   <p align=center>
+    <input type="submit" value="Close this window" onclick="window.close();">
+   </p>
+
+  </div>
+
+  <p>Valid <a href="http://validator.w3.org/">HTML 4.01 Transitional</a></p>
+
+ </body>
+</html>
diff --git a/doc/webserver/actions/testdrive.action b/doc/webserver/actions/testdrive.action
new file mode 100644 (file)
index 0000000..7e0250b
--- /dev/null
@@ -0,0 +1,164 @@
+#############################################################################
+#
+# Bare-bones actions file for Privoxy pre release testdrive
+#
+# For information, see http://www.oesterhelt.org/testdrive
+#
+#############################################################################
+{{alias}}
+# Useful aliases
++imageblock = +block +image
+
+# Fragile sites should have the minimum changes
+fragile     = -block -deanimate-gifs -fast-redirects -filter -hide-referer -no-cookies-keep -no-popups
+
+# Shops should be allowed to set persistent cookies
+shop        = -filter -no-cookies-keep
+
+#############################################################################
+# Defaults
+#############################################################################
+{\
+-add-header \
+-block \
++deanimate-gifs{last} \
+-downgrade \
++filter{html-annoyances} \
++filter{content-cookies} \
++filter{js-annoyances} \
++filter{no-popups} \
++filter{webbugs} \
++filter{nimda} \
++filter{banners-by-size} \
++no-compression \
++hide-forwarded \
++hide-from{block} \
++hide-referer{forge} \
+-hide-user-agent \
+-image \
++image-blocker{pattern} \
++no-cookies-keep \
+-no-cookies-read \
+-no-cookies-set \
++no-popups \
+-vanilla-wafer \
+-wafer \
+}
+/ # Match all URLs
+
+{+filter{noflash}}
+.moorhuhn.de
+[+filter{reorder}}
+.oesterhelt.org
+
+#############################################################################
+# Needed for automatic feedback evaluation; Please don't delete!
+#############################################################################
+{+add-header{X-Actions-File-Version: 1.2} -filter -no-popups}
+.privoxy.org/actions
+.oesterhelt.org/actions
+
+
+#############################################################################
+# These sites are very complex and require
+# minimal interference.
+#############################################################################
+{fragile}
+.office.microsoft.com
+.windowsupdate.microsoft.com
+
+#############################################################################
+# Shopping sites - still want to block ads.
+#############################################################################
+{shop}
+.quietpc.com
+.worldpay.com   # for quietpc.com
+.jungle.com
+.scan.co.uk
+
+#############################################################################
+# These shops require pop-ups
+#############################################################################
+{shop -no-popups -filter{no-poups}}
+.dabs.com
+.overclockers.co.uk
+
+#############################################################################
+# Sometimes fast-redirects catches things by mistake
+#############################################################################
+{-fast-redirects}
+www.ukc.ac.uk/cgi-bin/wac\.cgi\?
+login.yahoo.com
+edit.europe.yahoo.com
+.google.com
+.altavista.com/.*(like|url|link):http
+.altavista.com/trans.*urltext=http
+.speedfind.de
+.nytimes.com
+
+#############################################################################
+# Don't filter code!
+#############################################################################
+{-filter}
+.cvs.sourceforge.net
+
+#############################################################################
+# Imagelist:
+#############################################################################
+{+image}
+#############################################################################
+/.*\.(gif|jpe?g|png|bmp|ico)
+
+#############################################################################
+{+imageblock}
+#############################################################################
+#BLOCK-REFERRER: http://www.cnn.com/
+#BLOCK-REFERRER: http://www.aol.com/
+ar.atwola.com 
+
+#BLOCK-REFERRER: http://www.altavista.com/
+.ad.doubleclick.net
+
+#BLOCK-REFERRER: 
+bs*.gsanet.com
+bs*.einets.com
+
+#BLOCK-REFERRER: Opera browser built-in
+.qkimg.net
+
+#BLOCK-REFERRER: http://www.tecchannel.de/index.html
+#BLOCK-REFERRER: and thousands more
+ad.*.doubleclick.net
+
+#############################################################################
+# Blocklist:
+#############################################################################
+{+block}
+#############################################################################
+#BLOCK-GENERIC:
+ad*.
+.*ads.
+banner?.
+count*.
+
+/(?:.*/)?(ads(erver?|tream)?|.*?ads|adv(ert(s|enties|is(ing|e?ments)?)?)?|(ad)?[-_]?banner(s|ads?|farm)?)/
+/.*count(er)?\.(pl|cgi|exe|dll|asp|php[34]?)
+/(?:.*/)?(publicite|werbung|rekla(ma|me|am)|annonse|maino(kset|nta|s)?)/
+
+#BLOCK-REFERRER: http://www.brooksbrothers.com
+#BLOCK-REFERRER: http://www.autodesk.com
+.hitbox.com 
+
+#############################################################################
+{-block}
+#############################################################################
+include.ebay.com
+advogato.org
+adsl.
+ad[ud]*.
+advice.
+.edu
+.ac.uk
+.uni-*.de
+www.ugu.com/sui/ugu/adv
+.*downloads.
diff --git a/doc/webserver/config/.htaccess b/doc/webserver/config/.htaccess
new file mode 100644 (file)
index 0000000..f7d165f
--- /dev/null
@@ -0,0 +1,34 @@
+# http://ijbswa.sourceforge.net/config/.htaccess
+#
+# By Jon Foster
+#
+# Redirects any request for any file in this directory tree
+# to an error page.  The error page is reached through the
+# URL http://www.privoxy.org/config/ and is actually in
+# the file index.php
+#
+# Uses Apache's mod_rewrite
+# See http://httpd.apache.org/docs/mod/mod_rewrite.html
+#
+
+# Enable mod_rewrite
+RewriteEngine on
+
+# we are reached via /config/ prefix
+RewriteBase   /config/
+
+# The only file which really exists is index.php - allow this
+RewriteCond %{HTTP_HOST}   ^www\.privoxy\.org\.?$ [NC,OR]
+RewriteCond %{HTTP_HOST}   ^$
+RewriteRule  index.php - [L]
+
+# Silently redirect the config dir to index.php
+RewriteCond %{HTTP_HOST}   ^www\.privoxy\.org\.?$ [NC,OR]
+RewriteCond %{HTTP_HOST}   ^$
+RewriteRule  ^$      index.php [L]
+
+# anything else gets redirected to the config dir, and we update
+# the browser's location bar.
+RewriteRule  ^(.*)$  http://www.privoxy.org/config/  [R,L]
+
+
diff --git a/doc/webserver/config/index.php b/doc/webserver/config/index.php
new file mode 100644 (file)
index 0000000..f7ef30e
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<!--
+
+  File        :  $Source: /cvsroot/ijbswa/current/doc/webserver/config/index.php,v $
+
+  Purpose     :  Warn user of incorrect configuration.
+                 This file belongs in
+                 ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+
+  $Id: index.php,v 1.3 2002/04/03 19:41:11 swa Exp $
+
+  Written by and Copyright (C) 2001 the SourceForge
+  Privoxy team. http://www.privoxy.org/
+
+  Based on the Internet Junkbuster originally written
+  by and Copyright (C) 1997 Anonymous Coders and
+  Junkbusters Corporation.  http://www.junkbusters.com
+
+  This program is free software; you can redistribute it
+  and/or modify it under the terms of the GNU General
+  Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at
+  your option) any later version.
+
+  This program is distributed in the hope that it will
+  be useful, but WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  The GNU General Public License should be included with
+  this file.  If not, you can view it at
+  http://www.gnu.org/copyleft/gpl.html
+  or write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+-->
+
+<html><head>
+<title>Privoxy not running</title>
+    <link rel="stylesheet" type="text/css" href="../p_web.css">
+</head>
+
+<body>
+
+<h1>Privoxy isn't working</h1>
+
+<p>If you were redirected to this page, it means that you aren't using
+<a href="http://privoxy.org/">Privoxy</a>. &nbsp; Please check your browser settings.</p>
+
+<p>Until version 2.9.13, Privoxy was also known as Internet
+Junkbuster. If you recently upgraded, then the web-based interface has
+moved - it is now at <a
+href="http://config.privoxy.org/">http://config.privoxy.org/</a>
+(Short form: <a href="http://ijbswa.sourceforge.net/config/">p.p</a>
+[Privoxy Proxy]).</p>
+
+<p>Please see the <a href="http://privoxy.org/">Privoxy home page</a>.</p>
+
+</body>
+</html>
+
diff --git a/doc/webserver/default_page.php b/doc/webserver/default_page.php
new file mode 100644 (file)
index 0000000..75a4fdc
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+// Default Web Page for groups that haven't setup their page yet
+// Please replace this file with your own website
+//
+// $Id: default_page.php,v 1.2 2000/01/07 18:11:56 precision Exp $
+//
+$headers = getallheaders();
+?>
+<HTML>
+<HEAD>
+<TITLE>SourceForge: Welcome</TITLE>
+<LINK rel="stylesheet" href="http://sourceforge.net/sourceforge.css" type="text/css">
+</HEAD>
+
+<BODY bgcolor=#FFFFFF topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0">
+
+<!-- top strip -->
+<TABLE width="100%" border=0 cellspacing=0 cellpadding=2 bgcolor="737b9c">
+  <TR>
+    <TD><SPAN class=maintitlebar>&nbsp;&nbsp;
+      <A class=maintitlebar href="http://sourceforge.net/"><B>Home</B></A> | 
+      <A class=maintitlebar href="http://sourceforge.net/about.php"><B>About</B></A> | 
+      <A class=maintitlebar href="http://sourceforge.net/partners.php"><B>Partners</B></a> |
+      <A class=maintitlebar href="http://sourceforge.net/contact.php"><B>Contact Us</B></A></SPAN></TD>
+    </TD>
+  </TR>
+</TABLE>
+<!-- end top strip -->
+
+<!-- top title table -->
+<TABLE width="100%" border=0 cellspacing=0 cellpadding=0 bgcolor="" valign="center">
+  <TR valign="top" bgcolor="#eeeef8">
+    <TD>
+      <A href="http://sourceforge.net/"><IMG src="http://sourceforge.net/images/sflogo2-steel.png" vspace="0" border=0 width="143" height="70"></A>
+    </TD>
+    <TD width="99%"><!-- right of logo -->
+      <a href="http://www.valinux.com"><IMG src="http://sourceforge.net/images/valogo3.png" align="right" alt="VA Linux Systems" hspace="5" vspace="0" border=0 width="117" height="70"></A>
+    </TD><!-- right of logo -->
+  </TR>
+  <TR><TD bgcolor="#543a48" colspan=2><IMG src="http://sourceforge.net/images/blank.gif" height=2 vspace=0></TD></TR>
+</TABLE>
+<!-- end top title table -->
+
+<!-- center table -->
+<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="#FFFFFF" align="center">
+  <TR>
+    <TD>
+      <CENTER><BR>
+      <H1>Welcome to http://<?php print $headers[Host]; ?>/</H1>
+      <P>We're Sorry but this Project hasn't yet uploaded their personal webpage yet.<BR>
+      Please check back soon for updates or visit <A href="http://sourceforge.net/">SourceForge</A></P><BR>
+      </CENTER>
+    </TD>
+  </TR>
+</TABLE>
+<!-- end center table -->
+
+<!-- footer table -->
+<TABLE width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="737b9c">
+  <TR>
+    <TD align="center"><FONT color="#ffffff"><SPAN class="titlebar">
+      All trademarks and copyrights on this page are properties of their respective owners. Forum comments are owned by the poster. The rest is copyright Â©1999-2000 VA Linux Systems, Inc.</SPAN></FONT>
+    </TD>
+  </TR>
+</TABLE>
+
+<!-- end footer table -->
+</BODY>
+</HTML>
diff --git a/doc/webserver/developer-manual/coding.html b/doc/webserver/developer-manual/coding.html
new file mode 100644 (file)
index 0000000..364af8e
--- /dev/null
@@ -0,0 +1,2266 @@
+<HTML
+><HEAD
+><TITLE
+>Coding Guidelines</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Documentation Guidelines"
+HREF="documentation.html"><LINK
+REL="NEXT"
+TITLE="Testing Guidelines"
+HREF="testing.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="documentation.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="testing.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CODING"
+>4. Coding Guidelines</A
+></H1
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S1"
+>4.1. Introduction</A
+></H2
+><P
+>This set of standards is designed to make our lives easier.  It is
+    developed with the simple goal of helping us keep the "new and improved
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>" consistent and reliable. Thus making
+    maintenance easier and increasing chances of success of the
+    project.</P
+><P
+>And that of course comes back to us as individuals. If we can
+    increase our development and product efficiencies then we can solve more
+    of the request for changes/improvements and in general feel good about
+    ourselves. ;-&#62;</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S2"
+>4.2. Using Comments</A
+></H2
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S3"
+>4.2.1. Comment, Comment, Comment</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Comment as much as possible without commenting the obvious.
+    For example do not comment "aVariable is equal to bVariable".
+    Instead explain why aVariable should be equal to the bVariable.
+    Just because a person can read code does not mean they will
+    understand why or what is being done. A reader may spend a lot
+    more time figuring out what is going on when a simple comment
+    or explanation would have prevented the extra research. Please
+    help your brother IJB'ers out!</P
+><P
+>The comments will also help justify the intent of the code.
+    If the comment describes something different than what the code
+    is doing then maybe a programming error is occurring.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>/* if page size greater than 1k ... */
+if ( PageLength() &#62; 1024 )
+{
+    ... "block" the page up ...
+}
+
+/* if page size is small, send it in blocks */
+if ( PageLength() &#62; 1024 )
+{
+    ... "block" the page up ...
+}
+
+This demonstrates 2 cases of "what not to do".  The first is a
+"syntax comment".  The second is a comment that does not fit what
+is actually being done.</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S4"
+>4.2.2. Use blocks for comments</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Comments can help or they can clutter. They help when they
+    are differentiated from the code they describe. One line
+    comments do not offer effective separation between the comment
+    and the code. Block identifiers do, by surrounding the code
+    with a clear, definable pattern.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>/*********************************************************************
+ * This will stand out clearly in your code!
+ *********************************************************************/
+if ( thisVariable == thatVariable )
+{
+   DoSomethingVeryImportant();
+}
+
+
+/* unfortunately, this may not */
+if ( thisVariable == thatVariable )
+{
+   DoSomethingVeryImportant();
+}
+
+
+if ( thisVariable == thatVariable ) /* this may not either */
+{
+   DoSomethingVeryImportant();
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Exception:</I
+></P
+><P
+>If you are trying to add a small logic comment and do not
+    wish to "disrupt" the flow of the code, feel free to use a 1
+    line comment which is NOT on the same line as the code.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S5"
+>4.2.3. Keep Comments on their own line</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>It goes back to the question of readability. If the comment
+    is on the same line as the code it will be harder to read than
+    the comment that is on its own line.</P
+><P
+>There are three exceptions to this rule, which should be
+    violated freely and often: during the definition of variables,
+    at the end of closing braces, when used to comment
+    parameters.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>/*********************************************************************
+ * This will stand out clearly in your code,
+ * But the second example won't.
+ *********************************************************************/
+if ( thisVariable == thatVariable )
+{
+   DoSomethingVeryImportant();
+}
+
+if ( thisVariable == thatVariable ) /*can you see me?*/
+{
+   DoSomethingVeryImportant(); /*not easily*/
+}
+
+
+/*********************************************************************
+ * But, the encouraged exceptions:
+ *********************************************************************/
+int urls_read     = 0;     /* # of urls read + rejected */
+int urls_rejected = 0;     /* # of urls rejected */
+
+if ( 1 == X )
+{
+   DoSomethingVeryImportant();
+}
+
+
+short DoSomethingVeryImportant(
+   short firstparam,   /* represents something */
+   short nextparam     /* represents something else */ )
+{
+   ...code here...
+
+}   /* -END- DoSomethingVeryImportant */</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S6"
+>4.2.4. Comment each logical step</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Logical steps should be commented to help others follow the
+    intent of the written code and comments will make the code more
+    readable.</P
+><P
+>If you have 25 lines of code without a comment, you should
+    probably go back into it to see where you forgot to put
+    one.</P
+><P
+>Most "for", "while", "do", etc... loops _probably_ need a
+    comment. After all, these are usually major logic
+    containers.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S7"
+>4.2.5. Comment All Functions Thoroughly</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>A reader of the code should be able to look at the comments
+    just prior to the beginning of a function and discern the
+    reason for its existence and the consequences of using it. The
+    reader should not have to read through the code to determine if
+    a given function is safe for a desired use. The proper
+    information thoroughly presented at the introduction of a
+    function not only saves time for subsequent maintenance or
+    debugging, it more importantly aids in code reuse by allowing a
+    user to determine the safety and applicability of any function
+    for the problem at hand. As a result of such benefits, all
+    functions should contain the information presented in the
+    addendum section of this document.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S8"
+>4.2.6. Comment at the end of braces if the
+    content is more than one screen length</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Each closing brace should be followed on the same line by a
+    comment that describes the origination of the brace if the
+    original brace is off of the screen, or otherwise far away from
+    the closing brace. This will simplify the debugging,
+    maintenance, and readability of the code.</P
+><P
+>As a suggestion , use the following flags to make the
+    comment and its brace more readable:</P
+><P
+>use following a closing brace: } /* -END- if() or while ()
+    or etc... */</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>if ( 1 == X )
+{
+   DoSomethingVeryImportant();
+   ...some long list of commands...
+} /* -END- if x is 1 */
+
+or:
+
+if ( 1 == X )
+{
+   DoSomethingVeryImportant();
+   ...some long list of commands...
+} /* -END- if ( 1 == X ) */</PRE
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S9"
+>4.3. Naming Conventions</A
+></H2
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S10"
+>4.3.1. Variable Names</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Use all lowercase, and separate words via an underscore
+    ('_'). Do not start an identifier with an underscore. (ANSI C
+    reserves these for use by the compiler and system headers.) Do
+    not use identifiers which are reserved in ANSI C++. (E.g.
+    template, class, true, false, ...). This is in case we ever
+    decide to port Privoxy to C++.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>int ms_iis5_hack = 0;</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>int msiis5hack = 0; int msIis5Hack = 0;</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S11"
+>4.3.2. Function Names</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Use all lowercase, and separate words via an underscore
+    ('_'). Do not start an identifier with an underscore. (ANSI C
+    reserves these for use by the compiler and system headers.) Do
+    not use identifiers which are reserved in ANSI C++. (E.g.
+    template, class, true, false, ...). This is in case we ever
+    decide to port Privoxy to C++.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>int load_some_file( struct client_state *csp )</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>int loadsomefile( struct client_state *csp )
+int loadSomeFile( struct client_state *csp )</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S12"
+>4.3.3. Header file prototypes</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Use a descriptive parameter name in the function prototype
+    in header files. Use the same parameter name in the header file
+    that you use in the c file.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>(.h) extern int load_aclfile( struct client_state *csp );
+(.c) int load_aclfile( struct client_state *csp )</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+>
+<TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>(.h) extern int load_aclfile( struct client_state * ); or 
+(.h) extern int load_aclfile(); 
+(.c) int load_aclfile( struct client_state *csp )</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S13"
+>4.3.4. Enumerations, and #defines</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Use all capital letters, with underscores between words. Do
+    not start an identifier with an underscore. (ANSI C reserves
+    these for use by the compiler and system headers.)</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>(enumeration) : enum Boolean { FALSE, TRUE };
+(#define) : #define DEFAULT_SIZE 100;</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> We have a standard naming scheme for #defines
+    that toggle a feature in the preprocessor: FEATURE_&#62;, where
+    &#62; is a short (preferably 1 or 2 word) description.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#define FEATURE_FORCE 1
+
+#ifdef FEATURE_FORCE
+#define FORCE_PREFIX blah
+#endif /* def FEATURE_FORCE */</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S14"
+>4.3.5. Constants</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Spell common words out entirely (do not remove vowels).</P
+><P
+>Use only widely-known domain acronyms and abbreviations.
+    Capitalize all letters of an acronym.</P
+><P
+>Use underscore (_) to separate adjacent acronyms and
+    abbreviations. Never terminate a name with an underscore.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#define USE_IMAGE_LIST 1</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#define USE_IMG_LST 1 or 
+#define _USE_IMAGE_LIST 1 or
+#define USE_IMAGE_LIST_ 1 or 
+#define use_image_list 1 or
+#define UseImageList 1</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S15"
+>4.4. Using Space</A
+></H2
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S16"
+>4.4.1. Put braces on a line by themselves.</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>The brace needs to be on a line all by itself, not at the
+    end of the statement. Curly braces should line up with the
+    construct that they're associated with. This practice makes it
+    easier to identify the opening and closing braces for a
+    block.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>if ( this == that )
+{
+   ...
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+>if ( this == that ) { ... }</P
+><P
+>or</P
+><P
+>if ( this == that ) { ... }</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> In the special case that the if-statement is
+    inside a loop, and it is trivial, i.e. it tests for a
+    condition that is obvious from the purpose of the block,
+    one-liners as above may optically preserve the loop structure
+    and make it easier to read.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> developer-discretion.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example exception:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>while ( more lines are read )
+{
+   /* Please document what is/is not a comment line here */
+   if ( it's a comment ) continue;
+
+   do_something( line );
+}</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S17"
+>4.4.2. ALL control statements should have a
+    block</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Using braces to make a block will make your code more
+    readable and less prone to error. All control statements should
+    have a block defined.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>if ( this == that )
+{
+   DoSomething();
+   DoSomethingElse();
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+>if ( this == that ) DoSomething(); DoSomethingElse();</P
+><P
+>or</P
+><P
+>if ( this == that ) DoSomething();</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> The first example in "Instead of" will execute
+    in a manner other than that which the developer desired (per
+    indentation). Using code braces would have prevented this
+    "feature". The "explanation" and "exception" from the point
+    above also applies.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S18"
+>4.4.3. Do not belabor/blow-up boolean
+    expressions</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>structure-&#62;flag = ( condition );</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+>if ( condition ) { structure-&#62;flag = 1; } else {
+    structure-&#62;flag = 0; }</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> The former is readable and concise. The later
+    is wordy and inefficient. Please assume that any developer new
+    to the project has at least a "good" knowledge of C/C++. (Hope
+    I do not offend by that last comment ... 8-)</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S19"
+>4.4.4. Use white space freely because it is
+    free</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Make it readable. The notable exception to using white space
+    freely is listed in the next guideline.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>int firstValue   = 0;
+int someValue    = 0;
+int anotherValue = 0;
+int thisVariable = 0;
+
+if ( thisVariable == thatVariable )
+
+firstValue = oldValue + ( ( someValue - anotherValue ) - whatever )</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S20"
+>4.4.5. Don't use white space around structure
+    operators</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>- structure pointer operator ( "-&#62;" ) - member operator (
+    "." ) - functions and parentheses</P
+><P
+>It is a general coding practice to put pointers, references,
+    and function parentheses next to names. With spaces, the
+    connection between the object and variable/function name is not
+    as clear.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>aStruct-&#62;aMember;
+aStruct.aMember;
+FunctionName();</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+> aStruct -&#62; aMember; aStruct . aMember;
+    FunctionName ();</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S21"
+>4.4.6. Make the last brace of a function stand
+    out</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>int function1( ... )
+{
+   ...code...
+   return( retCode );
+
+}   /* -END- function1 */
+
+
+int function2( ... )
+{
+}   /* -END- function2 */</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+>int function1( ... ) { ...code... return( retCode ); } int
+    function2( ... ) { }</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> Use 1 blank line before the closing brace and 2
+    lines afterward. This makes the end of function standout to
+    the most casual viewer. Although function comments help
+    separate functions, this is still a good coding practice. In
+    fact, I follow these rules when using blocks in "for", "while",
+    "do" loops, and long if {} statements too. After all whitespace
+    is free!</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> developer-discretion on the number of blank
+    lines. Enforced is the end of function comments.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S22"
+>4.4.7. Use 3 character indentions</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>If some use 8 character TABs and some use 3 character TABs,
+    the code can look *very* ragged. So use 3 character indentions
+    only. If you like to use TABs, pass your code through a filter
+    such as "expand -t3" before checking in your code.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>static const char * const url_code_map[256] =
+{
+   NULL, ...
+};
+
+
+int function1( ... )
+{
+   if ( 1 )
+   {
+      return( ALWAYS_TRUE );
+   }
+   else
+   {
+      return( HOW_DID_YOU_GET_HERE );
+   }
+
+   return( NEVER_GETS_HERE );
+
+}</PRE
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S23"
+>4.5. Initializing</A
+></H2
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S24"
+>4.5.1. Initialize all variables</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Do not assume that the variables declared will not be used
+    until after they have been assigned a value somewhere else in
+    the code. Remove the chance of accidentally using an unassigned
+    variable.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>short anShort = 0;
+float aFloat  = 0;
+struct *ptr = NULL;</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> It is much easier to debug a SIGSEGV if the
+    message says you are trying to access memory address 00000000
+    and not 129FA012; or arrayPtr[20] causes a SIGSEV vs.
+    arrayPtr[0].</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> developer-discretion if and only if the
+    variable is assigned a value "shortly after" declaration.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S25"
+>4.6. Functions</A
+></H2
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S26"
+>4.6.1. Name functions that return a boolean as a
+    question.</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Value should be phrased as a question that would logically
+    be answered as a true or false statement</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>ShouldWeBlockThis();
+ContainsAnImage();
+IsWebPageBlank();</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S27"
+>4.6.2. Always specify a return type for a
+    function.</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>The default return for a function is an int. To avoid
+    ambiguity, create a return for a function when the return has a
+    purpose, and create a void return type if the function does not
+    need to return anything.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S28"
+>4.6.3. Minimize function calls when iterating by
+    using variables</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>It is easy to write the following code, and a clear argument
+    can be made that the code is easy to understand:</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>for ( size_t cnt = 0; cnt &#60; blockListLength(); cnt ++ )
+{
+   ....
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> Unfortunately, this makes a function call for
+    each and every iteration. This increases the overhead in the
+    program, because the compiler has to look up the function each
+    time, call it, and return a value. Depending on what occurs in
+    the blockListLength() call, it might even be creating and
+    destroying structures with each iteration, even though in each
+    case it is comparing "cnt" to the same value, over and over.
+    Remember too - even a call to blockListLength() is a function
+    call, with the same overhead.</P
+><P
+>Instead of using a function call during the iterations,
+    assign the value to a variable, and evaluate using the
+    variable.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>size_t len = blockListLength();
+
+for ( size_t cnt = 0; cnt &#60; len; cnt ++ )
+{
+   ....
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Exceptions:</I
+> if the value of blockListLength() *may*
+    change or could *potentially* change, then you must code the
+    function call in the for/while loop.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S29"
+>4.6.4. Pass and Return by Const Reference</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>This allows a developer to define a const pointer and call
+    your function. If your function does not have the const
+    keyword, we may not be able to use your function. Consider
+    strcmp, if it were defined as: extern int strcmp( char *s1,
+    char *s2 );</P
+><P
+>I could then not use it to compare argv's in main: int main(
+    int argc, const char *argv[] ) { strcmp( argv[0], "privoxy"
+    ); }</P
+><P
+>Both these pointers are *const*! If the c runtime library
+    maintainers do it, we should too.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S30"
+>4.6.5. Pass and Return by Value</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Most structures cannot fit onto a normal stack entry (i.e.
+    they are not 4 bytes or less). Aka, a function declaration
+    like: int load_aclfile( struct client_state csp )</P
+><P
+>would not work. So, to be consistent, we should declare all
+    prototypes with "pass by value": int load_aclfile( struct
+    client_state *csp )</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S31"
+>4.6.6. Names of include files</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Your include statements should contain the file name without
+    a path. The path should be listed in the Makefile, using -I as
+    processor directive to search the indicated paths. An exception
+    to this would be for some proprietary software that utilizes a
+    partial path to distinguish their header files from system or
+    other header files.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#include &#60;iostream.h&#62;     /* This is not a local include */
+#include "config.h"       /* This IS a local include */</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Exception:</I
+></P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>/* This is not a local include, but requires a path element. */ 
+#include &#60;sys/fileName.h&#62;</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> Please! do not add "-I." to the Makefile
+    without a _very_ good reason. This duplicates the #include
+    "file.h" behavior.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S32"
+>4.6.7. Provide multiple inclusion
+    protection</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Prevents compiler and linker errors resulting from
+    redefinition of items.</P
+><P
+>Wrap each header file with the following syntax to prevent
+    multiple inclusions of the file. Of course, replace PROJECT_H
+    with your file name, with "." Changed to "_", and make it
+    uppercase.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#ifndef PROJECT_H_INCLUDED
+#define PROJECT_H_INCLUDED
+ ...
+#endif /* ndef PROJECT_H_INCLUDED */</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S33"
+>4.6.8. Use `extern "C"` when appropriate</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>If our headers are included from C++, they must declare our
+    functions as `extern "C"`. This has no cost in C, but increases
+    the potential re-usability of our code.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#ifdef __cplusplus
+extern "C"
+{
+#endif /* def __cplusplus */
+
+... function definitions here ...
+
+#ifdef __cplusplus
+}
+#endif /* def __cplusplus */</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S34"
+>4.6.9. Where Possible, Use Forward Struct
+    Declaration Instead of Includes</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Useful in headers that include pointers to other struct's.
+    Modifications to excess header files may cause needless
+    compiles.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>/*********************************************************************
+ * We're avoiding an include statement here!
+ *********************************************************************/
+struct file_list;
+extern file_list *xyz;</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> If you declare "file_list xyz;" (without the
+    pointer), then including the proper header file is necessary.
+    If you only want to prototype a pointer, however, the header
+    file is unnecessary.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> Use with discretion.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S35"
+>4.7. General Coding Practices</A
+></H2
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S36"
+>4.7.1. Turn on warnings</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation</I
+></P
+><P
+>Compiler warnings are meant to help you find bugs. You
+    should turn on as many as possible. With GCC, the switch is
+    "-Wall". Try and fix as many warnings as possible.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S37"
+>4.7.2. Provide a default case for all switch
+    statements</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>What you think is guaranteed is never really guaranteed. The
+    value that you don't think you need to check is the one that
+    someday will be passed. So, to protect yourself from the
+    unknown, always have a default step in a switch statement.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>switch( hash_string( cmd ) )
+{
+   case hash_actions_file :
+      ... code ...
+      break;
+
+   case hash_confdir :
+      ... code ...
+      break;
+
+   default :
+      log_error( ... );
+      ... anomaly code goes here ...
+      continue; / break; / exit( 1 ); / etc ...
+
+} /* end switch( hash_string( cmd ) ) */</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> If you already have a default condition, you
+    are obviously exempt from this point. Of note, most of the
+    WIN32 code calls `DefWindowProc' after the switch statement.
+    This API call *should* be included in a default statement.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Another Note:</I
+> This is not so much a readability issue
+    as a robust programming issue. The "anomaly code goes here" may
+    be no more than a print to the STDERR stream (as in
+    load_config). Or it may really be an ABEND condition.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> Programmer discretion is advised.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S38"
+>4.7.3. Try to avoid falling through cases in a
+    switch statement.</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>In general, you will want to have a 'break' statement within
+    each 'case' of a switch statement. This allows for the code to
+    be more readable and understandable, and furthermore can
+    prevent unwanted surprises if someone else later gets creative
+    and moves the code around.</P
+><P
+>The language allows you to plan the fall through from one
+    case statement to another simply by omitting the break
+    statement within the case statement. This feature does have
+    benefits, but should only be used in rare cases. In general,
+    use a break statement for each case statement.</P
+><P
+>If you choose to allow fall through, you should comment both
+    the fact of the fall through and reason why you felt it was
+    necessary.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S39"
+>4.7.4. Use 'long' or 'short' Instead of
+    'int'</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>On 32-bit platforms, int usually has the range of long. On
+    16-bit platforms, int has the range of short.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> open-to-debate. In the case of most FSF
+    projects (including X/GNU-Emacs), there are typedefs to int4,
+    int8, int16, (or equivalence ... I forget the exact typedefs
+    now). Should we add these to IJB now that we have a "configure"
+    script?</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S40"
+>4.7.5. Don't mix size_t and other types</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>The type of size_t varies across platforms. Do not make
+    assumptions about whether it is signed or unsigned, or about
+    how long it is. Do not compare a size_t against another
+    variable of a different type (or even against a constant)
+    without casting one of the values. Try to avoid using size_t if
+    you can.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S41"
+>4.7.6. Declare each variable and struct on its
+    own line.</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>It can be tempting to declare a series of variables all on
+    one line. Don't.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>long a = 0;
+long b = 0;
+long c = 0;</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Instead of:</I
+></P
+><P
+>long a, b, c;</P
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+> - there is more room for comments on the
+    individual variables - easier to add new variables without
+    messing up the original ones - when searching on a variable to
+    find its type, there is less clutter to "visually"
+    eliminate</P
+><P
+><I
+CLASS="EMPHASIS"
+>Exceptions:</I
+> when you want to declare a bunch of loop
+    variables or other trivial variables; feel free to declare them
+    on 1 line. You should, although, provide a good comment on
+    their functions.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> developer-discretion.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S42"
+>4.7.7. Use malloc/zalloc sparingly</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>Create a local struct (on the stack) if the variable will
+    live and die within the context of one function call.</P
+><P
+>Only "malloc" a struct (on the heap) if the variable's life
+    will extend beyond the context of one function call.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>If a function creates a struct and stores a pointer to it in a
+list, then it should definitely be allocated via `malloc'.</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S43"
+>4.7.8. The Programmer Who Uses 'malloc' is
+    Responsible for Ensuring 'free'</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>If you have to "malloc" an instance, you are responsible for
+    insuring that the instance is `free'd, even if the deallocation
+    event falls within some other programmer's code. You are also
+    responsible for ensuring that deletion is timely (i.e. not too
+    soon, not too late). This is known as "low-coupling" and is a
+    "good thing (tm)". You may need to offer a
+    free/unload/destuctor type function to accommodate this.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>int load_re_filterfile( struct client_state *csp ) { ... }
+static void unload_re_filterfile( void *f ) { ... }</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Exceptions:</I
+></P
+><P
+>The developer cannot be expected to provide `free'ing
+    functions for C run-time library functions ... such as
+    `strdup'.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Status:</I
+> developer-discretion. The "main" use of this
+    standard is for allocating and freeing data structures (complex
+    or nested).</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S44"
+>4.7.9. Add loaders to the `file_list' structure
+    and in order</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>I have ordered all of the "blocker" file code to be in alpha
+    order. It is easier to add/read new blockers when you expect a
+    certain order.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> It may appear that the alpha order is broken in
+    places by POPUP tests coming before PCRS tests. But since
+    POPUPs can also be referred to as KILLPOPUPs, it is clear that
+    it should come first.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="S45"
+>4.7.10. "Uncertain" new code and/or changes to
+    existing code, use FIXME</A
+></H3
+><P
+><I
+CLASS="EMPHASIS"
+>Explanation:</I
+></P
+><P
+>If you have enough confidence in new code or confidence in
+    your changes, but are not *quite* sure of the repercussions,
+    add this:</P
+><P
+>/* FIXME: this code has a logic error on platform XYZ, *
+    attempting to fix */ #ifdef PLATFORM ...changed code here...
+    #endif</P
+><P
+>or:</P
+><P
+>/* FIXME: I think the original author really meant this...
+    */ ...changed code here...</P
+><P
+>or:</P
+><P
+>/* FIXME: new code that *may* break something else... */
+    ...new code here...</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> If you make it clear that this may or may not
+    be a "good thing (tm)", it will be easier to identify and
+    include in the project (or conversely exclude from the
+    project).</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="S46"
+>4.8. Addendum: Template for files and function
+    comment blocks:</A
+></H2
+><P
+><I
+CLASS="EMPHASIS"
+>Example for file comments:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>const char FILENAME_rcs[] = "$Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source$
+ *
+ * Purpose     :  (Fill me in with a good description!)
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log$
+ *
+ *********************************************************************/
+
+
+#include "config.h"
+
+   ...necessary include files for us to do our work...
+
+const char FILENAME_h_rcs[] = FILENAME_H_VERSION;</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> This declares the rcs variables that should be
+    added to the "show-proxy-args" page. If this is a brand new
+    creation by you, you are free to change the "Copyright" section
+    to represent the rights you wish to maintain.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> The formfeed character that is present right
+    after the comment flower box is handy for (X|GNU)Emacs users to
+    skip the verbiage and get to the heart of the code (via
+    `forward-page' and `backward-page'). Please include it if you
+    can.</P
+><P
+><I
+CLASS="EMPHASIS"
+>Example for file header comments:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>#ifndef _FILENAME_H
+#define _FILENAME_H
+#define FILENAME_H_VERSION "$Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source$
+ *
+ * Purpose     :  (Fill me in with a good description!)
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log$
+ *
+ *********************************************************************/
+
+
+#include "project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+   ... function headers here ...
+
+
+/* Revision control strings from this header and associated .c file */
+extern const char FILENAME_rcs[];
+extern const char FILENAME_h_rcs[];
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef _FILENAME_H */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Example for function comments:</I
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>/*********************************************************************
+ *
+ * Function    :  FUNCTION_NAME
+ *
+ * Description :  (Fill me in with a good description!)
+ *
+ * parameters  :
+ *          1  :  param1 = pointer to an important thing
+ *          2  :  x      = pointer to something else
+ *
+ * Returns     :  0 =&#62; Ok, everything else is an error.
+ *
+ *********************************************************************/
+int FUNCTION_NAME( void *param1, const char *x )
+{
+   ...
+   return( 0 );
+
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+><I
+CLASS="EMPHASIS"
+>Note:</I
+> If we all follow this practice, we should be
+    able to parse our code to create a "self-documenting" web
+    page.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="documentation.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="testing.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Documentation Guidelines</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Testing Guidelines</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/contact.html b/doc/webserver/developer-manual/contact.html
new file mode 100644 (file)
index 0000000..c911235
--- /dev/null
@@ -0,0 +1,309 @@
+<HTML
+><HEAD
+><TITLE
+>Contacting the developers, Bug Reporting and Feature Requests</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Update the Webserver"
+HREF="webserver-update.html"><LINK
+REL="NEXT"
+TITLE="Privoxy Copyright, License and History"
+HREF="copyright.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="webserver-update.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="copyright.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CONTACT"
+>8. Contacting the developers, Bug Reporting and Feature Requests</A
+></H1
+><P
+> We value your feedback. In fact, we rely on it to improve
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> and its configuration.
+ However, please note the following hints, so we can 
+ provide you with the best support:</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-SUPPORT"
+>8.1. Get Support</A
+></H2
+><P
+> For casual users, our support forum at
+ <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>SourceForge</A
+>
+ is probably best suited:
+ <A
+HREF="http://sourceforge.net/tracker/?group_id=11118&atid=211118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?group_id=11118&#38;atid=211118</A
+></P
+><P
+> All users are of course welcome to discuss their issues on the <A
+HREF="http://lists.sourceforge.net/lists/listinfo/ijbswa-users"
+TARGET="_top"
+>users
+ mailing list</A
+>, where the developers also hang around.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-BUGS"
+>8.2. Report Bugs</A
+></H2
+><P
+> Please report all bugs <I
+CLASS="EMPHASIS"
+>only</I
+> through our
+ bug tracker: 
+ <A
+HREF="http://sourceforge.net/tracker/?group_id=11118&atid=111118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?group_id=11118&#38;atid=111118</A
+>. </P
+><P
+>  Before doing so, please make sure that the bug has not already been submitted
+  and observe the aditional hints at the top of the <A
+HREF="http://sourceforge.net/tracker/?func=add&group_id=11118&atid=111118"
+TARGET="_top"
+>submit
+  form</A
+>.</P
+><P
+> 
+  Please try to verify that it is a <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> bug,
+  and not a browser or site bug first. If unsure,
+  try <A
+HREF="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>toggling
+  off</A
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and see if the problem persists.
+  The <A
+HREF="http://www.privoxy.org/user-manual/appendix.html#ACTIONSANAT"
+TARGET="_top"
+>appendix
+  of the user manual</A
+> also has helpful information 
+  on action debugging. If you are using your own custom configuration, please try
+  the stock configs to see if the problem is configuration related.</P
+><P
+>  If not using the latest version, chances are that the bug has been found
+  and fixed in the meantime. We would appreciate if you could take the time
+  to <A
+HREF="http://www.privoxy.org/user-manual/installation.html"
+TARGET="_top"
+>upgrade
+  to the latest version</A
+> (or  even the latest CVS snapshot) and verify
+  your bug, but this is not required for reporting.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-FEATURE"
+>8.3. Request New Features</A
+></H2
+><P
+> You are welcome to submit ideas on new features or other proposals
+ for improvement through our feature request tracker at
+ <A
+HREF="http://sourceforge.net/tracker/?atid=361118&group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?atid=361118&#38;group_id=11118</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-ADS"
+>8.4. Report Ads or Other Actions-Related Problems</A
+></H2
+><P
+> Please send feedback on ads that slipped through, innocent images that were blocked,
+ and any other problems relating to the <TT
+CLASS="FILENAME"
+>default.action</TT
+> file through
+ our actions feedback mechanism located at
+ <A
+HREF="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>http://www.privoxy.org/actions/</A
+>.
+ On this page, you will also find a bookmark which will take you back there from
+ any troubled site and even pre-fill the form!</P
+><P
+> New, improved <TT
+CLASS="FILENAME"
+>default.action</TT
+> files will occasionally be made
+ available based on your feedback. These will be announced on the <A
+HREF="http://lists.sourceforge.net/lists/listinfo/ijbswa-announce"
+TARGET="_top"
+>ijbswa-announce</A
+>
+ list and available from our <A
+HREF="http://sf.net/projects/ijbswa/"
+TARGET="_top"
+>project page</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-OTHER"
+>8.5. Other</A
+></H2
+><P
+>For any other issues, feel free to use the mailing lists. Technically interested users
+and people who wish to contribute to the project are also welcome on the developers list!
+You can find an overview of all <SPAN
+CLASS="APPLICATION"
+>Prixoxy</SPAN
+>-related mailing lists,
+including list archives, at:
+<A
+HREF="http://sourceforge.net/mail/?group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/mail/?group_id=11118</A
+>.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="webserver-update.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="copyright.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Update the Webserver</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Privoxy Copyright, License and History</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/copyright.html b/doc/webserver/developer-manual/copyright.html
new file mode 100644 (file)
index 0000000..f409341
--- /dev/null
@@ -0,0 +1,296 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy Copyright, License and History</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Contacting the developers, Bug Reporting and Feature Requests"
+HREF="contact.html"><LINK
+REL="NEXT"
+TITLE="See also"
+HREF="seealso.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="contact.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="seealso.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="COPYRIGHT"
+>9. Privoxy Copyright, License and History</A
+></H1
+><P
+> Copyright Â© 2001, 2002 by Privoxy Developers <TT
+CLASS="EMAIL"
+>&#60;<A
+HREF="mailto:developers@privoxy.org"
+>developers@privoxy.org</A
+>&#62;</TT
+></P
+><P
+> Some source code is based on code Copyright Â© 1997 by Anonymous Coders
+ and Junkbusters, Inc. and licensed under the <I
+CLASS="CITETITLE"
+>GNU General Public
+ License</I
+>.</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1121"
+>9.1. License</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is free software; you can
+ redistribute it and/or modify it under the terms of the 
+ <I
+CLASS="CITETITLE"
+>GNU General Public
+ License</I
+>, version 2, as published by the Free Software Foundation.</P
+><P
+> This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ <I
+CLASS="CITETITLE"
+>GNU General Public License</I
+> for
+ more details, which is available from the Free Software Foundation, Inc, 59
+ Temple Place - Suite 330, Boston, MA  02111-1307, USA.</P
+><P
+> You should have received a copy of the <A
+HREF="http://www.gnu.org/copyleft/gpl.html"
+TARGET="_top"
+> <I
+CLASS="CITETITLE"
+>GNU General Public License</I
+></A
+>
+ along with this program; if not, write to the <P
+CLASS="ADDRESS"
+>&nbsp;Free&nbsp;Software<br>
+&nbsp;Foundation,&nbsp;Inc.&nbsp;<SPAN
+CLASS="STREET"
+>59 Temple Place</SPAN
+>&nbsp;-&nbsp;Suite&nbsp;330<br>
+&nbsp;<SPAN
+CLASS="CITY"
+>Boston</SPAN
+>,&nbsp;<SPAN
+CLASS="STATE"
+>MA</SPAN
+>&nbsp;<SPAN
+CLASS="POSTCODE"
+>02111-1307</SPAN
+><br>
+&nbsp;<SPAN
+CLASS="COUNTRY"
+>USA</SPAN
+>&nbsp;</P
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1137"
+>9.2. History</A
+></H2
+><P
+> In the beginning, there was the
+ <A
+HREF="http://www.junkbusters.com/ijb.html"
+TARGET="_top"
+><SPAN
+CLASS="APPLICATION"
+>Internet Junkbuster</SPAN
+></A
+>, 
+ by Anonymous Coders and <A
+HREF="http://www.junkbusters.com/"
+TARGET="_top"
+>Junkbusters
+ Corporation</A
+>. It saved many users a lot of pain in the early days of
+ web advertising and user tracking.</P
+><P
+> But the web, its protocols and standards, and with it, the techniques for
+ forcing  users to consume ads, give up autonomy over their browsing, and
+ for spying on them, kept evolving. Unfortunately, the <SPAN
+CLASS="APPLICATION"
+>Internet
+ Junkbuster</SPAN
+> did not. Version 2.0.2, published in 1998, was 
+ (and is) the last official
+ <A
+HREF="http://www.junkbusters.com/ijbdist.html#release"
+TARGET="_top"
+>release</A
+>
+ available from <A
+HREF="http://www.junkbusters.com"
+TARGET="_top"
+>Junkbusters Corporation</A
+>.
+ Fortunately, it had been released under the GNU
+ <A
+HREF="http://www.gnu.org/licenses/gpl.html"
+TARGET="_top"
+> GPL</A
+>, which allowed further
+ development by others.</P
+><P
+> So Stefan Waldherr started maintaining an
+ <A
+HREF="http://www.waldherr.org/junkbuster/"
+TARGET="_top"
+>improved version of the
+ software</A
+>, to which eventually a number of people contributed patches.
+ It could already replace banners with a transparent image, and had a first
+ version of pop-up killing, but it was still very closely based on the
+ original, with all its limitations, such as the lack of HTTP/1.1 support,
+ flexible per-site configuration, or content modification. The last release
+ from this effort was version 2.0.2-10, published in 2000.</P
+><P
+> Then, some
+ <A
+HREF="http://www.privoxy.org/user-manual/copyright.html#AUTHORS"
+TARGET="_top"
+>developers</A
+>
+ picked up the thread, and started turning the software inside out, upside down,
+ and then reassembled it, adding many
+ <A
+HREF="http://www.privoxy.org/user-manual/introduction.html#FEATURES"
+TARGET="_top"
+>new
+ features</A
+> along the way.</P
+><P
+> The result of this is <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, whose first
+ stable release, 3.0, is due in May 2002.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="contact.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="seealso.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Contacting the developers, Bug Reporting and Feature Requests</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>See also</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/cvs.html b/doc/webserver/developer-manual/cvs.html
new file mode 100644 (file)
index 0000000..8801054
--- /dev/null
@@ -0,0 +1,301 @@
+<HTML
+><HEAD
+><TITLE
+>The CVS Repository</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Introduction"
+HREF="introduction.html"><LINK
+REL="NEXT"
+TITLE="Documentation Guidelines"
+HREF="documentation.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="introduction.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="documentation.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CVS"
+>2. The CVS Repository</A
+></H1
+><P
+>      If you intend to help us with programming, documentation or packaging
+      you will need write access to our holy grail, the CVS repository.
+      Please read this chapter completely before accessing via CVS.
+    </P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CVSACCESS"
+>2.1. Access to CVS</A
+></H2
+><P
+>        The project's CVS repository is hosted on
+        <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>SourceForge.</A
+>
+        Please refer to the chapters 6 and 7 in
+        <A
+HREF="http://sourceforge.net/docman/?group_id=1"
+TARGET="_top"
+>SF's site
+        documentation</A
+> for the technical access details for your
+        operating system. For historical reasons, the CVS server is
+        called <TT
+CLASS="LITERAL"
+>cvs.ijbswa.sourceforge.net</TT
+>, the repository is
+        called <TT
+CLASS="LITERAL"
+>ijbswa</TT
+>, and the source tree module is called
+        <TT
+CLASS="LITERAL"
+>current</TT
+>.
+      </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CVSCOMMIT"
+>2.2. CVS Commit Guideline</A
+></H2
+><P
+>        The source tree is the heart of every software project. Every effort must
+        be made to ensure that it is readable, compilable and consistent at all
+        times. We therefore ask anyone with CVS access to strictly adhere to the
+        following guidelines:
+        <P
+></P
+><UL
+><LI
+><P
+>            Never (read: <I
+CLASS="EMPHASIS"
+>never, ever</I
+>) be tempted to commit
+            that small change without testing it thoroughly first. When we're
+            close to a public release, ask a fellow developer to review your 
+            changes.
+          </P
+></LI
+><LI
+><P
+>            Your commit message should give a concise overview of <I
+CLASS="EMPHASIS"
+>what you
+            changed</I
+> (no big details) and <I
+CLASS="EMPHASIS"
+>why you changed it</I
+>
+            Just check previous messages for good examples.
+          </P
+></LI
+><LI
+><P
+>            Don't use the same message on multiple files, unless it equally applies to
+            all those files.
+          </P
+></LI
+><LI
+><P
+>            If your changes span multiple files, and the code won't recompile unless
+            all changes are commited (e.g. when changing the signature of a function),
+            then commit all files one after another, without long delays in beween.
+            If necessary, prepare the commit messages in advance.
+          </P
+></LI
+><LI
+><P
+>            Before changing things on CVS, make sure that your changes are in line
+            with the team's general consensus on what should be done (see below).
+          </P
+></LI
+></UL
+>
+      </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CVSWHENASK"
+>2.3. Discussing Changes First</A
+></H2
+><P
+>        We don't have a too formal policy on this, just use common sense. Hints: If it is..
+        <P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>            ..a bugfix / clean-up / cosmetic thing: shoot
+          </P
+></LI
+><LI
+><P
+>            ..a new feature that can be turned off: shoot
+          </P
+></LI
+><LI
+><P
+>            ..a clear improvement w/o side effects on other parts of the code: shoot
+          </P
+></LI
+><LI
+><P
+>            ..a matter of taste: <A
+HREF="mailto:developers@privoxy.org"
+TARGET="_top"
+>ask the list</A
+>
+          </P
+></LI
+><LI
+><P
+>            ..a major redesign of some part of the code: <A
+HREF="mailto:developers@privoxy.org"
+TARGET="_top"
+>ask
+            the list</A
+>
+          </P
+></LI
+></OL
+>
+      </P
+><P
+>        Note that near a major public release, we get a bit more cautious - if
+        unsure, it doesn't hurt to ask first. There is always the possibility
+        to submit a patch to the <A
+HREF="http://sourceforge.net/tracker/?atid=311118&group_id=11118&func=browse"
+TARGET="_top"
+>patches
+        tracker</A
+> instead.
+      </P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="introduction.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="documentation.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Introduction</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Documentation Guidelines</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/documentation.html b/doc/webserver/developer-manual/documentation.html
new file mode 100644 (file)
index 0000000..19ac418
--- /dev/null
@@ -0,0 +1,838 @@
+<HTML
+><HEAD
+><TITLE
+>Documentation Guidelines</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="The CVS Repository"
+HREF="cvs.html"><LINK
+REL="NEXT"
+TITLE="Coding Guidelines"
+HREF="coding.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="cvs.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="coding.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="DOCUMENTATION"
+>3. Documentation Guidelines</A
+></H1
+><P
+>    All formal documents are maintained in Docbook SGML and located in the
+    <TT
+CLASS="COMPUTEROUTPUT"
+>doc/source/*</TT
+> directory. You will need
+    <A
+HREF="http://www.docbook.org"
+TARGET="_top"
+>Docbook</A
+>, the Docbook 
+    DTD's and the Docbook modular stylesheets (or comparable alternatives),
+    and either <SPAN
+CLASS="APPLICATION"
+>jade</SPAN
+> or
+    <SPAN
+CLASS="APPLICATION"
+>openjade</SPAN
+> (recommended) installed in order to
+    build docs from source. Currently there is <A
+HREF="../user-manual/index.html"
+TARGET="_top"
+><I
+CLASS="CITETITLE"
+>user-manual</I
+></A
+>,
+    <A
+HREF="../faq/index.html"
+TARGET="_top"
+><I
+CLASS="CITETITLE"
+>FAQ</I
+></A
+>, and, of
+    course this, the <I
+CLASS="CITETITLE"
+>developer-manual</I
+> in this format.
+    The <I
+CLASS="CITETITLE"
+>README</I
+>, <I
+CLASS="CITETITLE"
+>AUTHORS</I
+>
+    <I
+CLASS="CITETITLE"
+>privoxy.1</I
+> (man page) files are also now maintained
+    as Docbook SGML. The finished files are all in the top-level source
+    directory are generated files! Also, <TT
+CLASS="FILENAME"
+>index.html</TT
+>, the
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> home page, is maintained as SGML.
+    <I
+CLASS="EMPHASIS"
+>DO NOT edit these directly</I
+>. Edit the SGML source, or
+    contact someone involved in the documentation (at present Stefan and
+    Hal).
+    </P
+><P
+>     Other, less formal documents (e.g. <TT
+CLASS="FILENAME"
+>LICENSE</TT
+>,
+     <TT
+CLASS="FILENAME"
+>INSTALL</TT
+>) are maintained as plain text files in the
+     top-level source directory. At least for the time being.
+    </P
+><P
+>     Packagers are encouraged to include this documentation. For those without
+     the ability to build the docs locally, text versions of each are kept in
+     CVS. HTML versions are also now being kept in CVS under 
+     <TT
+CLASS="FILENAME"
+>doc/webserver/*</TT
+>.
+    </P
+><P
+>     Formal documents are built with the Makefile targets of
+     <TT
+CLASS="COMPUTEROUTPUT"
+>make dok</TT
+>, or alternately
+     <TT
+CLASS="COMPUTEROUTPUT"
+>make redhat-dok</TT
+>. If you have problems,
+     try both. The build process uses the document SGML sources in
+     <TT
+CLASS="COMPUTEROUTPUT"
+>doc/source/*/*</TT
+> to update all text files in
+     <TT
+CLASS="COMPUTEROUTPUT"
+>doc/text/</TT
+> and to update all HTML
+     documents in <TT
+CLASS="COMPUTEROUTPUT"
+>doc/webserver/</TT
+>.
+    </P
+><P
+>     Documentation writers should please make sure documents build
+     successfully before committing to CVS, if possible.
+    </P
+><P
+>     How do you update the webserver (i.e. the pages on privoxy.org)?
+     
+     <P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>        First, build the docs by running <TT
+CLASS="COMPUTEROUTPUT"
+>make
+        dok</TT
+> (or alternately <TT
+CLASS="COMPUTEROUTPUT"
+>make
+        redhat-dok</TT
+>).                 
+      </P
+></LI
+><LI
+><P
+>        Run <TT
+CLASS="COMPUTEROUTPUT"
+>make webserver</TT
+> which copies all
+        files from <TT
+CLASS="COMPUTEROUTPUT"
+>doc/webserver</TT
+> to the
+        sourceforge webserver via scp.
+      </P
+></LI
+></OL
+>
+  </P
+><P
+>   Finished docs should be occasionally submitted to CVS
+   (<TT
+CLASS="FILENAME"
+>doc/webserver/*/*.html</TT
+>) so that those without 
+   the ability to build them locally, have access to them if needed.
+   This is especially important just prior to a new release! Please
+   do this <I
+CLASS="EMPHASIS"
+>after</I
+> the <TT
+CLASS="LITERAL"
+>$VERSION</TT
+> and
+   other release specific data in <TT
+CLASS="FILENAME"
+>configure.in</TT
+> has been
+   updated (this is done just prior to a new release).
+  </P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="SGML"
+>3.1. Quickstart to Docbook and SGML</A
+></H2
+><P
+> If you are not familiar with SGML, it is a markup language similar to HTML. 
+ Actually, not a mark up language per se, but a language used to define 
+ markup languages. In fact, HTML is an SGML application. Both will use
+ <SPAN
+CLASS="QUOTE"
+>"tags"</SPAN
+> to format text and other content. SGML tags can be much
+ more varied, and flexible, but do much of the same kinds of things. The tags,
+ or <SPAN
+CLASS="QUOTE"
+>"elements"</SPAN
+>, are definable in SGML. There is no set
+ <SPAN
+CLASS="QUOTE"
+>"standards"</SPAN
+>. Since we are using
+ <SPAN
+CLASS="APPLICATION"
+>Docbook</SPAN
+>, our tags are those that are defined by 
+ <SPAN
+CLASS="APPLICATION"
+>Docbook</SPAN
+>. Much of how the finish document is
+ rendered is determined by the <SPAN
+CLASS="QUOTE"
+>"stylesheets"</SPAN
+>.
+ The stylesheets determine how each tag gets translated to HTML, or other
+ formats.</P
+><P
+> Tags in Docbook SGML need to be always <SPAN
+CLASS="QUOTE"
+>"closed"</SPAN
+>. If not, you
+ will likely generate errors. Example: <TT
+CLASS="LITERAL"
+>&#60;title&#62;My
+ Title&#60;/title&#62;</TT
+>. They are also case-insensitive, but we
+ strongly suggest using all lower case. This keeps compatibility with
+ [Docbook] <SPAN
+CLASS="APPLICATION"
+>XML</SPAN
+>.</P
+><P
+> Our documents use <SPAN
+CLASS="QUOTE"
+>"sections"</SPAN
+> for the most part. Sections
+ will be processed into HTML headers (e.g. <TT
+CLASS="LITERAL"
+>h1</TT
+> for 
+ <TT
+CLASS="LITERAL"
+>sect1</TT
+>). The <SPAN
+CLASS="APPLICATION"
+>Docbook</SPAN
+> stylesheets
+ will use these to also generate the Table of Contents for each doc. Our 
+ TOC's are set to a depth of three. Meaning <TT
+CLASS="LITERAL"
+>sect1</TT
+>, 
+ <TT
+CLASS="LITERAL"
+>sect2</TT
+>, and <TT
+CLASS="LITERAL"
+>sect3</TT
+> will have TOC 
+ entries, but <TT
+CLASS="LITERAL"
+>sect4</TT
+> will not. Each section requires 
+ a <TT
+CLASS="LITERAL"
+>&#60;title&#62;</TT
+> element, and at least one 
+ <TT
+CLASS="LITERAL"
+>&#60;para&#62;</TT
+>. There is a limit of five section 
+ levels in Docbook, but generally three should be sufficient for our 
+ purposes.</P
+><P
+> Some common elements that you likely will use: </P
+><P
+>  <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;para&#62;&#60;/para&#62;</I
+>, paragraph delimiter. Most 
+      text needs to be within paragraph elements (there are some exceptions).
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;emphasis&#62;&#60;/emphasis&#62;</I
+>, the stylesheets
+      make this italics.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;filename&#62;&#60;/filename&#62;</I
+>, files and directories.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;command&#62;&#60;/command&#62;</I
+>, command examples.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;literallayout&#62;&#60;/literallayout&#62;</I
+>, like 
+      <TT
+CLASS="LITERAL"
+>&#60;pre&#62;</TT
+>, more or less.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;itemizedlist&#62;&#60;/itemizedlist&#62;</I
+>, list with bullets.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;listitem&#62;&#60;/listitem&#62;</I
+>, member of the above.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;screen&#62;&#60;/screen&#62;</I
+>, screen output, implies 
+      <TT
+CLASS="LITERAL"
+>&#60;literallayout&#62;</TT
+>.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;ulink url="example.com"&#62;&#60;/ulink&#62;</I
+>, like 
+      HTML <TT
+CLASS="LITERAL"
+>&#60;a&#62;</TT
+> tag.
+    </TD
+></TR
+><TR
+><TD
+>      <I
+CLASS="EMPHASIS"
+>&#60;quote&#62;&#60;/quote&#62;</I
+>, for, doh, quoting text. 
+    </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+> Look at any of the existing docs for examples of all these and more.</P
+><P
+> You might also find <SPAN
+CLASS="QUOTE"
+>"<A
+HREF="http://www.bureau-cornavin.com/opensource/crash-course/"
+TARGET="_top"
+>Writing Documentation
+ Using DocBook - A Crash Course</A
+>"</SPAN
+> useful.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="DOCSTYLE"
+>3.2. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Documentation Style</A
+></H2
+><P
+>    It will be easier if everyone follows a similar writing style. This 
+    just makes it easier to read what someone else has written if it 
+    is all done in a similar fashion.
+   </P
+><P
+>    Here it is:
+   </P
+><P
+>    <P
+></P
+><UL
+><LI
+><P
+>       All tags should be lower case.
+      </P
+></LI
+><LI
+><P
+>       Tags delimiting a <I
+CLASS="EMPHASIS"
+>block</I
+> of text (even small
+       blocks) should be on their own line. Like:
+       <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&#60;para&#62;<br>
+&nbsp;&nbsp;Some&nbsp;text&nbsp;goes&nbsp;here.<br>
+&nbsp;&#60;/para&#62;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P
+>
+       Tags marking individual words, or few words, should be in-line:
+       <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;Just&nbsp;to&nbsp;&#60;emphasis&#62;emphasize&#60;/emphasis&#62;,&nbsp;some&nbsp;text&nbsp;goes&nbsp;here.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P
+>
+     </P
+></LI
+><LI
+><P
+>      Tags should be nested and step indented for block text like: (except
+      in-line tags) 
+     <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&#60;para&#62;<br>
+&nbsp;&nbsp;&#60;itemizedlist&#62;<br>
+&nbsp;&nbsp;&nbsp;&#60;para&#62;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&#60;listitem&#62;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Some&nbsp;text&nbsp;goes&nbsp;here&nbsp;in&nbsp;our&nbsp;list&nbsp;example.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#60;/listitem&#62;<br>
+&nbsp;&nbsp;&nbsp;&#60;/para&#62;<br>
+&nbsp;&nbsp;&#60;/itemizedlist&#62;<br>
+&nbsp;&#60;/para&#62;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P
+>
+      This makes it easier to find the text amongst the tags ;-)
+    </P
+></LI
+><LI
+><P
+>     Use white space to separate logical divisions within a document, 
+     like between sections. Running everything together consistently 
+     makes it harder to read and work on.
+    </P
+></LI
+><LI
+><P
+>     Do not hesitate to make comments. Comments can either use the 
+     &#60;comment&#62; element, or the &#60;!--  --&#62; style comment 
+     familiar from HTML. (Note in Docbook v4.x &#60;comment&#62; is 
+     replaced by &#60;remark&#62;.)
+    </P
+></LI
+><LI
+><P
+>     We have an international audience. Refrain from slang, or English 
+     idiosyncrasies (too many to list :). Humor also does not translate 
+     well sometimes.
+   </P
+></LI
+><LI
+><P
+>    Try to keep overall line lengths in source files to 80 characters or less
+    for obvious reasons. This is not always possible, with lengthy URLs for
+    instance.
+   </P
+></LI
+><LI
+><P
+>    Our documents are available in differing formats. Right now, they 
+    are just plain text, and HTML, but PDF, and others is always a 
+    future possibility. Be careful with URLs (&#60;ulink&#62;), and avoid 
+    this mistake:
+   </P
+><P
+>     My favorite site is &#60;ulink url="http://example.com"&#62;here&#60;/ulink&#62;.
+   </P
+><P
+>     This will render as <SPAN
+CLASS="QUOTE"
+>"My favorite site is here"</SPAN
+>, which is 
+     not real helpful in a text doc. Better like this:
+   </P
+><P
+>     My favorite site is &#60;ulink url="http://example.com"&#62;example.com&#60;/ulink&#62;.
+   </P
+></LI
+><LI
+><P
+>    All documents should be spell checked occasionally.
+    <SPAN
+CLASS="APPLICATION"
+>aspell</SPAN
+> can check SGML with the
+    <TT
+CLASS="LITERAL"
+>-H</TT
+> option. (<SPAN
+CLASS="APPLICATION"
+>ispell</SPAN
+> I think
+    too.)
+   </P
+></LI
+></UL
+>
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN209"
+>3.3. Privoxy Custom Entities</A
+></H2
+><P
+>  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> documentation is using 
+  a number of customized <SPAN
+CLASS="QUOTE"
+>"entities"</SPAN
+> to facilitate 
+  documentation maintenance. 
+ </P
+><P
+>  We are using a set of <SPAN
+CLASS="QUOTE"
+>"boilerplate"</SPAN
+> files with generic text,
+  that is used by multiple docs. This way we can write something once, and use
+  it repeatedly without having to re-write the same content over and over again.
+  If editing such a file, keep in mind that it should be
+  <I
+CLASS="EMPHASIS"
+>generic</I
+>. That is the purpose; so it can be used in varying 
+  contexts without additional modifications.
+ </P
+><P
+>  We are also using what <SPAN
+CLASS="APPLICATION"
+>Docbook</SPAN
+> calls 
+  <SPAN
+CLASS="QUOTE"
+>"internal entities"</SPAN
+>. These are like variables in 
+  programming. Well, sort of. For instance, we have the
+  <TT
+CLASS="LITERAL"
+>p-version</TT
+> entity that contains the current 
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> version string. You are strongly 
+  encouraged to use these where possible. Some of these obviously 
+  require re-setting with each release (done by the Makefile). A sampling of
+  custom entities are listed below. See any of the main docs for examples.
+ </P
+><P
+>  <P
+></P
+><UL
+><LI
+><P
+>    Re- <SPAN
+CLASS="QUOTE"
+>"boilerplate"</SPAN
+> text entities are defined like:
+   </P
+><P
+>    <TT
+CLASS="LITERAL"
+>&#60;!entity supported SYSTEM "supported.sgml"&#62;</TT
+>
+   </P
+><P
+>     In this example, the contents of the file,
+     <TT
+CLASS="FILENAME"
+>supported.sgml</TT
+> is available for inclusion anywhere 
+     in the doc. To make this happen, just reference the now defined 
+     entity: <TT
+CLASS="LITERAL"
+>&#38;supported;</TT
+> (starts with an ampersand 
+     and ends with a semi-colon), and the contents will be dumped into 
+     the finished doc at that point.
+   </P
+></LI
+><LI
+><P
+>    Commonly used <SPAN
+CLASS="QUOTE"
+>"internal entities"</SPAN
+>:
+  </P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>    <I
+CLASS="EMPHASIS"
+>p-version</I
+>: the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> 
+    version string, e.g. <SPAN
+CLASS="QUOTE"
+>"2.9.15"</SPAN
+>.
+   </TD
+></TR
+><TR
+><TD
+>    <I
+CLASS="EMPHASIS"
+>p-status</I
+>: the project status, either 
+    <SPAN
+CLASS="QUOTE"
+>"alpha"</SPAN
+>, <SPAN
+CLASS="QUOTE"
+>"beta"</SPAN
+>, or <SPAN
+CLASS="QUOTE"
+>"stable"</SPAN
+>.
+   </TD
+></TR
+><TR
+><TD
+>    <I
+CLASS="EMPHASIS"
+>p-not-stable</I
+>: use to conditionally include 
+    text in <SPAN
+CLASS="QUOTE"
+>"not stable"</SPAN
+> releases (e.g. <SPAN
+CLASS="QUOTE"
+>"beta"</SPAN
+>).
+   </TD
+></TR
+><TR
+><TD
+>    <I
+CLASS="EMPHASIS"
+>p-stable</I
+>: just the opposite.
+   </TD
+></TR
+><TR
+><TD
+>    <I
+CLASS="EMPHASIS"
+>p-text</I
+>: this doc is only generated as text.
+   </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></LI
+></UL
+>
+ </P
+><P
+>  There are others in various places that are defined for a specific 
+  purpose. Read the source!
+ </P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="cvs.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="coding.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>The CVS Repository</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Coding Guidelines</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/index.html b/doc/webserver/developer-manual/index.html
new file mode 100644 (file)
index 0000000..cf386de
--- /dev/null
@@ -0,0 +1,668 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy Developer Manual</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="NEXT"
+TITLE="Introduction"
+HREF="introduction.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="AEN2"
+>Privoxy Developer Manual</A
+></H1
+><P
+CLASS="PUBDATE"
+>     <SUB
+>    
+    
+      <A
+HREF="copyright.html"
+>Copyright</A
+> Â© 2001, 2002 by 
+      <A
+HREF="http://www.privoxy.org"
+TARGET="_top"
+>Privoxy Developers</A
+>
+     </SUB
+>
+    <BR></P
+><P
+CLASS="PUBDATE"
+>$Id: developer-manual.sgml,v 1.45 2002/05/19 23:01:54 hal9 Exp $<BR></P
+><DIV
+><DIV
+CLASS="ABSTRACT"
+><A
+NAME="AEN9"
+></A
+><P
+></P
+><P
+> The developer manual gives the users information on how to help the developer
+ team. It provides guidance on coding, testing, documentation and other
+ issues. 
+ </P
+><P
+> You can find the latest version of the this manual at <A
+HREF="http://www.privoxy.org/developer-manual/"
+TARGET="_top"
+>http://www.privoxy.org/developer-manual/</A
+>.
+ Please see <A
+HREF="contact.html"
+>the Contact section</A
+> 
+ on how to contact the developers.</P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="introduction.html"
+>Introduction</A
+></DT
+><DD
+><DL
+><DT
+>1.1. <A
+HREF="introduction.html#QUICKSTART"
+>Quickstart to Privoxy Development</A
+></DT
+></DL
+></DD
+><DT
+>2. <A
+HREF="cvs.html"
+>The CVS Repository</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="cvs.html#CVSACCESS"
+>Access to CVS</A
+></DT
+><DT
+>2.2. <A
+HREF="cvs.html#CVSCOMMIT"
+>CVS Commit Guideline</A
+></DT
+><DT
+>2.3. <A
+HREF="cvs.html#CVSWHENASK"
+>Discussing Changes First</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="documentation.html"
+>Documentation Guidelines</A
+></DT
+><DD
+><DL
+><DT
+>3.1. <A
+HREF="documentation.html#SGML"
+>Quickstart to Docbook and SGML</A
+></DT
+><DT
+>3.2. <A
+HREF="documentation.html#DOCSTYLE"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Documentation Style</A
+></DT
+><DT
+>3.3. <A
+HREF="documentation.html#AEN209"
+>Privoxy Custom Entities</A
+></DT
+></DL
+></DD
+><DT
+>4. <A
+HREF="coding.html"
+>Coding Guidelines</A
+></DT
+><DD
+><DL
+><DT
+>4.1. <A
+HREF="coding.html#S1"
+>Introduction</A
+></DT
+><DT
+>4.2. <A
+HREF="coding.html#S2"
+>Using Comments</A
+></DT
+><DD
+><DL
+><DT
+>4.2.1. <A
+HREF="coding.html#S3"
+>Comment, Comment, Comment</A
+></DT
+><DT
+>4.2.2. <A
+HREF="coding.html#S4"
+>Use blocks for comments</A
+></DT
+><DT
+>4.2.3. <A
+HREF="coding.html#S5"
+>Keep Comments on their own line</A
+></DT
+><DT
+>4.2.4. <A
+HREF="coding.html#S6"
+>Comment each logical step</A
+></DT
+><DT
+>4.2.5. <A
+HREF="coding.html#S7"
+>Comment All Functions Thoroughly</A
+></DT
+><DT
+>4.2.6. <A
+HREF="coding.html#S8"
+>Comment at the end of braces if the
+    content is more than one screen length</A
+></DT
+></DL
+></DD
+><DT
+>4.3. <A
+HREF="coding.html#S9"
+>Naming Conventions</A
+></DT
+><DD
+><DL
+><DT
+>4.3.1. <A
+HREF="coding.html#S10"
+>Variable Names</A
+></DT
+><DT
+>4.3.2. <A
+HREF="coding.html#S11"
+>Function Names</A
+></DT
+><DT
+>4.3.3. <A
+HREF="coding.html#S12"
+>Header file prototypes</A
+></DT
+><DT
+>4.3.4. <A
+HREF="coding.html#S13"
+>Enumerations, and #defines</A
+></DT
+><DT
+>4.3.5. <A
+HREF="coding.html#S14"
+>Constants</A
+></DT
+></DL
+></DD
+><DT
+>4.4. <A
+HREF="coding.html#S15"
+>Using Space</A
+></DT
+><DD
+><DL
+><DT
+>4.4.1. <A
+HREF="coding.html#S16"
+>Put braces on a line by themselves.</A
+></DT
+><DT
+>4.4.2. <A
+HREF="coding.html#S17"
+>ALL control statements should have a
+    block</A
+></DT
+><DT
+>4.4.3. <A
+HREF="coding.html#S18"
+>Do not belabor/blow-up boolean
+    expressions</A
+></DT
+><DT
+>4.4.4. <A
+HREF="coding.html#S19"
+>Use white space freely because it is
+    free</A
+></DT
+><DT
+>4.4.5. <A
+HREF="coding.html#S20"
+>Don't use white space around structure
+    operators</A
+></DT
+><DT
+>4.4.6. <A
+HREF="coding.html#S21"
+>Make the last brace of a function stand
+    out</A
+></DT
+><DT
+>4.4.7. <A
+HREF="coding.html#S22"
+>Use 3 character indentions</A
+></DT
+></DL
+></DD
+><DT
+>4.5. <A
+HREF="coding.html#S23"
+>Initializing</A
+></DT
+><DD
+><DL
+><DT
+>4.5.1. <A
+HREF="coding.html#S24"
+>Initialize all variables</A
+></DT
+></DL
+></DD
+><DT
+>4.6. <A
+HREF="coding.html#S25"
+>Functions</A
+></DT
+><DD
+><DL
+><DT
+>4.6.1. <A
+HREF="coding.html#S26"
+>Name functions that return a boolean as a
+    question.</A
+></DT
+><DT
+>4.6.2. <A
+HREF="coding.html#S27"
+>Always specify a return type for a
+    function.</A
+></DT
+><DT
+>4.6.3. <A
+HREF="coding.html#S28"
+>Minimize function calls when iterating by
+    using variables</A
+></DT
+><DT
+>4.6.4. <A
+HREF="coding.html#S29"
+>Pass and Return by Const Reference</A
+></DT
+><DT
+>4.6.5. <A
+HREF="coding.html#S30"
+>Pass and Return by Value</A
+></DT
+><DT
+>4.6.6. <A
+HREF="coding.html#S31"
+>Names of include files</A
+></DT
+><DT
+>4.6.7. <A
+HREF="coding.html#S32"
+>Provide multiple inclusion
+    protection</A
+></DT
+><DT
+>4.6.8. <A
+HREF="coding.html#S33"
+>Use `extern "C"` when appropriate</A
+></DT
+><DT
+>4.6.9. <A
+HREF="coding.html#S34"
+>Where Possible, Use Forward Struct
+    Declaration Instead of Includes</A
+></DT
+></DL
+></DD
+><DT
+>4.7. <A
+HREF="coding.html#S35"
+>General Coding Practices</A
+></DT
+><DD
+><DL
+><DT
+>4.7.1. <A
+HREF="coding.html#S36"
+>Turn on warnings</A
+></DT
+><DT
+>4.7.2. <A
+HREF="coding.html#S37"
+>Provide a default case for all switch
+    statements</A
+></DT
+><DT
+>4.7.3. <A
+HREF="coding.html#S38"
+>Try to avoid falling through cases in a
+    switch statement.</A
+></DT
+><DT
+>4.7.4. <A
+HREF="coding.html#S39"
+>Use 'long' or 'short' Instead of
+    'int'</A
+></DT
+><DT
+>4.7.5. <A
+HREF="coding.html#S40"
+>Don't mix size_t and other types</A
+></DT
+><DT
+>4.7.6. <A
+HREF="coding.html#S41"
+>Declare each variable and struct on its
+    own line.</A
+></DT
+><DT
+>4.7.7. <A
+HREF="coding.html#S42"
+>Use malloc/zalloc sparingly</A
+></DT
+><DT
+>4.7.8. <A
+HREF="coding.html#S43"
+>The Programmer Who Uses 'malloc' is
+    Responsible for Ensuring 'free'</A
+></DT
+><DT
+>4.7.9. <A
+HREF="coding.html#S44"
+>Add loaders to the `file_list' structure
+    and in order</A
+></DT
+><DT
+>4.7.10. <A
+HREF="coding.html#S45"
+>"Uncertain" new code and/or changes to
+    existing code, use FIXME</A
+></DT
+></DL
+></DD
+><DT
+>4.8. <A
+HREF="coding.html#S46"
+>Addendum: Template for files and function
+    comment blocks:</A
+></DT
+></DL
+></DD
+><DT
+>5. <A
+HREF="testing.html"
+>Testing Guidelines</A
+></DT
+><DD
+><DL
+><DT
+>5.1. <A
+HREF="testing.html#TESTING-PLAN"
+>Testplan for releases</A
+></DT
+><DT
+>5.2. <A
+HREF="testing.html#TESTING-REPORT"
+>Test reports</A
+></DT
+></DL
+></DD
+><DT
+>6. <A
+HREF="newrelease.html"
+>Releasing a New Version</A
+></DT
+><DD
+><DL
+><DT
+>6.1. <A
+HREF="newrelease.html#VERSIONNUMBERS"
+>Version numbers</A
+></DT
+><DT
+>6.2. <A
+HREF="newrelease.html#BEFORERELEASE"
+>Before the Release: Freeze</A
+></DT
+><DT
+>6.3. <A
+HREF="newrelease.html#THERELEASE"
+>Building and Releasing the Packages</A
+></DT
+><DD
+><DL
+><DT
+>6.3.1. <A
+HREF="newrelease.html#PACK-GUIDELINES"
+>Note on Privoxy Packaging</A
+></DT
+><DT
+>6.3.2. <A
+HREF="newrelease.html#NEWRELEASE-TARBALL"
+>Source Tarball</A
+></DT
+><DT
+>6.3.3. <A
+HREF="newrelease.html#NEWRELEASE-RPM"
+>SuSE, Conectiva or Red Hat RPM</A
+></DT
+><DT
+>6.3.4. <A
+HREF="newrelease.html#NEWRELEASE-OS2"
+>OS/2</A
+></DT
+><DT
+>6.3.5. <A
+HREF="newrelease.html#NEWRELEASE-SOLARIS"
+>Solaris</A
+></DT
+><DT
+>6.3.6. <A
+HREF="newrelease.html#NEWRELEASE-WINDOWS"
+>Windows</A
+></DT
+><DT
+>6.3.7. <A
+HREF="newrelease.html#NEWRELEASE-DEBIAN"
+>Debian</A
+></DT
+><DT
+>6.3.8. <A
+HREF="newrelease.html#NEWRELEASE-MACOSX"
+>Mac OSX</A
+></DT
+><DT
+>6.3.9. <A
+HREF="newrelease.html#NEWRELEASE-FREEBSD"
+>FreeBSD</A
+></DT
+><DT
+>6.3.10. <A
+HREF="newrelease.html#NEWRELEASE-HPUX"
+>HP-UX 11</A
+></DT
+><DT
+>6.3.11. <A
+HREF="newrelease.html#NEWRELEASE-AMIGA"
+>Amiga OS</A
+></DT
+><DT
+>6.3.12. <A
+HREF="newrelease.html#NEWRELEASE-AIX"
+>AIX</A
+></DT
+></DL
+></DD
+><DT
+>6.4. <A
+HREF="newrelease.html#RELEASING"
+>Uploading and Releasing Your Package</A
+></DT
+><DT
+>6.5. <A
+HREF="newrelease.html#AFTERRELEASE"
+>After the Release</A
+></DT
+></DL
+></DD
+><DT
+>7. <A
+HREF="webserver-update.html"
+>Update the Webserver</A
+></DT
+><DT
+>8. <A
+HREF="contact.html"
+>Contacting the developers, Bug Reporting and Feature Requests</A
+></DT
+><DD
+><DL
+><DT
+>8.1. <A
+HREF="contact.html#CONTACT-SUPPORT"
+>Get Support</A
+></DT
+><DT
+>8.2. <A
+HREF="contact.html#CONTACT-BUGS"
+>Report Bugs</A
+></DT
+><DT
+>8.3. <A
+HREF="contact.html#CONTACT-FEATURE"
+>Request New Features</A
+></DT
+><DT
+>8.4. <A
+HREF="contact.html#CONTACT-ADS"
+>Report Ads or Other Actions-Related Problems</A
+></DT
+><DT
+>8.5. <A
+HREF="contact.html#CONTACT-OTHER"
+>Other</A
+></DT
+></DL
+></DD
+><DT
+>9. <A
+HREF="copyright.html"
+>Privoxy Copyright, License and History</A
+></DT
+><DD
+><DL
+><DT
+>9.1. <A
+HREF="copyright.html#AEN1121"
+>License</A
+></DT
+><DT
+>9.2. <A
+HREF="copyright.html#AEN1137"
+>History</A
+></DT
+></DL
+></DD
+><DT
+>10. <A
+HREF="seealso.html"
+>See also</A
+></DT
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="introduction.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Introduction</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/introduction.html b/doc/webserver/developer-manual/introduction.html
new file mode 100644 (file)
index 0000000..b4bcd2b
--- /dev/null
@@ -0,0 +1,184 @@
+<HTML
+><HEAD
+><TITLE
+>Introduction</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="NEXT"
+TITLE="The CVS Repository"
+HREF="cvs.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="index.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="cvs.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="INTRODUCTION"
+>1. Introduction</A
+></H1
+><P
+>     <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, as an heir to
+     <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>, is an Open Source project 
+     and licensed under the GPL. As such, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+     development is potentially open to anyone who has the time, knowledge,
+     and desire to contribute in any capacity. Our goals are simply to
+     continue the mission, to improve <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and
+     to make it available to as wide an audience as possible. 
+    </P
+><P
+>     One does not have to be a programmer to contribute. Packaging, testing,
+     and porting, are all important jobs as well.
+    </P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="QUICKSTART"
+>1.1. Quickstart to Privoxy Development</A
+></H2
+><P
+>      You'll need an account on <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>Sourceforge</A
+> to support our
+      development.  Mail your ID to <A
+HREF="mailto:developers@privoxy.org"
+TARGET="_top"
+>the list</A
+> and wait until a
+      project manager has added you.
+    </P
+><P
+>      For the time being (read, this section is under construction), please
+      refer to the extensive comments in the source code.
+    </P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="index.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="cvs.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Privoxy Developer Manual</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The CVS Repository</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/newrelease.html b/doc/webserver/developer-manual/newrelease.html
new file mode 100644 (file)
index 0000000..5ff11fb
--- /dev/null
@@ -0,0 +1,1667 @@
+<HTML
+><HEAD
+><TITLE
+>Releasing a New Version</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Testing Guidelines"
+HREF="testing.html"><LINK
+REL="NEXT"
+TITLE="Update the Webserver"
+HREF="webserver-update.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="testing.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="webserver-update.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="NEWRELEASE"
+>6. Releasing a New Version</A
+></H1
+><P
+>        When we release versions of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>,
+        our work leaves our cozy secret lab and has to work in the cold
+        RealWorld[tm]. Once it is released, there is no way to call it
+        back, so it is very important that great care is taken to ensure
+        that everything runs fine, and not to introduce problems in the
+        very last minute.
+    </P
+><P
+>        So when releasing a new version, please adhere exactly to the
+        procedure outlined in this chapter.
+    </P
+><P
+>      The following programs are required to follow this process:
+       <TT
+CLASS="FILENAME"
+>ncftpput</TT
+> (ncftp), <TT
+CLASS="FILENAME"
+>scp, ssh</TT
+> (ssh),
+        <TT
+CLASS="FILENAME"
+>gmake</TT
+> (GNU's version of make), autoconf, cvs.
+    </P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="VERSIONNUMBERS"
+>6.1. Version numbers</A
+></H2
+><P
+>      First you need to determine which version number the release will have. 
+      <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> version numbers consist of three numbers,
+      separated by dots, like in X.Y.Z, where:
+        <P
+></P
+><UL
+><LI
+><P
+>              X, the version major, is rarely ever changed. It is increased by one if
+              turning a development branch into stable substantially changes the functionality,
+              user interface or configuration syntax. Majors 1 and 2 were 
+              <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>, and 3 will be the first stable
+              <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> release.
+            </P
+></LI
+><LI
+><P
+>              Y, the version minor, represents the branch within the major version.
+              At any point in time, there are two branches being maintained:
+              The stable branch, with an even minor, say, 2N, in which no functionality is
+              being added and only bugfixes are made, and 2N+1, the development branch, in
+              which the further development of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> takes
+              place.
+              This enables us to turn the code upside down and inside out, while at the same time
+              providing and maintaining a stable version.
+              The minor is reset to zero (and one) when the major is inrcemented. When a development
+              branch has matured to the point where it can be turned into stable, the old stable branch
+              2N is given up (i.e. no longer maintained), the former development branch 2N+1 becomes the
+              new stable branch 2N+2, and a new development branch 2N+3 is opened.
+            </P
+></LI
+><LI
+><P
+>              Z, the point or sub version, represents a release of the software within a branch.
+              It is therefore incremented immediately before each code freeze. 
+              In development branches, only the even point versions correspond to actual releases,
+              while the odd ones denote the evolving state of the sources on CVS in between.
+              It follows that Z is odd on CVS in development branches most of the time. There, it gets
+              increased to an even number immediately before a code freeze, and is increased to an odd
+              number again immediately thereafter.
+              This ensures that builds from CVS snapshots are easily distinguished from released versions.
+              The point version is reset to zero when the minor changes.
+            </P
+></LI
+></UL
+>
+    </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="BEFORERELEASE"
+>6.2. Before the Release: Freeze</A
+></H2
+><P
+>       The following <I
+CLASS="EMPHASIS"
+>must be done by one of the
+       developers</I
+> prior to each new release.
+     </P
+><P
+>      <P
+></P
+><UL
+><LI
+><P
+>         Make sure that everybody who has worked on the code in the last
+         couple of days has had a chance to yell <SPAN
+CLASS="QUOTE"
+>"no!"</SPAN
+> in case
+         they have pending changes/fixes in their pipelines. Announce the
+         freeze so that nobody will interfere with last minute changes.
+        </P
+></LI
+><LI
+><P
+>         Increment the version number (point from odd to even in development
+         branches!) in <TT
+CLASS="FILENAME"
+>configure.in</TT
+>.
+       </P
+></LI
+><LI
+><P
+>        If <TT
+CLASS="FILENAME"
+>default.action</TT
+> has changed since last
+        release (i.e. software release or standalone actions file release),
+        bump up its version info to A.B in this line:
+       </P
+><P
+> 
+        <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  {+add-header{X-Actions-File-Version: A.B} -filter -no-popups}</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+> 
+        Then change the version info in doc/webserver/actions/index.php,
+        line: '$required_actions_file_version = "A.B";'
+       </P
+></LI
+><LI
+><P
+>        If the HTML documentation is not in sync with the SGML sources
+        you need to regenerate and upload it to the webserver. (If in
+        doubt, just do it.) See the Section "Updating the webserver" in
+        this manual for details.
+       </P
+></LI
+><LI
+><P
+>        <I
+CLASS="EMPHASIS"
+>Commit all files that were changed in the above steps!</I
+>
+       </P
+></LI
+><LI
+><P
+>        Tag all files in CVS with the version number with
+        <SPAN
+CLASS="QUOTE"
+>"<B
+CLASS="COMMAND"
+>cvs tag v_X_Y_Z</B
+>"</SPAN
+>.
+        Don't use vX_Y_Z, ver_X_Y_Z, v_X.Y.Z (won't work) etc.
+       </P
+></LI
+><LI
+><P
+>        If the release was in a development branch, increase the point version
+        from even to odd (X.Y.(Z+1)) again in <TT
+CLASS="FILENAME"
+>configure.in</TT
+> and
+        commit your change.
+       </P
+></LI
+><LI
+><P
+>        On the webserver, copy the user manual to a new top-level directory
+        called <TT
+CLASS="FILENAME"
+>X.Y.Z</TT
+>. This ensures that help links from the CGI
+        pages, which have the version as a prefix, will go into the right version of the manual.
+        If this is a development branch release, also symlink <TT
+CLASS="FILENAME"
+>X.Y.(Z-1)</TT
+>
+        to <TT
+CLASS="FILENAME"
+>X.Y.Z</TT
+> and <TT
+CLASS="FILENAME"
+>X.Y.(Z+1)</TT
+> to
+        <TT
+CLASS="FILENAME"
+>.</TT
+> (i.e. dot). 
+       </P
+></LI
+></UL
+>
+     </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="THERELEASE"
+>6.3. Building and Releasing the Packages</A
+></H2
+><P
+>      Now the individual packages can be built and released. Note that for
+      GPL reasons the first package to be released is always the source tarball.
+     </P
+><P
+>      For <I
+CLASS="EMPHASIS"
+>all</I
+> types of packages, including the source tarball,
+      <I
+CLASS="EMPHASIS"
+>you must make sure that you build from clean sources by exporting
+      the right version from CVS into an empty directory:</I
+>.
+     </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  mkdir dist # delete or choose different name if it already exists
+  cd dist
+  cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa export -r v_X_Y_Z current</PRE
+></TD
+></TR
+></TABLE
+>
+    </P
+><P
+>     <I
+CLASS="EMPHASIS"
+>Do NOT change</I
+> a single bit, including, but not limited to
+     version information after export from CVS. This is to make sure that
+     all release packages, and with them, all future bug reports, are based
+     on exactly the same code.
+    </P
+><P
+>     Please find additional instructions for the source tarball and the
+     individual platform dependent binary packages below. And details 
+     on the Sourceforge release process below that.
+    </P
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="PACK-GUIDELINES"
+>6.3.1. Note on Privoxy Packaging</A
+></H3
+><P
+>      Please keep these general guidelines in mind when putting together 
+      your package. These apply to <I
+CLASS="EMPHASIS"
+>all</I
+> platforms!
+     </P
+><P
+>      <P
+></P
+><UL
+><LI
+><P
+>          <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> <I
+CLASS="EMPHASIS"
+>requires</I
+>
+          write access to: all <TT
+CLASS="FILENAME"
+>*.action</TT
+> files, all 
+          logfiles, and the <TT
+CLASS="FILENAME"
+>trust</TT
+> file. You will 
+          need to determine the best way to do this for your platform.
+        </P
+></LI
+><LI
+><P
+>          Please include up to date documentation. At a bare minimum:
+        </P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>          <TT
+CLASS="FILENAME"
+>LICENSE</TT
+> (toplevel directory)
+         </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>          <TT
+CLASS="FILENAME"
+>README</TT
+> (toplevel directory)
+         </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>          <TT
+CLASS="FILENAME"
+>AUTHORS</TT
+> (toplevel directory)
+         </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>          <TT
+CLASS="FILENAME"
+>man page</TT
+> (toplevel directory, Unix-like
+          platforms only)
+         </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>          <TT
+CLASS="FILENAME"
+>The User Manual</TT
+> (doc/webserver/user-manual/)
+         </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>          <TT
+CLASS="FILENAME"
+>FAQ</TT
+> (doc/webserver/faq/)
+         </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+>          Also suggested: <TT
+CLASS="FILENAME"
+>Developer Manual</TT
+>
+          (doc/webserver/devel-manual) and <TT
+CLASS="FILENAME"
+>ChangeLog</TT
+>
+          (toplevel directory). <TT
+CLASS="FILENAME"
+>FAQ</TT
+> and the manuals are
+          HTML docs. There are also text versions in
+          <TT
+CLASS="FILENAME"
+>doc/text/</TT
+> which could conceivably also be
+          included.
+        </P
+><P
+>         The documentation has been designed such that the manuals are linked
+         to each other from parallel directories, and should be packaged 
+         that way. <TT
+CLASS="FILENAME"
+>index.html</TT
+> can also be included and 
+         can serve as a focal point for docs and other links of interest.
+         This should be one level up from the manuals. There are two 
+         css stylesheets that can be included for better presentation:
+         <TT
+CLASS="FILENAME"
+>p_doc.css</TT
+> and <TT
+CLASS="FILENAME"
+>p_web.css</TT
+>.
+         These should be in the same directory with
+         <TT
+CLASS="FILENAME"
+>index.html</TT
+>, (i.e. one level up from the manual 
+         directories).
+        </P
+></LI
+><LI
+><P
+>        <TT
+CLASS="FILENAME"
+>user.action</TT
+> is designed for local preferences. 
+        Make sure this does not get overwritten!
+       </P
+></LI
+><LI
+><P
+>        Other configuration files should be installed as the new defaults, 
+        but all previously installed configuration files should be preserved
+        as backups. This is just good manners :-)
+       </P
+></LI
+><LI
+><P
+>       Please check platform specific notes in this doc, if you haven't 
+       done <SPAN
+CLASS="QUOTE"
+>"Privoxy"</SPAN
+> packaging before for other platform 
+       specific issues. Conversely, please add any notes that you know 
+       are important for your platform (or contact one of the doc 
+       maintainers to do this if you can't).
+      </P
+></LI
+></UL
+>
+     </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-TARBALL"
+>6.3.2. Source Tarball</A
+></H3
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then do:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  make tarball-dist</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      To upload the package to Sourceforge, simply issue
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  make tarball-upload</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Go to the displayed URL and release the file publicly on Sourceforge.
+        For the change log field, use the relevant section of the
+        <TT
+CLASS="FILENAME"
+>ChangeLog</TT
+> file.
+      </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-RPM"
+>6.3.3. SuSE, Conectiva or Red Hat RPM</A
+></H3
+><P
+>        In following text, replace <TT
+CLASS="REPLACEABLE"
+><I
+>dist</I
+></TT
+>
+        with either <SPAN
+CLASS="QUOTE"
+>"rh"</SPAN
+> for Red Hat or <SPAN
+CLASS="QUOTE"
+>"suse"</SPAN
+> for SuSE.
+        </P
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). 
+       </P
+><P
+>        As the only exception to not changing anything after export from CVS,
+        now examine the file <TT
+CLASS="FILENAME"
+>privoxy-</TT
+><TT
+CLASS="REPLACEABLE"
+><I
+>dist</I
+></TT
+><TT
+CLASS="FILENAME"
+>.spec</TT
+>
+        and make sure that the version information and the RPM release number are
+        correct. The RPM release numbers for each version start at one. Hence it must
+        be reset to one if this is the first RPM for
+        <TT
+CLASS="REPLACEABLE"
+><I
+>dist</I
+></TT
+> which is built from version
+        X.Y.Z. Check the
+        <A
+HREF="http://sourceforge.net/project/showfiles.php?group_id=11118"
+TARGET="_top"
+>file
+        list</A
+> if unsure. Else, it must be set to the highest already available RPM
+        release number for that version plus one.
+       </P
+><P
+>        Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then do
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  make <TT
+CLASS="REPLACEABLE"
+><I
+>dist</I
+></TT
+>-dist</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      To upload the package to Sourceforge, simply issue
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  make <TT
+CLASS="REPLACEABLE"
+><I
+>dist</I
+></TT
+>-upload <TT
+CLASS="REPLACEABLE"
+><I
+>rpm_packagerev</I
+></TT
+></PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>        where <TT
+CLASS="REPLACEABLE"
+><I
+>rpm_packagerev</I
+></TT
+> is the
+        RPM release number as determined above.
+       Go to the displayed URL and release the file publicly on Sourceforge.
+        Use the release notes and change log from the source tarball package.
+      </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-OS2"
+>6.3.4. OS/2</A
+></H3
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then get the OS/2 Setup module:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co os2setup</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      You will need a mix of development tools.
+       The main compilation takes place with IBM Visual Age C++.
+       Some ancillary work takes place with GNU tools, available from
+       various sources like hobbes.nmsu.edu.
+       Specificially, you will need <TT
+CLASS="FILENAME"
+>autoheader</TT
+>,
+       <TT
+CLASS="FILENAME"
+>autoconf</TT
+> and <TT
+CLASS="FILENAME"
+>sh</TT
+> tools.
+       The packaging takes place with WarpIN, available from various sources, including
+       its home page: <A
+HREF="http://www.xworkplace.org/"
+TARGET="_top"
+>xworkplace</A
+>.
+       </P
+><P
+>      Change directory to the <TT
+CLASS="FILENAME"
+>os2setup</TT
+> directory.
+       Edit the os2build.cmd file to set the final executable filename.
+       For example, 
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  installExeName='privoxyos2_setup_X.Y.Z.exe'</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Next, edit the <TT
+CLASS="FILENAME"
+>IJB.wis</TT
+> file so the release number matches
+       in the <TT
+CLASS="FILENAME"
+>PACKAGEID</TT
+> section:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  PACKAGEID="Privoxy Team\Privoxy\Privoxy Package\X\Y\Z"</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      You're now ready to build.  Run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  os2build</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>         You will find the  WarpIN-installable executable in the
+        <TT
+CLASS="FILENAME"
+>./files</TT
+> directory. Upload this anonymously to
+         <TT
+CLASS="FILENAME"
+>uploads.sourceforge.net/incoming</TT
+>, create a release
+         for it, and you're done. Use the release notes and Change Log from the
+         source tarball package.
+       </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-SOLARIS"
+>6.3.5. Solaris</A
+></H3
+><P
+>      Login to Sourceforge's compilefarm via ssh:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  ssh cf.sourceforge.net</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Choose the right operating system (not the Debian one).
+        When logged in, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then run
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  gmake solaris-dist</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      which creates a gzip'ed tar archive. Sadly, you cannot use <B
+CLASS="COMMAND"
+>make
+       solaris-upload</B
+> on the Sourceforge machine (no ncftpput). You now have
+       to manually upload the archive to Sourceforge's ftp server and release
+       the file publicly. Use the release notes and Change Log from the
+        source tarball package.
+       </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-WINDOWS"
+>6.3.6. Windows</A
+></H3
+><P
+>        You should ensure you have the latest version of Cygwin (from
+        <A
+HREF="http://www.cygwin.com/"
+TARGET="_top"
+>http://www.cygwin.com/</A
+>).
+        Run the following commands from within a Cygwin bash shell.
+      </P
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then get the Windows setup module:
+      </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>        cvs -z3  -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co winsetup</PRE
+></TD
+></TR
+></TABLE
+>
+      </P
+><P
+>        Then you can build the package.  This is fully automated, and is
+        controlled by <TT
+CLASS="FILENAME"
+>winsetup/GNUmakefile</TT
+>.
+        All you need to do is:
+      </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>        cd winsetup
+        make</PRE
+></TD
+></TR
+></TABLE
+>
+      </P
+><P
+>        Now you can manually rename <TT
+CLASS="FILENAME"
+>privoxy_setup.exe</TT
+> to
+        <TT
+CLASS="FILENAME"
+>privoxy_setup_X_Y_Z.exe</TT
+>, and upload it to
+        SourceForge. When releasing the package on SourceForge, use the release notes
+        and Change Log from the source tarball package.
+      </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-DEBIAN"
+>6.3.7. Debian</A
+></H3
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then, run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then do FIXME.
+       </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-MACOSX"
+>6.3.8. Mac OSX</A
+></H3
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then get the Mac OSX setup module:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co osxsetup</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd osxsetup
+  build</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      This will run <TT
+CLASS="FILENAME"
+>autoheader</TT
+>, <TT
+CLASS="FILENAME"
+>autoconf</TT
+> and
+       <TT
+CLASS="FILENAME"
+>configure</TT
+> as well as <TT
+CLASS="FILENAME"
+>make</TT
+>.
+       Finally, it will copy over the necessary files to the ./osxsetup/files directory
+       for further processing by <TT
+CLASS="FILENAME"
+>PackageMaker</TT
+>.
+       </P
+><P
+>      Bring up PackageMaker with the PrivoxyPackage.pmsp definition file, modify the package
+       name to match the release, and hit the "Create package" button.
+       If you specify ./Privoxy.pkg as the output package name, you can then create
+       the distributable zip file with the command:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>zip -r privoxyosx_setup_x.y.z.zip Privoxy.pkg</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      You can then upload <TT
+CLASS="FILENAME"
+>privoxyosx_setup_x.y.z.zip</TT
+> anonymously to 
+       <TT
+CLASS="FILENAME"
+>uploads.sourceforge.net/incoming</TT
+>,
+       create a release for it, and you're done. Use the release notes
+        and Change Log from the source tarball package.
+       </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-FREEBSD"
+>6.3.9. FreeBSD</A
+></H3
+><P
+>      Login to Sourceforge's compilefarm via ssh:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  ssh cf.sourceforge.net</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Choose the right operating system.
+        When logged in, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  gmake freebsd-dist</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      which creates a gzip'ed tar archive. Sadly, you cannot use <B
+CLASS="COMMAND"
+>make
+       freebsd-upload</B
+> on the Sourceforge machine (no ncftpput). You now have
+       to manually upload the archive to Sourceforge's ftp server and release
+       the file publicly. Use the release notes and Change Log from the
+        source tarball package.
+       </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-HPUX"
+>6.3.10. HP-UX 11</A
+></H3
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then do FIXME.
+       </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-AMIGA"
+>6.3.11. Amiga OS</A
+></H3
+><P
+>      First, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then do FIXME.
+       </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="NEWRELEASE-AIX"
+>6.3.12. AIX</A
+></H3
+><P
+>      Login to Sourceforge's compilefarm via ssh:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  ssh cf.sourceforge.net</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Choose the right operating system.
+        When logged in, <I
+CLASS="EMPHASIS"
+>make sure that you have freshly exported the right
+        version into an empty directory</I
+>. (See "Building and releasing
+        packages" above). Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  cd current
+  autoheader &#38;&#38; autoconf &#38;&#38; ./configure</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      Then run:
+       </P
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  make aix-dist</PRE
+></TD
+></TR
+></TABLE
+>
+       </P
+><P
+>      which creates a gzip'ed tar archive. Sadly, you cannot use <B
+CLASS="COMMAND"
+>make
+       aix-upload</B
+> on the Sourceforge machine (no ncftpput). You now have
+       to manually upload the archive to Sourceforge's ftp server and release
+       the file publicly. Use the release notes and Change Log from the
+        source tarball package.
+       </P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="RELEASING"
+>6.4. Uploading and Releasing Your Package</A
+></H2
+><P
+>      After the package is ready, it is time to upload it 
+      to SourceForge, and go through the release steps. The upload
+      is done via FTP:
+    </P
+><P
+>      <P
+></P
+><UL
+><LI
+><P
+>          Upload to: <A
+HREF="ftp://upload.sourceforge.net/incoming"
+TARGET="_top"
+>ftp://upload.sourceforge.net/incoming</A
+>
+        </P
+></LI
+><LI
+><P
+>         user: <TT
+CLASS="LITERAL"
+>anonymous</TT
+>
+       </P
+></LI
+><LI
+><P
+>         password: <TT
+CLASS="LITERAL"
+>ijbswa-developers@lists.sourceforge.net</TT
+>
+       </P
+></LI
+></UL
+>
+    </P
+><P
+>     Or use the <B
+CLASS="COMMAND"
+>make</B
+> targets as described above.
+    </P
+><P
+>     Once this done go to <A
+HREF="http://sourceforge.net/project/admin/editpackages.php?group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/project/admin/editpackages.php?group_id=11118</A
+>, 
+     making sure you are logged in. Find your target platform in the 
+     second column, and click <TT
+CLASS="LITERAL"
+>Add Release</TT
+>. You will 
+     then need to create a new release for your package, using the format 
+     of <TT
+CLASS="LITERAL"
+>$VERSION ($CODE_STATUS)</TT
+>, e.g. <I
+CLASS="EMPHASIS"
+>2.9.15
+     (beta)</I
+>.
+    </P
+><P
+>     Now just follow the prompts. Be sure to add any appropriate Release
+     notes. You should see your freshly uploaded packages in 
+     <SPAN
+CLASS="QUOTE"
+>"Step 2. Add Files To This Release"</SPAN
+>. Check the 
+     appropriate box(es). Remember at each step to hit the 
+     <SPAN
+CLASS="QUOTE"
+>"Refresh/Submit"</SPAN
+> buttons! You should now see your 
+     file(s) listed in Step 3. Fill out the forms with the appropriate 
+     information for your platform, being sure to hit <SPAN
+CLASS="QUOTE"
+>"Update"</SPAN
+>
+     for each file. If anyone is monitoring your platform, check the 
+     <SPAN
+CLASS="QUOTE"
+>"email"</SPAN
+> box at the very bottom to notify them of 
+     the new package. This should do it!
+    </P
+><P
+>     If you have made errors, or need to make changes, you can go through 
+     essentially the same steps, but select <TT
+CLASS="LITERAL"
+>Edit Release</TT
+>, 
+     instead of <TT
+CLASS="LITERAL"
+>Add Release</TT
+>.
+    </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AFTERRELEASE"
+>6.5. After the Release</A
+></H2
+><P
+>      When all (or: most of the) packages have been uploaded and made available,
+      send an email to the <A
+HREF="mailto:ijbswa-announce@lists.sourceforge.net"
+TARGET="_top"
+>announce
+      mailing list</A
+>, Subject: "Version X.Y.Z available for download". Be sure to
+      include the
+      <A
+HREF="http://sourceforge.net/project/showfiles.php?group_id=11118"
+TARGET="_top"
+>download
+      location</A
+>, the release notes and the change log.
+     </P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="testing.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="webserver-update.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Testing Guidelines</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Update the Webserver</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/quickstart.html b/doc/webserver/developer-manual/quickstart.html
new file mode 100644 (file)
index 0000000..ba84f13
--- /dev/null
@@ -0,0 +1,150 @@
+<HTML
+><HEAD
+><TITLE
+>Quickstart to Privoxy Development</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Introduction"
+HREF="introduction.html"><LINK
+REL="NEXT"
+TITLE="The CVS Repository"
+HREF="cvs.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="introduction.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="cvs.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="QUICKSTART"
+>3. Quickstart to Privoxy Development</A
+></H1
+><P
+>      You'll need an account on <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>Sourceforge</A
+> to support our
+      development.  Mail your ID to <A
+HREF="mailto:developers@privoxy.org"
+TARGET="_top"
+>the list</A
+> and wait until a
+      project manager has added you.
+    </P
+><P
+>      For the time being (read, this section is under construction), please
+      refer to the extensive comments in the source code.
+    </P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="introduction.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="cvs.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Introduction</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The CVS Repository</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/seealso.html b/doc/webserver/developer-manual/seealso.html
new file mode 100644 (file)
index 0000000..3c9f9e4
--- /dev/null
@@ -0,0 +1,385 @@
+<HTML
+><HEAD
+><TITLE
+>See also</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Privoxy Copyright, License and History"
+HREF="copyright.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="copyright.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+>&nbsp;</TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="SEEALSO"
+>10. See also</A
+></H1
+><P
+> Other references and sites of interest to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ users:</P
+><P
+> <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/"
+TARGET="_top"
+>http://www.privoxy.org/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Home page. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/faq/"
+TARGET="_top"
+>http://www.privoxy.org/faq/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> FAQ. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://sourceforge.net/projects/ijbswa/"
+TARGET="_top"
+>http://sourceforge.net/projects/ijbswa/</A
+>, 
+   the Project Page for <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> on 
+   <A
+HREF="http://sourceforge.net"
+TARGET="_top"
+>SourceForge</A
+>.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>,
+   the web-based user interface. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> must be
+   running for this to work. Shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>http://www.privoxy.org/actions/</A
+>, to submit <SPAN
+CLASS="QUOTE"
+>"misses"</SPAN
+> to the developers. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.junkbusters.com/ht/en/cookies.html"
+TARGET="_top"
+>http://www.junkbusters.com/ht/en/cookies.html</A
+>,
+   an explanation how cookies are used to track web users.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.junkbusters.com/ijb.html"
+TARGET="_top"
+>http://www.junkbusters.com/ijb.html</A
+>,
+   the original Internet Junkbuster.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.waldherr.org/junkbuster/"
+TARGET="_top"
+>http://www.waldherr.org/junkbuster/</A
+>,
+   Stefan Waldherr's version of Junkbuster, from which <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> was
+   derived.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://privacy.net/analyze/"
+TARGET="_top"
+>http://privacy.net/analyze/</A
+>, a useful site
+   to check what information about you is leaked while you browse the web.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.squid-cache.org/"
+TARGET="_top"
+>http://www.squid-cache.org/</A
+>, a very popular
+   caching proxy, which is often used together with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/developer-manual/"
+TARGET="_top"
+>http://www.privoxy.org/developer-manual/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> developer manual. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="copyright.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Privoxy Copyright, License and History</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/testing.html b/doc/webserver/developer-manual/testing.html
new file mode 100644 (file)
index 0000000..d957a18
--- /dev/null
@@ -0,0 +1,249 @@
+<HTML
+><HEAD
+><TITLE
+>Testing Guidelines</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Coding Guidelines"
+HREF="coding.html"><LINK
+REL="NEXT"
+TITLE="Releasing a New Version"
+HREF="newrelease.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="coding.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="newrelease.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="TESTING"
+>5. Testing Guidelines</A
+></H1
+><P
+>To be filled.</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="TESTING-PLAN"
+>5.1. Testplan for releases</A
+></H2
+><P
+>       Explain release numbers. major, minor. developer releases. etc.
+
+<P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>Remove any existing rpm with rpm -e</P
+></LI
+><LI
+><P
+>Remove any file that was left over. This includes (but is not limited to)
+      <P
+></P
+><UL
+><LI
+><P
+>/var/log/privoxy</P
+></LI
+><LI
+><P
+>/etc/privoxy</P
+></LI
+><LI
+><P
+>/usr/sbin/privoxy</P
+></LI
+><LI
+><P
+>/etc/init.d/privoxy</P
+></LI
+><LI
+><P
+>/usr/doc/privoxy*</P
+></LI
+></UL
+></P
+></LI
+><LI
+><P
+>Install the rpm. Any error messages?</P
+></LI
+><LI
+><P
+>start,stop,status <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with the specific script
+      (e.g. /etc/rc.d/init/privoxy stop). Reboot your machine. Does
+      autostart work?</P
+></LI
+><LI
+><P
+>Start browsing. Does <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> work? Logfile written?</P
+></LI
+><LI
+><P
+>Remove the rpm. Any error messages? All files removed?</P
+></LI
+></OL
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="TESTING-REPORT"
+>5.2. Test reports</A
+></H2
+><P
+>Please submit test reports only with the <A
+HREF="http://sourceforge.net/tracker/?func=add&group_id=11118&atid=395005"
+TARGET="_top"
+>test form</A
+>
+at sourceforge. Three simple steps:
+        <P
+></P
+><UL
+><LI
+><P
+>Select category: the distribution you test on.</P
+></LI
+><LI
+><P
+>Select group: the version of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> that we are about to release.</P
+></LI
+><LI
+><P
+>Fill the Summary and Detailed Description with something
+              intelligent (keep it short and precise).</P
+></LI
+></UL
+>
+        Do not mail to the mailinglist (we cannot keep track on issues there).
+      </P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="coding.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="newrelease.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Coding Guidelines</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Releasing a New Version</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/developer-manual/webserver-update.html b/doc/webserver/developer-manual/webserver-update.html
new file mode 100644 (file)
index 0000000..5112a56
--- /dev/null
@@ -0,0 +1,239 @@
+<HTML
+><HEAD
+><TITLE
+>Update the Webserver</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Developer Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Releasing a New Version"
+HREF="newrelease.html"><LINK
+REL="NEXT"
+TITLE="Contacting the developers, Bug Reporting and Feature Requests"
+HREF="contact.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Developer Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="newrelease.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="contact.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="WEBSERVER-UPDATE"
+>7. Update the Webserver</A
+></H1
+><P
+>    When updating the webserver, please follow these steps to make
+    sure that no broken links, incosistent contents or permission
+    problems will occur:
+   </P
+><P
+>    If you have changed anything in the documentation source SGML files,
+    do:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  make dok # (or make redkat-dok if make dok doesn't work for you)</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    That will generate <TT
+CLASS="FILENAME"
+>doc/webserver/user-manual</TT
+>,
+    <TT
+CLASS="FILENAME"
+>doc/webserver/developer-manual</TT
+>,
+    <TT
+CLASS="FILENAME"
+>doc/webserver/faq</TT
+> and
+    <TT
+CLASS="FILENAME"
+>doc/webserver/index.html</TT
+> automatically.
+   </P
+><P
+>    If you changed the manual page source, generate
+    <TT
+CLASS="FILENAME"
+>doc/webserver/man-page/privoxy-man-page.html</TT
+>
+    by running <SPAN
+CLASS="QUOTE"
+>"<B
+CLASS="COMMAND"
+>make man</B
+>"</SPAN
+>. (This is
+    a separate target due to dependencies on some obscure perl scripts. 
+    See comments in <TT
+CLASS="FILENAME"
+>GNUmakefile</TT
+>.)
+   </P
+><P
+>    If you want to add new files to the webserver, create them locally in
+    the <TT
+CLASS="FILENAME"
+>doc/webserver/*</TT
+> directory (or
+    create new directories under <TT
+CLASS="FILENAME"
+>doc/webserver</TT
+>).
+   </P
+><P
+>    Next, commit any changes from the above steps to CVS. All set? Then do
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  make webserver</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    This will do the upload to <A
+HREF="http://www.privoxy.org/"
+TARGET="_top"
+>the
+    webserver</A
+> (www.privoxy.org) and ensure all files and directories
+    there are group writable.
+   </P
+><P
+>    Please do <I
+CLASS="EMPHASIS"
+>NOT</I
+> use any other means of transferring
+    files to the webserver to avoid permission problems.
+   </P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="newrelease.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="contact.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Releasing a New Version</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Contacting the developers, Bug Reporting and Feature Requests</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/configuration.html b/doc/webserver/faq/configuration.html
new file mode 100644 (file)
index 0000000..506e60b
--- /dev/null
@@ -0,0 +1,808 @@
+<HTML
+><HEAD
+><TITLE
+>Configuration</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Installation"
+HREF="installation.html"><LINK
+REL="NEXT"
+TITLE="Miscellaneous"
+HREF="misc.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Frequently Asked Questions</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="installation.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="misc.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CONFIGURATION"
+>3. Configuration</A
+></H1
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="NEWCONFIG"
+>3.1. Can I use my old config files?</A
+></H3
+><P
+>   There are major changes to <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>/ 
+   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> configuration from version 2.0.x to
+   2.9.x and later. Most of the older files will not work at all. This is 
+   especially true of <TT
+CLASS="FILENAME"
+>blocklist</TT
+>. If this is the case, you
+   will need to re-enter your old data into the new configuration structure.
+   This is probably also a good recommendation even if upgrading from 2.9.x to
+   3.x since there were many minor changes along the way.
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN234"
+>3.2. What is an <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> file?</A
+></H3
+><P
+> <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> files are where various actions that
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> might take, are configured. 
+ Typically, you would define a set of default actions that apply 
+ to all URLs, then add exceptions to these defaults where needed.</P
+><P
+> Actions can be defined on a per site basis, or for groups of sites. Actions
+ can also be grouped together and then applied to one or more sites. There
+ are many possible actions that might apply to any given site. As an example,
+ if we are blocking cookies as one of our default
+ <SPAN
+CLASS="APPLICATION"
+>actions</SPAN
+>, but need to accept cookies from a given
+ site, we would define this in our <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> file.&#13;</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="ACTIONSS"
+>3.3. The <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> concept confuses me. Please list 
+some of these <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+>.</A
+></H3
+><P
+> These are all explained in the 
+ <A
+HREF="../user-manual/actions-file.html"
+TARGET="_top"
+>user-manual</A
+>.
+ Please refer to that.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN249"
+>3.4. How are actions files configured? What is the easiest
+way to do this?</A
+></H3
+><P
+> The easiest way to do this, is to access <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ with your web browser at <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>, 
+ and then select 
+ "<A
+HREF="http://config.privoxy.org"
+TARGET="_top"
+>View &#38; change the current configuration</A
+>"
+ from the selection list. You can also do this by editing the appropriate 
+ file with a text editor.</P
+><P
+> Please see the 
+ <A
+HREF="../user-manual/actions-file.html"
+TARGET="_top"
+>user-manual</A
+> for a
+ detailed explanation of these and other configuration files, and their
+ various options and syntax.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN257"
+>3.5. There are several different <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> files. What are
+the differences?</A
+></H3
+><P
+> As of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> v2.9.15, three actions files 
+ are being included, to be used for 
+ different purposes. These are 
+ <TT
+CLASS="FILENAME"
+>default.action</TT
+>, <TT
+CLASS="FILENAME"
+>standard.action</TT
+>, 
+ and <TT
+CLASS="FILENAME"
+>user.action</TT
+>. Please see 
+ <A
+HREF="../user-manual/actions-file.html"
+TARGET="_top"
+>the User Manual</A
+> 
+ for an explanation of each.</P
+><P
+> Earlier versions included three different versions
+ <TT
+CLASS="FILENAME"
+>default.action</TT
+> files. The new scheme allows for 
+ greater flexibility of local configuration, and for browser based 
+ configuration.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="BROWSECONFIG"
+>3.6. Why can I change the configuration with a
+browser? Does that not raise security issues?</A
+></H3
+><P
+>What I don't understand, is how I can browser edit the config file as a
+regular user, while the whole <TT
+CLASS="FILENAME"
+>/etc/privoxy</TT
+> hierarchy
+belongs to the user <SPAN
+CLASS="QUOTE"
+>"privoxy"</SPAN
+>, with only 644 permissions.
+ </P
+><P
+>When you use the browser-based editor, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+itself is writing to the config files.  Because
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is running as the user <SPAN
+CLASS="QUOTE"
+>"privoxy"</SPAN
+>, it can
+update the config files.
+ </P
+><P
+>If you don't like this, setting <SPAN
+CLASS="QUOTE"
+>"enable-edit-actions 0"</SPAN
+> in the
+config file will disable the browser-based editor.  If you're that paranoid,
+you should also consider setting <SPAN
+CLASS="QUOTE"
+>"enable-remote-toggle 0"</SPAN
+> to prevent
+browser-based enabling/disabling of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+ </P
+><P
+>Note that normally only local users can connect to
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, so this is not (normally) a security
+problem.
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN283"
+>3.7. What is <SPAN
+CLASS="QUOTE"
+>"default.filter"</SPAN
+>?</A
+></H3
+><P
+> The <SPAN
+CLASS="QUOTE"
+>"default.filter"</SPAN
+> file is where <SPAN
+CLASS="QUOTE"
+>"filters"</SPAN
+>
+ are defined, which are used to <SPAN
+CLASS="QUOTE"
+>"filter"</SPAN
+> any
+ web page content. By <SPAN
+CLASS="QUOTE"
+>"filtering"</SPAN
+> we mean it can modify, remove, 
+ or change <I
+CLASS="EMPHASIS"
+>anything</I
+> on the page, including HTML tags, and
+ JavaScript. Regular expressions are used to accomplish this, and operate 
+ on a line by line basis. This is potentially a very powerful feature, but
+ requires some expertise. </P
+><P
+> If you are familiar with regular expressions, and HTML, you can look at 
+ the provided <TT
+CLASS="FILENAME"
+>default.filter</TT
+> with a text editor and see
+ some of things it can be used for.</P
+><P
+> Presently, there is no GUI editor option for this part of the configuration, 
+ but you can disable/enable various sections of the included default 
+ file with the <SPAN
+CLASS="QUOTE"
+>"View &#38; change the current configuration"</SPAN
+> from
+ your browser. </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN296"
+>3.8. How can I set up <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to act as a proxy for my 
+ LAN?</A
+></H3
+><P
+> By default, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> only responds to requests 
+ from localhost. To have it act as a server for a network, this needs to be 
+ changed in the main config file where the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ configuration is located. In that file is a <SPAN
+CLASS="QUOTE"
+>"listen-address"</SPAN
+> 
+ option. It may be commented out with a <SPAN
+CLASS="QUOTE"
+>"#"</SPAN
+> symbol. Make sure 
+ it is uncommented, and assign it the address of the LAN gateway interface, 
+ and port number to use:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  listen-address  192.168.1.1:8118</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Save the file, and restart <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Configure 
+ all browsers on the network then to use this address and port number.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN308"
+>3.9. Instead of ads, now I get a checkerboard pattern. I don't want to see anything.</A
+></H3
+><P
+> This is a configuration option for images that
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is stopping. You have the choice of a
+ checkerboard pattern, a transparent 1x1 GIF image (aka <SPAN
+CLASS="QUOTE"
+>"blank"</SPAN
+>),
+ or a custom URL of your choice. Note that to fit this category, the URL must
+ match both the <A
+HREF="../user-manual/actions-file.html#HANDLE-AS-IMAGE"
+TARGET="_top"
+><SPAN
+CLASS="QUOTE"
+>"+handle-as-image"</SPAN
+></A
+>
+ <I
+CLASS="EMPHASIS"
+>and</I
+> 
+ <A
+HREF="../user-manual/actions-file.html#BLOCK"
+TARGET="_top"
+><SPAN
+CLASS="QUOTE"
+>"+block"</SPAN
+></A
+> actions.</P
+><P
+> If you want to see nothing, then change the 
+ <A
+HREF="../user-manual/actions-file.html#SET-IMAGE-BLOCKER"
+TARGET="_top"
+><SPAN
+CLASS="QUOTE"
+>"+set-image-blocker"</SPAN
+></A
+>
+ action to <SPAN
+CLASS="QUOTE"
+>"+image-blocker{blank}"</SPAN
+>. This can be done from the 
+ <SPAN
+CLASS="QUOTE"
+>"View &#38; change the current configuration"</SPAN
+> selection at <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>. Or by hand editing the appropriate 
+ actions file. This will only effect what is defined as <SPAN
+CLASS="QUOTE"
+>"images"</SPAN
+>
+ though. Also, some URLs that generate the bright red <SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+>
+ banner, can be moved to the <SPAN
+CLASS="QUOTE"
+>"+set-image-blocker"</SPAN
+> section for the
+ same reason, but there are some limits and risks to this (see below).</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN327"
+>3.10. Why would anybody want to see a checkerboard pattern?</A
+></H3
+><P
+> This can be helpful for troubleshooting problems. It might also be good 
+ for anyone new to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> so that they can 
+ see if their favorite pages are displaying correctly, and
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is not inadvertently removing something 
+ important.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN332"
+>3.11. I see large red banners on some pages that say 
+<SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+>. Why and how do I get rid of this?</A
+></H3
+><P
+> These are URLs that match something in one of 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> block actions 
+ (<A
+HREF="../user-manual/actions-file.html#BLOCK"
+TARGET="_top"
+><SPAN
+CLASS="QUOTE"
+>"+block"</SPAN
+></A
+>).
+ It is meant to be a warning so that you know something has been blocked and
+ an easy way for you to see why. These are handled differently than what has
+ been defined explicitly as <SPAN
+CLASS="QUOTE"
+>"images"</SPAN
+> (e.g. ads that are GIF image
+ files). Depending on the URL itself, it is sometimes hard for
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to really know whether there is indeed an
+ ad image there or not. And there are limitations as to what
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can do to <SPAN
+CLASS="QUOTE"
+>"fool"</SPAN
+> the
+ browser.</P
+><P
+> For instance, if the ad is in a frame, then it is embedded in the separate
+ HTML page used for the frame. In this case, you cannot just substitute an
+ aribitrary image (like we would for a <SPAN
+CLASS="QUOTE"
+>"blank"</SPAN
+> image), for an HTML
+ page. The browser is expecting an HTML page, and that is what it must have
+ for frames. Such situations can be a little trickier to deal with, and 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> may show the <SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+> page,
+ despite your best efforts.</P
+><P
+> If you want these to be treated as if they were images, so that they can be
+ made invisible, you can try moving the offending URL from the
+ <SPAN
+CLASS="QUOTE"
+>"+block"</SPAN
+> section to the <SPAN
+CLASS="QUOTE"
+>"+imageblock"</SPAN
+> section of
+ your actions file. Just be forewarned, if any URL is made
+ <SPAN
+CLASS="QUOTE"
+>"invisible"</SPAN
+>, you may not have any inkling that something has
+ been removed from that page, or why. If this approach does not work, then you are
+ probably dealing with a frame (or <SPAN
+CLASS="QUOTE"
+>"ilayer"</SPAN
+>), and the only thing
+ that can go there is an HTML page of some sort.</P
+><P
+> To deal with this situation, you could modify the
+ <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="FILENAME"
+>block</TT
+>"</SPAN
+> HTML template that is used by
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to display this, and make it something
+ more to your liking. Currently, there is no configuration option for this.
+ You will have to modify, or create your own page, and use this to replace
+ <TT
+CLASS="FILENAME"
+>templates/blocked</TT
+>, which is what
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> uses to display the <SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+>
+ page.</P
+><P
+> Another way to deal with this is find why and where
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is blocking the frame, and 
+ diable this. Then let the <SPAN
+CLASS="QUOTE"
+>"+set-image-blocker"</SPAN
+> action 
+ handle the ad that is embedded in the frame's HTML page. </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="ALLISEEISRED"
+>3.12. I cannot see all of the <SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+> page banner. Help.</A
+></H3
+><P
+> There is not enough available space to fit the entire Blocked page. Try right
+ clicking on the visible portion, and select <SPAN
+CLASS="QUOTE"
+>"Show Frame"</SPAN
+>,
+ or equivalent. This will usually allow you to see the entire Privoxy
+ <SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+> page, and from there you can see just what is being
+ blocked, and why.</P
+><P
+> As of Privoxy 2.9.14, the Blocked banner page is re-sizeable, and tries
+ to adjust to the allotted space. There may be occassions where there 
+ just isn't enough room to display much of anything useful though. &#13;</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="SRVANY"
+>3.13. Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> run as a service 
+on Win2K/NT?</A
+></H3
+><P
+> Yes, it can run as a system service using <B
+CLASS="COMMAND"
+>srvany.exe</B
+>.
+ The only catch is that this will effectively disable the
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> icon in the taskbar. You can have 
+ one or the other, but not both at this time :( </P
+><P
+> There is a pending feature request for this functionality. See 
+ thread: <A
+HREF="http://sourceforge.net/tracker/?func=detail&atid=361118&aid=485617&group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?func=detail&#38;atid=361118&#38;aid=485617&#38;group_id=11118</A
+>, 
+ for details, and a sample configuration.&#13;</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="OTHERPROXY"
+>3.14. How can I make <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> work with other 
+proxies like <SPAN
+CLASS="APPLICATION"
+>Squid</SPAN
+>?</A
+></H3
+><P
+> This can be done. See the <A
+HREF="../user-manual/config.html#FORWARDING"
+TARGET="_top"
+>user manual</A
+>, 
+ which describes how to do this.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="TRANSPARENT"
+>3.15. Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> run as a <SPAN
+CLASS="QUOTE"
+>"transparent"</SPAN
+> proxy?</A
+></H3
+><P
+> No, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> currently does not have this ability, 
+ though it is planned for a future release. Transparent proxies require 
+ special handling of the request headers beyond what
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is now capable of.</P
+><P
+> Chaining <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with another proxy that has 
+ this ability should work though. 
+ See the <A
+HREF="../user-manual/config.html#FORWARDING"
+TARGET="_top"
+>user
+ manual</A
+>, which describes this, and also <A
+HREF="http://www.transproxy.nlc.net.au/"
+TARGET="_top"
+>http://www.transproxy.nlc.net.au/</A
+>.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="installation.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="misc.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Installation</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Miscellaneous</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/contact.html b/doc/webserver/faq/contact.html
new file mode 100644 (file)
index 0000000..7c8ff51
--- /dev/null
@@ -0,0 +1,309 @@
+<HTML
+><HEAD
+><TITLE
+>Contacting the developers, Bug Reporting and Feature Requests</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Troubleshooting"
+HREF="trouble.html"><LINK
+REL="NEXT"
+TITLE="Privoxy Copyright, License and History"
+HREF="copyright.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Frequently Asked Questions</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="trouble.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="copyright.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CONTACT"
+>6. Contacting the developers, Bug Reporting and Feature Requests</A
+></H1
+><P
+> We value your feedback. In fact, we rely on it to improve
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> and its configuration.
+ However, please note the following hints, so we can 
+ provide you with the best support:</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-SUPPORT"
+>6.1. Get Support</A
+></H2
+><P
+> For casual users, our support forum at
+ <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>SourceForge</A
+>
+ is probably best suited:
+ <A
+HREF="http://sourceforge.net/tracker/?group_id=11118&atid=211118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?group_id=11118&#38;atid=211118</A
+></P
+><P
+> All users are of course welcome to discuss their issues on the <A
+HREF="http://lists.sourceforge.net/lists/listinfo/ijbswa-users"
+TARGET="_top"
+>users
+ mailing list</A
+>, where the developers also hang around.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-BUGS"
+>6.2. Report Bugs</A
+></H2
+><P
+> Please report all bugs <I
+CLASS="EMPHASIS"
+>only</I
+> through our
+ bug tracker: 
+ <A
+HREF="http://sourceforge.net/tracker/?group_id=11118&atid=111118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?group_id=11118&#38;atid=111118</A
+>. </P
+><P
+>  Before doing so, please make sure that the bug has not already been submitted
+  and observe the aditional hints at the top of the <A
+HREF="http://sourceforge.net/tracker/?func=add&group_id=11118&atid=111118"
+TARGET="_top"
+>submit
+  form</A
+>.</P
+><P
+> 
+  Please try to verify that it is a <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> bug,
+  and not a browser or site bug first. If unsure,
+  try <A
+HREF="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>toggling
+  off</A
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and see if the problem persists.
+  The <A
+HREF="http://www.privoxy.org/user-manual/appendix.html#ACTIONSANAT"
+TARGET="_top"
+>appendix
+  of the user manual</A
+> also has helpful information 
+  on action debugging. If you are using your own custom configuration, please try
+  the stock configs to see if the problem is configuration related.</P
+><P
+>  If not using the latest version, chances are that the bug has been found
+  and fixed in the meantime. We would appreciate if you could take the time
+  to <A
+HREF="http://www.privoxy.org/user-manual/installation.html"
+TARGET="_top"
+>upgrade
+  to the latest version</A
+> (or  even the latest CVS snapshot) and verify
+  your bug, but this is not required for reporting.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-FEATURE"
+>6.3. Request New Features</A
+></H2
+><P
+> You are welcome to submit ideas on new features or other proposals
+ for improvement through our feature request tracker at
+ <A
+HREF="http://sourceforge.net/tracker/?atid=361118&group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?atid=361118&#38;group_id=11118</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-ADS"
+>6.4. Report Ads or Other Actions-Related Problems</A
+></H2
+><P
+> Please send feedback on ads that slipped through, innocent images that were blocked,
+ and any other problems relating to the <TT
+CLASS="FILENAME"
+>default.action</TT
+> file through
+ our actions feedback mechanism located at
+ <A
+HREF="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>http://www.privoxy.org/actions/</A
+>.
+ On this page, you will also find a bookmark which will take you back there from
+ any troubled site and even pre-fill the form!</P
+><P
+> New, improved <TT
+CLASS="FILENAME"
+>default.action</TT
+> files will occasionally be made
+ available based on your feedback. These will be announced on the <A
+HREF="http://lists.sourceforge.net/lists/listinfo/ijbswa-announce"
+TARGET="_top"
+>ijbswa-announce</A
+>
+ list and available from our <A
+HREF="http://sf.net/projects/ijbswa/"
+TARGET="_top"
+>project page</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-OTHER"
+>6.5. Other</A
+></H2
+><P
+>For any other issues, feel free to use the mailing lists. Technically interested users
+and people who wish to contribute to the project are also welcome on the developers list!
+You can find an overview of all <SPAN
+CLASS="APPLICATION"
+>Prixoxy</SPAN
+>-related mailing lists,
+including list archives, at:
+<A
+HREF="http://sourceforge.net/mail/?group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/mail/?group_id=11118</A
+>.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="trouble.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="copyright.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Troubleshooting</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Privoxy Copyright, License and History</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/copyright.html b/doc/webserver/faq/copyright.html
new file mode 100644 (file)
index 0000000..8a79af8
--- /dev/null
@@ -0,0 +1,301 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy Copyright, License and History</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Contacting the developers, Bug Reporting and Feature Requests"
+HREF="contact.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Frequently Asked Questions</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="contact.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+>&nbsp;</TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="COPYRIGHT"
+>7. Privoxy Copyright, License and History</A
+></H1
+><P
+> Copyright Â© 2001, 2002 by Privoxy Developers <TT
+CLASS="EMAIL"
+>&#60;<A
+HREF="mailto:developers@privoxy.org"
+>developers@privoxy.org</A
+>&#62;</TT
+></P
+><P
+> Some source code is based on code Copyright Â© 1997 by Anonymous Coders
+ and Junkbusters, Inc. and licensed under the <I
+CLASS="CITETITLE"
+>GNU General Public
+ License</I
+>.</P
+><P
+>   Portions of this document are <SPAN
+CLASS="QUOTE"
+>"borrowed"</SPAN
+> from the original
+   <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> (tm) FAQ, and modified as 
+   appropriate for <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+  </P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN666"
+>7.1. License</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is free software; you can
+ redistribute it and/or modify it under the terms of the 
+ <I
+CLASS="CITETITLE"
+>GNU General Public
+ License</I
+>, version 2, as published by the Free Software Foundation.</P
+><P
+> This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ <I
+CLASS="CITETITLE"
+>GNU General Public License</I
+> for
+ more details, which is available from the Free Software Foundation, Inc, 59
+ Temple Place - Suite 330, Boston, MA  02111-1307, USA.</P
+><P
+> You should have received a copy of the <A
+HREF="http://www.gnu.org/copyleft/gpl.html"
+TARGET="_top"
+> <I
+CLASS="CITETITLE"
+>GNU General Public License</I
+></A
+>
+ along with this program; if not, write to the <P
+CLASS="ADDRESS"
+>&nbsp;Free&nbsp;Software<br>
+&nbsp;Foundation,&nbsp;Inc.&nbsp;<SPAN
+CLASS="STREET"
+>59 Temple Place</SPAN
+>&nbsp;-&nbsp;Suite&nbsp;330<br>
+&nbsp;<SPAN
+CLASS="CITY"
+>Boston</SPAN
+>,&nbsp;<SPAN
+CLASS="STATE"
+>MA</SPAN
+>&nbsp;<SPAN
+CLASS="POSTCODE"
+>02111-1307</SPAN
+><br>
+&nbsp;<SPAN
+CLASS="COUNTRY"
+>USA</SPAN
+>&nbsp;</P
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN682"
+>7.2. History</A
+></H2
+><P
+> In the beginning, there was the
+ <A
+HREF="http://www.junkbusters.com/ijb.html"
+TARGET="_top"
+><SPAN
+CLASS="APPLICATION"
+>Internet Junkbuster</SPAN
+></A
+>, 
+ by Anonymous Coders and <A
+HREF="http://www.junkbusters.com/"
+TARGET="_top"
+>Junkbusters
+ Corporation</A
+>. It saved many users a lot of pain in the early days of
+ web advertising and user tracking.</P
+><P
+> But the web, its protocols and standards, and with it, the techniques for
+ forcing  users to consume ads, give up autonomy over their browsing, and
+ for spying on them, kept evolving. Unfortunately, the <SPAN
+CLASS="APPLICATION"
+>Internet
+ Junkbuster</SPAN
+> did not. Version 2.0.2, published in 1998, was 
+ (and is) the last official
+ <A
+HREF="http://www.junkbusters.com/ijbdist.html#release"
+TARGET="_top"
+>release</A
+>
+ available from <A
+HREF="http://www.junkbusters.com"
+TARGET="_top"
+>Junkbusters Corporation</A
+>.
+ Fortunately, it had been released under the GNU
+ <A
+HREF="http://www.gnu.org/licenses/gpl.html"
+TARGET="_top"
+> GPL</A
+>, which allowed further
+ development by others.</P
+><P
+> So Stefan Waldherr started maintaining an
+ <A
+HREF="http://www.waldherr.org/junkbuster/"
+TARGET="_top"
+>improved version of the
+ software</A
+>, to which eventually a number of people contributed patches.
+ It could already replace banners with a transparent image, and had a first
+ version of pop-up killing, but it was still very closely based on the
+ original, with all its limitations, such as the lack of HTTP/1.1 support,
+ flexible per-site configuration, or content modification. The last release
+ from this effort was version 2.0.2-10, published in 2000.</P
+><P
+> Then, some
+ <A
+HREF="http://www.privoxy.org/user-manual/copyright.html#AUTHORS"
+TARGET="_top"
+>developers</A
+>
+ picked up the thread, and started turning the software inside out, upside down,
+ and then reassembled it, adding many
+ <A
+HREF="http://www.privoxy.org/user-manual/introduction.html#FEATURES"
+TARGET="_top"
+>new
+ features</A
+> along the way.</P
+><P
+> The result of this is <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, whose first
+ stable release, 3.0, is due in May 2002.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="contact.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Contacting the developers, Bug Reporting and Feature Requests</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/general.html b/doc/webserver/faq/general.html
new file mode 100644 (file)
index 0000000..eadcc0f
--- /dev/null
@@ -0,0 +1,677 @@
+<HTML
+><HEAD
+><TITLE
+>General Information</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="NEXT"
+TITLE="Installation"
+HREF="installation.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Frequently Asked Questions</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="index.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="installation.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="GENERAL"
+>1. General Information</A
+></H1
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="NEWJB"
+>1.1. What is this new version of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></H3
+><P
+>  The original <SPAN
+CLASS="APPLICATION"
+><SPAN
+CLASS="TRADEMARK"
+>Internet
+  Junkbuster</SPAN
+>&trade;</SPAN
+> (tm) is a copyrighted product of <A
+HREF="http://www.junkbusters.com"
+TARGET="_top"
+>Junkbusters Corporation</A
+>.
+  Development of this effort stopped some time ago as of version 2.0.2. Stefan
+  Waldherr started the ijbswa project on <A
+HREF="http://sourceforge.net/projects/ijbswa/"
+TARGET="_top"
+>Sourceforge</A
+> to
+  rekindle development. Other developers subsequently joined with Stefan, and
+  have since added many new features, refinements and enhancements. The result
+  of this effort is <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+ </P
+><P
+>  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has evolved from the 
+  <SPAN
+CLASS="APPLICATION"
+>Junkbuster 2.0.2</SPAN
+> code base, and has advanced
+  significantly at this point. 
+ </P
+><P
+> 
+  Please see the <A
+HREF="copyright.html"
+>History section</A
+> for more
+  information on the history of <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> and 
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN39"
+>1.2. Why <SPAN
+CLASS="QUOTE"
+>"Privoxy"</SPAN
+>? Why a name change at all?</A
+></H3
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is the 
+ <SPAN
+CLASS="QUOTE"
+>"<I
+CLASS="EMPHASIS"
+>Privacy Enhancing Proxy</I
+>"</SPAN
+>.</P
+><P
+> There are potential legal complications from the continued use of the 
+ <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> name, which is a registered trademark of 
+ <A
+HREF="http://junkbusters.com"
+TARGET="_top"
+>Junkbusters Corporation</A
+>.
+ And thus they <SPAN
+CLASS="QUOTE"
+>"own"</SPAN
+> the rights to the name.
+ (There are, however, no objections from Junkbusters Corporation to the 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> project itself, and they, in fact, still
+ share our ideals and goals.)</P
+><P
+> The developers also believed that there are so many changes from the original 
+ code, that it was time to make a clean break from the past and make 
+ a name in their own right, especially now with the pending
+ release of version 3.0.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="DIFFERS"
+>1.3. How does <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> differ
+from the old <SPAN
+CLASS="APPLICATION"
+>Junkbuster?</SPAN
+></A
+></H3
+><P
+>  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> picks up where
+  <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> left off. All the old features remain.
+  The new <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> still blocks ads and banners,
+  still manages cookies, and still helps protect your privacy. But, these are
+  all enhanced, and many new features have been added, all in the same vein.
+ </P
+><P
+>  The configuration has changed significantly as well. This is something that
+  users will notice right off the bat if you are upgrading from 
+  <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> 2.0.x. The <SPAN
+CLASS="QUOTE"
+>"blocklist"</SPAN
+>
+  file does not exist any more. This is replaced by <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+>
+  files, such as <TT
+CLASS="FILENAME"
+>default.actions</TT
+>. This is where most of
+  the per site configuration is now.
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="FEATURES"
+>1.4. What are some of the new features?</A
+></H3
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>   Integrated browser based configuration and control utility at <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>
+   (shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>). Browser-based
+   tracing of rule and filter effects. Remote toggling.
+  </P
+></LI
+><LI
+><P
+>   Web page content filtering (removes banners based on size,
+   invisible <SPAN
+CLASS="QUOTE"
+>"web-bugs"</SPAN
+>, JavaScript and HTML annoyances, pop-up windows, etc.)
+  </P
+></LI
+><LI
+><P
+>   Modularized configuration that allows for standard settings and
+   user settings to reside in separate files, so that installing updated
+   actions files won't overwrite individual user settings.
+  </P
+></LI
+><LI
+><P
+>   HTTP/1.1 compliant (but not all optional 1.1 features are supported).
+  </P
+></LI
+><LI
+><P
+>   Support for Perl Compatible Regular Expressions in the configuration files, and 
+   generally a more sophisticated and flexible configuration syntax over
+   previous versions.
+  </P
+></LI
+><LI
+><P
+>   Improved cookie management features (e.g. session based cookies).
+  </P
+></LI
+><LI
+><P
+>   GIF de-animation. 
+  </P
+></LI
+><LI
+><P
+>   Bypass many click-tracking scripts (avoids script redirection).
+  </P
+></LI
+><LI
+><P
+>   Multi-threaded (POSIX and native threads).
+  </P
+></LI
+><LI
+><P
+>   User-customizable HTML templates for all proxy-generated pages (e.g. "blocked" page).
+  </P
+></LI
+><LI
+><P
+>   Auto-detection and re-reading of config file changes.
+  </P
+></LI
+><LI
+><P
+>   Improved signal handling, and a true daemon mode (Unix).
+  </P
+></LI
+><LI
+><P
+>   Every feature now controllable on a per-site or per-location basis, configuration
+   more powerful and versatile over-all.
+  </P
+></LI
+><LI
+><P
+>   Many smaller new features added, limitations and bugs removed, and security holes fixed.
+  </P
+></LI
+></UL
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="PROXYMORON"
+>1.5. What is a <SPAN
+CLASS="QUOTE"
+>"proxy"</SPAN
+>? How does
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> work?</A
+></H3
+><P
+>  When you connect to a web site with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, 
+  you are really connecting to your locally running version of 
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+  intercepts your requests for the web page, and relays that to the 
+  <SPAN
+CLASS="QUOTE"
+>"real"</SPAN
+> web site. The web site sends the HTTP data stream 
+  back to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, where
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can work its magic before it 
+  relays this data back to your web browser.
+ </P
+><P
+>  Since <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> sits between you and the 
+  WWW, it is in a position to intercept and completely manage all web traffic and 
+  HTTP content before it gets to your browser.
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> uses various programming methods to do
+  this, all of which is under your control via the various configuration
+  files and options.
+ </P
+><P
+>  There are many kinds of proxies. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> best 
+  fits the <SPAN
+CLASS="QUOTE"
+>"filtering proxy"</SPAN
+> category.
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN117"
+>1.6. How does <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> know what is
+an ad, and what is not?</A
+></H3
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> processes all the raw content of every 
+ web page. So it reads everything on each page. It then compares this to the
+ rules as set up in the configuration files, and looks for any matches to
+ these rules. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> makes heavy use of
+ <SPAN
+CLASS="QUOTE"
+>"regular expressions"</SPAN
+>. (If you are not familiar with regular
+ expressions, it is explained briefly in <A
+HREF="../user-manual/appendix.html"
+TARGET="_top"
+>the user manual</A
+>.) Regular
+ expressions facilitate matching of one text string against another, using
+ wildcards to build complex patterns. So <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ will typically look for URLs and other content that match certain key words
+ and expressions as defined in the configuration files. For instance a URL
+ that contains <SPAN
+CLASS="QUOTE"
+>"/banners"</SPAN
+>, has a high probability of containing
+ ad banners, and thus would be a prime candidate to have a matching rule.</P
+><P
+> So <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will look for these kinds of obvious 
+ looking culprits. And also, will use lists of known organizations that
+ specialize in ads. Again, using complex patterns to match as many potential 
+ combinations as possible since there tend to be many, many variations used by 
+ advertisers, and new ones are being introduced all the time.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN129"
+>1.7. Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> make mistakes? 
+This does not sound very scientific.</A
+></H3
+><P
+> Actually, it's a black art ;-) And yes, it is always possible to have a broad rule
+ accidentally block something by mistake. There is a good chance you may run 
+ into such a situation at some point. It is tricky writing rules to cover
+ every conceivable possibility, and not occasionally get false positives.</P
+><P
+> But this should not be a big concern since the
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> configuration is very flexible, and
+ includes tools to help identify these types of situations so they can be
+ addressed as needed, allowing you to customize your installation.
+ (<A
+HREF="trouble.html#AEN589"
+>See the Troubleshooting section below</A
+>.)</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="BROWSERS2"
+>1.8. My browser does the same things as
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Why should I use
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> at all?</A
+></H3
+><P
+>  Modern browsers do indeed have <I
+CLASS="EMPHASIS"
+>some</I
+> of the same
+  functionality as <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Maybe this is
+  adequate for you. But <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is much more
+  versatile and powerful, and can do a number of things that browsers just can't.
+ </P
+><P
+>  In addition, a proxy is good choice if you use multiple browsers, or 
+  have a LAN with multiple computers. This way all the configuration 
+  is in one place, and you don't have to maintain a similar configuration 
+  for possibly many browsers.
+
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="LICENSE"
+>1.9. Is there is a license or fee? What about a 
+warranty? Registration?</A
+></H3
+><P
+>  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is licensed under the GNU General Public
+  License (GPL). It is free to use, copy, modify or distribute as you wish
+  under the terms of this license.  Please see the <A
+HREF="copyright.html"
+>Copyright</A
+> section for more information on the
+  license and copyright. Or the <TT
+CLASS="FILENAME"
+>LICENSE</TT
+> file 
+  that should be included.
+
+  </P
+><P
+>  There is no warranty of any kind, expressed, implied or otherwise. That is
+  something that would cost real money ;-) There is no registration either.
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> really is <I
+CLASS="EMPHASIS"
+>free</I
+>
+  in every respect!
+
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="JOINTEAM"
+>1.10. I would like to help you, what do I do?</A
+></H3
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="JOINTEAM-MONEY"
+>1.10.1. Money Money Money</A
+></H4
+><P
+> We, of course, welcome donations and use the money for domain registering,
+ regular world-wide get-togethers (hahaha). Anyway, we'll soon describe the
+ process how to donate money to the team.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="JOINTEAM-WORK"
+>1.10.2. You want to work with us?</A
+></H4
+><P
+>   Well, helping the team is always a good idea. We welcome new developers,
+   RPM gurus or documentation makers. Simply get an account on sourceforge.net
+   and mail your id to the developer mailing list. Then read the
+   section Quickstart in the <A
+HREF="../developer-manual/quickstart.html"
+TARGET="_top"
+>   Developer's Manual</A
+>.</P
+><P
+> Once we have added you to the team, you'll have write access to the CVS
+ repository, and together we'll find a suitable task for you.</P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="index.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="installation.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Privoxy Frequently Asked Questions</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Installation</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/index.html b/doc/webserver/faq/index.html
new file mode 100644 (file)
index 0000000..b6cba2e
--- /dev/null
@@ -0,0 +1,682 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy Frequently Asked Questions</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="NEXT"
+TITLE="General Information"
+HREF="general.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="AEN2"
+>Privoxy Frequently Asked Questions</A
+></H1
+><P
+CLASS="PUBDATE"
+> <SUB
+> <A
+HREF="copyright.html"
+>Copyright</A
+> Â© 2001, 2002 by 
+ <A
+HREF="http://www.privoxy.org"
+TARGET="_top"
+>Privoxy Developers</A
+>
+ </SUB
+><BR></P
+><P
+CLASS="PUBDATE"
+>$Id: faq.sgml,v 1.59 2002/05/15 04:03:30 hal9 Exp $<BR></P
+><DIV
+><DIV
+CLASS="ABSTRACT"
+><A
+NAME="AEN9"
+></A
+><P
+></P
+><P
+> This FAQ gives users and developers alike answers to frequently asked
+ questions about <A
+HREF="http://www.privoxy.org"
+TARGET="_top"
+>Privoxy</A
+> 
+ .
+ </P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is a web proxy with advanced filtering
+ capabilities for protecting privacy, filtering web page content, managing
+ cookies, controlling access, and removing ads, banners, pop-ups and other
+ obnoxious Internet junk. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has a very
+ flexible configuration and can be customized to suit individual needs and
+ tastes. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has application for both
+ stand-alone systems and multi-user networks.</P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is based on <SPAN
+CLASS="APPLICATION"
+>Internet
+ Junkbuster</SPAN
+> (tm).</P
+><P
+>  You can find the latest version of the document at <A
+HREF="http://www.privoxy.org/faq/"
+TARGET="_top"
+>http://www.privoxy.org/faq/</A
+>.
+  Please see the Contact section if you want to contact the developers.
+ </P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="general.html"
+>General Information</A
+></DT
+><DD
+><DL
+><DT
+>1.1. <A
+HREF="general.html#NEWJB"
+>What is this new version of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></DT
+><DT
+>1.2. <A
+HREF="general.html#AEN39"
+>Why <SPAN
+CLASS="QUOTE"
+>"Privoxy"</SPAN
+>? Why a name change at all?</A
+></DT
+><DT
+>1.3. <A
+HREF="general.html#DIFFERS"
+>How does <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> differ
+from the old <SPAN
+CLASS="APPLICATION"
+>Junkbuster?</SPAN
+></A
+></DT
+><DT
+>1.4. <A
+HREF="general.html#FEATURES"
+>What are some of the new features?</A
+></DT
+><DT
+>1.5. <A
+HREF="general.html#PROXYMORON"
+>What is a <SPAN
+CLASS="QUOTE"
+>"proxy"</SPAN
+>? How does
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> work?</A
+></DT
+><DT
+>1.6. <A
+HREF="general.html#AEN117"
+>How does <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> know what is
+an ad, and what is not?</A
+></DT
+><DT
+>1.7. <A
+HREF="general.html#AEN129"
+>Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> make mistakes? 
+This does not sound very scientific.</A
+></DT
+><DT
+>1.8. <A
+HREF="general.html#BROWSERS2"
+>My browser does the same things as
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Why should I use
+<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> at all?</A
+></DT
+><DT
+>1.9. <A
+HREF="general.html#LICENSE"
+>Is there is a license or fee? What about a 
+warranty? Registration?</A
+></DT
+><DT
+>1.10. <A
+HREF="general.html#JOINTEAM"
+>I would like to help you, what do I do?</A
+></DT
+><DD
+><DL
+><DT
+>1.10.1. <A
+HREF="general.html#JOINTEAM-MONEY"
+>Money Money Money</A
+></DT
+><DT
+>1.10.2. <A
+HREF="general.html#JOINTEAM-WORK"
+>You want to work with us?</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>2. <A
+HREF="installation.html"
+>Installation</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="installation.html#WHICHBROWSERS"
+>Which browsers are supported by <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></DT
+><DT
+>2.2. <A
+HREF="installation.html#WHICHOS"
+>Which operating systems are supported?</A
+></DT
+><DT
+>2.3. <A
+HREF="installation.html#NEWINSTALL"
+>Can I install  
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> over <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>?</A
+></DT
+><DT
+>2.4. <A
+HREF="installation.html#AEN191"
+>I just installed <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Is there anything 
+special I have to do now?</A
+></DT
+><DT
+>2.5. <A
+HREF="installation.html#LOCALHOST"
+>What is the proxy address of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></DT
+><DT
+>2.6. <A
+HREF="installation.html#AEN216"
+>I just installed <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and nothing is happening.
+All the ads are there. What's wrong?</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="configuration.html"
+>Configuration</A
+></DT
+><DD
+><DL
+><DT
+>3.1. <A
+HREF="configuration.html#NEWCONFIG"
+>Can I use my old config files?</A
+></DT
+><DT
+>3.2. <A
+HREF="configuration.html#AEN234"
+>What is an <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> file?</A
+></DT
+><DT
+>3.3. <A
+HREF="configuration.html#ACTIONSS"
+>The <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> concept confuses me. Please list 
+some of these <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+>.</A
+></DT
+><DT
+>3.4. <A
+HREF="configuration.html#AEN249"
+>How are actions files configured? What is the easiest
+way to do this?</A
+></DT
+><DT
+>3.5. <A
+HREF="configuration.html#AEN257"
+>There are several different <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> files. What are
+the differences?</A
+></DT
+><DT
+>3.6. <A
+HREF="configuration.html#BROWSECONFIG"
+>Why can I change the configuration with a
+browser? Does that not raise security issues?</A
+></DT
+><DT
+>3.7. <A
+HREF="configuration.html#AEN283"
+>What is <SPAN
+CLASS="QUOTE"
+>"default.filter"</SPAN
+>?</A
+></DT
+><DT
+>3.8. <A
+HREF="configuration.html#AEN296"
+>How can I set up <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to act as a proxy for my 
+ LAN?</A
+></DT
+><DT
+>3.9. <A
+HREF="configuration.html#AEN308"
+>Instead of ads, now I get a checkerboard pattern. I don't want to see anything.</A
+></DT
+><DT
+>3.10. <A
+HREF="configuration.html#AEN327"
+>Why would anybody want to see a checkerboard pattern?</A
+></DT
+><DT
+>3.11. <A
+HREF="configuration.html#AEN332"
+>I see large red banners on some pages that say 
+<SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+>. Why and how do I get rid of this?</A
+></DT
+><DT
+>3.12. <A
+HREF="configuration.html#ALLISEEISRED"
+>I cannot see all of the <SPAN
+CLASS="QUOTE"
+>"Blocked"</SPAN
+> page banner. Help.</A
+></DT
+><DT
+>3.13. <A
+HREF="configuration.html#SRVANY"
+>Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> run as a service 
+on Win2K/NT?</A
+></DT
+><DT
+>3.14. <A
+HREF="configuration.html#OTHERPROXY"
+>How can I make <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> work with other 
+proxies like <SPAN
+CLASS="APPLICATION"
+>Squid</SPAN
+>?</A
+></DT
+><DT
+>3.15. <A
+HREF="configuration.html#TRANSPARENT"
+>Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> run as a <SPAN
+CLASS="QUOTE"
+>"transparent"</SPAN
+> proxy?</A
+></DT
+></DL
+></DD
+><DT
+>4. <A
+HREF="misc.html"
+>Miscellaneous</A
+></DT
+><DD
+><DL
+><DT
+>4.1. <A
+HREF="misc.html#AEN396"
+>How much does <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> slow my browsing down? This 
+has to add extra time to browsing.</A
+></DT
+><DT
+>4.2. <A
+HREF="misc.html#LOADINGTIMES"
+>I noticed considerable
+delays in page requests compared to the old Junkbuster. What's wrong?</A
+></DT
+><DT
+>4.3. <A
+HREF="misc.html#CONFIGURL"
+>What is the "http://p.p/"?</A
+></DT
+><DT
+>4.4. <A
+HREF="misc.html#BLOCKLIST"
+>Do you still maintain the blocklists?</A
+></DT
+><DT
+>4.5. <A
+HREF="misc.html#NEWADS"
+>How can I submit new ads?</A
+></DT
+><DT
+>4.6. <A
+HREF="misc.html#IP"
+>How can I hide my IP address?</A
+></DT
+><DT
+>4.7. <A
+HREF="misc.html#AEN447"
+>Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> guarantee I am anonymous?</A
+></DT
+><DT
+>4.8. <A
+HREF="misc.html#AEN458"
+>Might some things break because header information is
+being altered?</A
+></DT
+><DT
+>4.9. <A
+HREF="misc.html#AEN468"
+>Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> act as a <SPAN
+CLASS="QUOTE"
+>"caching"</SPAN
+> proxy to 
+speed up web browsing?</A
+></DT
+><DT
+>4.10. <A
+HREF="misc.html#AEN476"
+>What about as a firewall? Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> protect me?</A
+></DT
+><DT
+>4.11. <A
+HREF="misc.html#AEN481"
+>The <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> logo that replaces ads is very blocky 
+and ugly looking. Can't a better font be used?</A
+></DT
+><DT
+>4.12. <A
+HREF="misc.html#AEN490"
+>I have large empty spaces now where ads used to be. 
+Why?</A
+></DT
+><DT
+>4.13. <A
+HREF="misc.html#AEN493"
+>How can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> filter Secure (HTTPS) URLs?</A
+></DT
+><DT
+>4.14. <A
+HREF="misc.html#AEN500"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> runs as a <SPAN
+CLASS="QUOTE"
+>"server"</SPAN
+>. How 
+secure is it? Do I need to take any special precautions?</A
+></DT
+><DT
+>4.15. <A
+HREF="misc.html#TURNOFF"
+>How can I temporarily disable <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></DT
+><DT
+>4.16. <A
+HREF="misc.html#SEEALSO"
+>Where can I find more information about <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+and related issues?</A
+></DT
+></DL
+></DD
+><DT
+>5. <A
+HREF="trouble.html"
+>Troubleshooting</A
+></DT
+><DD
+><DL
+><DT
+>5.1. <A
+HREF="trouble.html#AEN570"
+>I just upgraded and am getting <SPAN
+CLASS="QUOTE"
+>"connection refused"</SPAN
+>
+with every web page?</A
+></DT
+><DT
+>5.2. <A
+HREF="trouble.html#AEN583"
+>I just added a new rule, but the steenkin ad is 
+still getting through. How?</A
+></DT
+><DT
+>5.3. <A
+HREF="trouble.html#AEN589"
+>One of my favorite sites does not work with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+What can I do?</A
+></DT
+></DL
+></DD
+><DT
+>6. <A
+HREF="contact.html"
+>Contacting the developers, Bug Reporting and Feature Requests</A
+></DT
+><DD
+><DL
+><DT
+>6.1. <A
+HREF="contact.html#CONTACT-SUPPORT"
+>Get Support</A
+></DT
+><DT
+>6.2. <A
+HREF="contact.html#CONTACT-BUGS"
+>Report Bugs</A
+></DT
+><DT
+>6.3. <A
+HREF="contact.html#CONTACT-FEATURE"
+>Request New Features</A
+></DT
+><DT
+>6.4. <A
+HREF="contact.html#CONTACT-ADS"
+>Report Ads or Other Actions-Related Problems</A
+></DT
+><DT
+>6.5. <A
+HREF="contact.html#CONTACT-OTHER"
+>Other</A
+></DT
+></DL
+></DD
+><DT
+>7. <A
+HREF="copyright.html"
+>Privoxy Copyright, License and History</A
+></DT
+><DD
+><DL
+><DT
+>7.1. <A
+HREF="copyright.html#AEN666"
+>License</A
+></DT
+><DT
+>7.2. <A
+HREF="copyright.html#AEN682"
+>History</A
+></DT
+></DL
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="general.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>General Information</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/installation.html b/doc/webserver/faq/installation.html
new file mode 100644 (file)
index 0000000..87fa8c7
--- /dev/null
@@ -0,0 +1,375 @@
+<HTML
+><HEAD
+><TITLE
+>Installation</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="General Information"
+HREF="general.html"><LINK
+REL="NEXT"
+TITLE="Configuration"
+HREF="configuration.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Frequently Asked Questions</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="general.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="configuration.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="INSTALLATION"
+>2. Installation</A
+></H1
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="WHICHBROWSERS"
+>2.1. Which browsers are supported by <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></H3
+><P
+> Any browser that can be configured to use a <SPAN
+CLASS="QUOTE"
+>"proxy"</SPAN
+>, which 
+ should be virtually all browsers. Direct browser support is not necessary
+ since <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> runs as a separate application and
+ just exchanges standard HTML data with your browser, just like a web server
+ does.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="WHICHOS"
+>2.2. Which operating systems are supported?</A
+></H3
+><P
+> At present, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is known to run on
+ Windows(95, 98, ME, 2000, XP), Linux (RedHat, Suse, Debian), Mac OSX,
+ OS/2, AmigaOS, FreeBSD, NetBSD, BeOS, and many more flavors of Unix.</P
+><P
+> But any operating system that runs TCP/IP, can conceivably take advantage of
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> in a networked situation where
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> would run as a server on a LAN gateway. 
+ Then only the <SPAN
+CLASS="QUOTE"
+>"gateway"</SPAN
+> needs to be running one of the above
+ operating systems. </P
+><P
+> Source code is freely available, so porting to other operating systems, 
+ is always a possibility.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="NEWINSTALL"
+>2.3. Can I install  
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> over <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>?</A
+></H3
+><P
+>   We recommend you uninstall <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>
+   first to minimize conflicts and confusion. You may want to 
+   save your old configuration files for future reference. The configuration
+   is substantially changed.
+ </P
+><P
+>  See the <A
+HREF="../user-manual/index.html"
+TARGET="_top"
+>user-manual</A
+> for
+  platform specific installation instructions.
+ </P
+><P
+>  Note: Some installers may automatically uninstall
+  <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>, if present!
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN191"
+>2.4. I just installed <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Is there anything 
+special I have to do now?</A
+></H3
+><P
+> All browsers must be told to use <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> 
+ as a proxy by specifying the correct proxy address and port number 
+ in the appropriate configuration area for the browser. See below.
+ Also, you should flush your browser's memory and disk cache to get rid of any
+ cached items.&#13;</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="LOCALHOST"
+>2.5. What is the proxy address of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></H3
+><P
+>  If you set up the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to run on
+  the computer you browse from (rather than your ISP's server or some
+  networked computer on a LAN), the proxy will be on <SPAN
+CLASS="QUOTE"
+>"localhost"</SPAN
+>
+  (which is the special name used by every computer on the Internet to refer
+  to itself) and the port will be 8118 (unless you have <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to run on a different port with the
+  <I
+CLASS="EMPHASIS"
+>listen-address</I
+> config option). 
+ </P
+><P
+>  When configuring your browser's proxy settings you typically enter
+  the word <SPAN
+CLASS="QUOTE"
+>"localhost"</SPAN
+> in the boxes next to <SPAN
+CLASS="QUOTE"
+>"HTTP"</SPAN
+>
+  and <SPAN
+CLASS="QUOTE"
+>"Secure"</SPAN
+> (HTTPS) and then the number <SPAN
+CLASS="QUOTE"
+>"8118"</SPAN
+>
+  for <SPAN
+CLASS="QUOTE"
+>"port"</SPAN
+>.  This tells your browser to send all web 
+  requests to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> instead of directly to the 
+  Internet.
+ </P
+><P
+>  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can also be used to proxy for 
+  a Local Area Network. In this case, your would enter either the IP 
+  address of the LAN host where <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> 
+  is running, or the equivalent hostname. Port assignment would be 
+  same as above.
+ </P
+><P
+>  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> does not currently handle
+  protocols such as FTP, SMTP, IM, IRC, ICQ, or other Internet
+  protocols. 
+ </P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN216"
+>2.6. I just installed <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and nothing is happening.
+All the ads are there. What's wrong?</A
+></H3
+><P
+> Did you configure your browser to use <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> 
+ as a proxy? It does not sound like it. See above. You might also try flushing
+ the browser's caches to force a full re-reading of pages. You can verify 
+ that <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is running, and your browser 
+ is correctly configured by entering the special URL: 
+ <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>. This should give you 
+ a banner that says <SPAN
+CLASS="QUOTE"
+>"This is Privoxy"</SPAN
+> and 
+ access to <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> internal configuration. 
+ If you see this, then you are good to go. If not, the browser or 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> are not set up correctly.&#13;</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="general.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="configuration.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>General Information</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Configuration</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/misc.html b/doc/webserver/faq/misc.html
new file mode 100644 (file)
index 0000000..df6c40b
--- /dev/null
@@ -0,0 +1,911 @@
+<HTML
+><HEAD
+><TITLE
+>Miscellaneous</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Configuration"
+HREF="configuration.html"><LINK
+REL="NEXT"
+TITLE="Troubleshooting"
+HREF="trouble.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Frequently Asked Questions</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="configuration.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="trouble.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="MISC"
+>4. Miscellaneous</A
+></H1
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN396"
+>4.1. How much does <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> slow my browsing down? This 
+has to add extra time to browsing.</A
+></H3
+><P
+> It should not slow you down any in real terms, and may actually help 
+ speed things up since ads, banners and other junk are not being displayed.
+ The actual processing time required by <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> 
+ itself for each page, is relatively small in the overall scheme of things,
+ and happens very quickly. This is typically more than offset by time saved
+ not downloading and rendering ad images.</P
+><P
+> <SPAN
+CLASS="QUOTE"
+>"Filtering"</SPAN
+> via the <TT
+CLASS="FILENAME"
+>filterfile</TT
+> 
+ mechanism may cause a perceived slowdown, since the entire page is buffered
+ before displaying. See below.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="LOADINGTIMES"
+>4.2. I noticed considerable
+delays in page requests compared to the old Junkbuster. What's wrong?</A
+></H3
+><P
+>The entire page content must be loaded into memory in order for the filtering 
+mechanism to work, and nothing is sent to the browser during this time. The
+loading time does not really change in real numbers, but the feeling is
+different, because most browsers are able to start rendering incomplete
+content, giving the user a feeling of "it works". 
+ </P
+><P
+> To modify the content of a page (i.e. make frames resizeable again, etc.) and
+ not just replace ads, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> needs to download
+ the entire page first, do its content magic and then send the page to the
+ browser.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="CONFIGURL"
+>4.3. What is the "http://p.p/"?</A
+></H3
+><P
+>Since <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> sits between your web browser and the Internet, it can be
+programmed to handle certain pages specially.</P
+><P
+> With recent versions of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> (version 2.9.x and
+ greater), you can get some information about
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> and change some settings by going to
+ <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+> or, equivalently, <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+> (Note
+ that p.p is far easier to type but may not work in some configurations. With
+ the name change to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, this is changed from
+ the previous http://i.j.b/ and earlier 2.9.x versions).</P
+><P
+> These pages are <I
+CLASS="EMPHASIS"
+>not</I
+> forwarded to a server on the
+ Internet - instead they are handled by a special web server which is built in to
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.</P
+><P
+> If you are not running <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, then <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+> will fail, and <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+> will
+ return a web page telling you you're not running
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.</P
+><P
+> If you have version 2.0.2, then the equivalent is
+ http://example.com/show-proxy-args (but you get far less information, and
+ you should really consider upgrading to 2.9.15).</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="BLOCKLIST"
+>4.4. Do you still maintain the blocklists?</A
+></H3
+><P
+>    No, not by this name. The format of the blocklists has changed
+    significantly in versions 2.9.x and later. This functionality 
+    is done by the <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> file now. See next question ...</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="NEWADS"
+>4.5. How can I submit new ads?</A
+></H3
+><P
+>Please see the <A
+HREF="contact.html"
+>Contact section</A
+>.</P
+><P
+> This process does not work with earlier versions of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ or <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="IP"
+>4.6. How can I hide my IP address?</A
+></H3
+><P
+> You cannot hide your IP address with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> or any other software, since
+the server needs to know your IP address to send the answers back to you.</P
+><P
+>Fortunately there are many publicly usable anonymous proxies out there, which
+solve the problem by providing a further level of indirection between you and
+the web server, shared by many people and thus letting your requests "drown"
+in white noise of unrelated requests as far as user tracking is concerned.</P
+><P
+>Most of them will, however, log your IP address and make it available to the
+authorities in case you abuse that anonymity for criminal purposes. In fact
+you can't even rule out that some of them only exist to *collect* information
+on (those suspicious) people with a more than average preference for privacy.</P
+><P
+>You can find a list of anonymous public proxies at <A
+HREF="http://www.multiproxy.org/anon_list.htm"
+TARGET="_top"
+>multiproxy.org</A
+> and many
+more through Google.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN447"
+>4.7. Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> guarantee I am anonymous?</A
+></H3
+><P
+> No. Your chances of remaining anonymous are greatly improved, but unless you
+ are an expert on Internet security it would be safest to assume that
+ everything you do on the Web can be traced back to you.</P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can remove various information about you,
+ and allows <I
+CLASS="EMPHASIS"
+>you</I
+> more freedom  to decide which sites 
+ you can trust, and what details you want to reveal. But it's still possible
+ that web sites can find out who you are. Here's one way this can happen.</P
+><P
+> A few browsers disclose the user's email address in certain situations, such
+ as when transferring a file by FTP. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ does not filter FTP. If you need this feature, or are concerned about the
+ mail handler of your browser disclosing your email address, you might
+ consider products such as <SPAN
+CLASS="APPLICATION"
+>NSClean</SPAN
+>.</P
+><P
+> Browsers available only as binaries could use non-standard headers to give
+ out any information they can have access to: see the manufacturer's license
+ agreement. It's impossible to anticipate and prevent every breach of privacy
+ that might occur. The professionally paranoid prefer browsers available as
+ source code, because anticipating their behavior is easier. Trust the source,
+ Luke!</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN458"
+>4.8. Might some things break because header information is
+being altered?</A
+></H3
+><P
+> Definitely. More and more sites use HTTP header content to decide what to
+ display and how to display it. There is many ways that this can be handled, 
+ so having hard and fast rules, is tricky.</P
+><P
+> <SPAN
+CLASS="QUOTE"
+>"USER AGENT"</SPAN
+> in particular is often used in this way to identify
+ the browser, and adjust content accordingly. Changing this now is not
+ recommended, since so many sites do look for this. You may get undesirable 
+ results by changing this.</P
+><P
+> For instance, different browsers use different encodings of Russian and Czech
+ characters, certain web servers convert pages on-the-fly according to the
+ User Agent header. Giving a <SPAN
+CLASS="QUOTE"
+>"User Agent"</SPAN
+> with the wrong
+ operating system or browser manufacturer causes some sites in these languages
+ to be garbled; Surfers to Eastern European sites should change it to
+ something closer. And then some page access counters work by looking at the
+ <SPAN
+CLASS="QUOTE"
+>"REFERER"</SPAN
+> header; they may fail or break if unavailable. The
+ weather maps of Intellicast have been blocked by their server when no
+ <SPAN
+CLASS="QUOTE"
+>"REFERER"</SPAN
+> or cookie is provided, is another example. There are
+ many, many other ways things can go wrong when trying to fool a web server.</P
+><P
+> If you have problems with a site, you will have to adjust your configuration 
+ accordingly. Cookies are probably the most likely adjustment that may 
+ be required, but by no means the only one.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN468"
+>4.9. Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> act as a <SPAN
+CLASS="QUOTE"
+>"caching"</SPAN
+> proxy to 
+speed up web browsing?</A
+></H3
+><P
+> No, it does not have this ability at all. You want something like 
+ <A
+HREF="http://www.squid-cache.org/"
+TARGET="_top"
+>Squid</A
+> for this. And, yes, 
+ before you ask, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can co-exist 
+ with other kinds of proxies like <SPAN
+CLASS="APPLICATION"
+>Squid</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN476"
+>4.10. What about as a firewall? Can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> protect me?</A
+></H3
+><P
+> Not in the way you mean, or in the way a true firewall can, or a proxy that
+ has this specific capability. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can help
+ protect your privacy, but not really protect you from intrusion attempts.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN481"
+>4.11. The <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> logo that replaces ads is very blocky 
+and ugly looking. Can't a better font be used?</A
+></H3
+><P
+> This is not a font problem. The logo is an image that is created by 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> on the fly. So as to not waste 
+ memory, the image is rather small. The blockiness comes when the 
+ image is scaled to fill a largish area. There is not much to be done 
+ about this, other than to use one of the other
+ <SPAN
+CLASS="QUOTE"
+>"imageblock"</SPAN
+> directives: <I
+CLASS="EMPHASIS"
+>pattern</I
+>, 
+ <I
+CLASS="EMPHASIS"
+>blank</I
+>, or a URL of your choosing.</P
+><P
+>Given the above problem, we have decided to remove the logo option entirely 
+[as of v2.9.13].</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN490"
+>4.12. I have large empty spaces now where ads used to be. 
+Why?</A
+></H3
+><P
+> It would be easy enough to just eliminate this space altogether, rather than
+ fill it with blank space. But, this would create problems with many pages
+ that use the overall size of the ad to help organize the page layout and
+ position the various components of the page where they were intended to be.
+ It is best left this way.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN493"
+>4.13. How can <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> filter Secure (HTTPS) URLs?</A
+></H3
+><P
+> This is a limitation since HTTPS transactions are encrypted SSL sessions
+ between your browser and the secure site, and are meant to be reliably 
+ <I
+CLASS="EMPHASIS"
+>secure</I
+> and private. This means that all cookies and HTTP
+ header information are also encrypted from the time they leave your browser,
+ to the site, and vice versa. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> does not
+ try to unencrypt this information, so it just passes through as is.
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can still catch images and ads that
+ are embedded in the SSL stream though.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN500"
+>4.14. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> runs as a <SPAN
+CLASS="QUOTE"
+>"server"</SPAN
+>. How 
+secure is it? Do I need to take any special precautions?</A
+></H3
+><P
+> There are no known exploits that might effect
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. On Unix-like systems, 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can run as a non-privileged 
+ user, which is how we recommend it be run. Also, by default 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> only listens to requests 
+ from <SPAN
+CLASS="QUOTE"
+>"localhost"</SPAN
+>. The server aspect of
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is not itself directly exposed to the
+ Internet in this configuration. If you want to have
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> serve as a LAN proxy, this will have to
+ be opened up to allow for LAN requests. In this case, we'd recommend
+ you specify only the LAN gateway address, e.g. 192.168.1.1, in the main 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> config file. All LAN hosts can then use 
+ this as their proxy address in the browser proxy configuration. In this way, 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will not listen on any external ports.
+ Of course, a firewall is always good too. Better safe than sorry.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="TURNOFF"
+>4.15. How can I temporarily disable <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>?</A
+></H3
+><P
+> The easiest way is to access <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with your 
+ browser by using the special URL: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>
+ and select "Toggle Privoxy on or off" from that page.&#13;</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="SEEALSO"
+>4.16. Where can I find more information about <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+and related issues?</A
+></H3
+><P
+> Other references and sites of interest to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ users:</P
+><P
+> <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/"
+TARGET="_top"
+>http://www.privoxy.org/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Home page. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/faq/"
+TARGET="_top"
+>http://www.privoxy.org/faq/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> FAQ. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://sourceforge.net/projects/ijbswa/"
+TARGET="_top"
+>http://sourceforge.net/projects/ijbswa/</A
+>, 
+   the Project Page for <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> on 
+   <A
+HREF="http://sourceforge.net"
+TARGET="_top"
+>SourceForge</A
+>.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>,
+   the web-based user interface. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> must be
+   running for this to work. Shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>http://www.privoxy.org/actions/</A
+>, to submit <SPAN
+CLASS="QUOTE"
+>"misses"</SPAN
+> to the developers. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.junkbusters.com/ht/en/cookies.html"
+TARGET="_top"
+>http://www.junkbusters.com/ht/en/cookies.html</A
+>,
+   an explanation how cookies are used to track web users.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.junkbusters.com/ijb.html"
+TARGET="_top"
+>http://www.junkbusters.com/ijb.html</A
+>,
+   the original Internet Junkbuster.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.waldherr.org/junkbuster/"
+TARGET="_top"
+>http://www.waldherr.org/junkbuster/</A
+>,
+   Stefan Waldherr's version of Junkbuster, from which <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> was
+   derived.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://privacy.net/analyze/"
+TARGET="_top"
+>http://privacy.net/analyze/</A
+>, a useful site
+   to check what information about you is leaked while you browse the web.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.squid-cache.org/"
+TARGET="_top"
+>http://www.squid-cache.org/</A
+>, a very popular
+   caching proxy, which is often used together with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/developer-manual/"
+TARGET="_top"
+>http://www.privoxy.org/developer-manual/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> developer manual. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="configuration.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="trouble.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Configuration</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Troubleshooting</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/faq/trouble.html b/doc/webserver/faq/trouble.html
new file mode 100644 (file)
index 0000000..59af117
--- /dev/null
@@ -0,0 +1,306 @@
+<HTML
+><HEAD
+><TITLE
+>Troubleshooting</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"><LINK
+REL="HOME"
+TITLE="Privoxy Frequently Asked Questions"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Miscellaneous"
+HREF="misc.html"><LINK
+REL="NEXT"
+TITLE="Contacting the developers, Bug Reporting and Feature Requests"
+HREF="contact.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy Frequently Asked Questions</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="misc.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="contact.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="TROUBLE"
+>5. Troubleshooting</A
+></H1
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN570"
+>5.1. I just upgraded and am getting <SPAN
+CLASS="QUOTE"
+>"connection refused"</SPAN
+>
+with every web page?</A
+></H3
+><P
+> Either <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is not running, or your 
+ browser is configured for a different port than what
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is using.</P
+><P
+> The old <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> (and also
+ <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>) used port 8000 by 
+ default. This has been changed to port 8118 now, due to a conflict 
+ with NAS (Network Audio Service), which uses port 8000. If you haven't, 
+ you need to change your browser to the new port number, or alternately 
+ change <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> <SPAN
+CLASS="QUOTE"
+>"listen-address"</SPAN
+>
+ setting in the <TT
+CLASS="FILENAME"
+>config</TT
+> file used to start 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN583"
+>5.2. I just added a new rule, but the steenkin ad is 
+still getting through. How?</A
+></H3
+><P
+> If the ad had been displayed before you added its URL, it will probably be
+ held in the browser's cache for some time, so it will be displayed without
+ the need for any request to the server, and <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ will not be in the picture. The best thing to do is try flushing the browser's
+ caches. And then try again.</P
+><P
+> If this doesn't help, you probably have an error in the rule you
+ applied. Try pasting the full URL of the offending ad into <A
+HREF="http://config.privoxy.org/show-url-info"
+TARGET="_top"
+>http://config.privoxy.org/show-url-info</A
+>
+ and see if any actions match your new rule.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H3
+CLASS="SECT2"
+><A
+NAME="AEN589"
+>5.3. One of my favorite sites does not work with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+What can I do?</A
+></H3
+><P
+> First verify that it is indeed a <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> problem, 
+ by disabling <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> filtering and blocking. 
+ Go to <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+> and click on 
+ <SPAN
+CLASS="QUOTE"
+>"Toggle Privoxy On or Off"</SPAN
+>, then disable it. Now try that 
+ page again. It's probably a good idea to flush the browser cache as well 
+ with <TT
+CLASS="LITERAL"
+>Shift+Reload</TT
+> to flush caches.</P
+><P
+> If still a problem, go to <SPAN
+CLASS="QUOTE"
+>"Show which actions apply to a URL and
+ why"</SPAN
+> from <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+> and paste
+ the full URL of the page in question into the prompt. See which actions are
+ being applied to the URL. Now, armed with this information, go to 
+ <SPAN
+CLASS="QUOTE"
+>"View &#38; change the current configuration"</SPAN
+>. Here you should see various sections that have
+ various <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> features disabled for specific
+ sites. Most disabled <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> will have a <SPAN
+CLASS="QUOTE"
+>"-"</SPAN
+> (minus
+ sign) in front of them. Some aliases are used just to disable other actions, 
+ e.g. <SPAN
+CLASS="QUOTE"
+>"shop"</SPAN
+> and <SPAN
+CLASS="QUOTE"
+>"fragile"</SPAN
+>, and won't necessarily 
+ use a <SPAN
+CLASS="QUOTE"
+>"+"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"-"</SPAN
+> sign. Add your problem page
+ URL to one of these sections that looks like it is disabling the feature that
+ is causing the problem. Rember to flush your browser's caches when making 
+ such changes! As a last resort, try <SPAN
+CLASS="QUOTE"
+>"fragile"</SPAN
+> which
+ disables most actions. Now re-try the page. There might be some trial and
+ error involved. This is discussed in more detail in the <A
+HREF="../user-manual/appendix.html#ACTIONSANAT"
+TARGET="_top"
+>user-manual appendix</A
+>.&#13;</P
+><P
+> Alternately, if you are comfortable with a text editor, you can accomplish 
+ the same thing by editing the appropriate <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> file.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="misc.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="contact.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Miscellaneous</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Contacting the developers, Bug Reporting and Feature Requests</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/images/files-in-use.jpg b/doc/webserver/images/files-in-use.jpg
new file mode 100644 (file)
index 0000000..207b6f7
Binary files /dev/null and b/doc/webserver/images/files-in-use.jpg differ
diff --git a/doc/webserver/images/proxy_setup.jpg b/doc/webserver/images/proxy_setup.jpg
new file mode 100644 (file)
index 0000000..9e80f97
Binary files /dev/null and b/doc/webserver/images/proxy_setup.jpg differ
diff --git a/doc/webserver/index.html b/doc/webserver/index.html
new file mode 100644 (file)
index 0000000..b13eee8
--- /dev/null
@@ -0,0 +1,344 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy - Homepage</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><META
+NAME="KEYWORD"
+CONTENT="privoxy"><META
+NAME="KEYWORD"
+CONTENT="HTTP"><META
+NAME="KEYWORD"
+CONTENT="proxy"><META
+NAME="KEYWORD"
+CONTENT="privacy"><META
+NAME="KEYWORD"
+CONTENT="popups"><META
+NAME="KEYWORD"
+CONTENT="po-ups"><META
+NAME="KEYWORD"
+CONTENT="HTML"><META
+NAME="KEYWORD"
+CONTENT="JavaScript"><META
+NAME="KEYWORD"
+CONTENT="cleaning"><META
+NAME="KEYWORD"
+CONTENT="blocking"><META
+NAME="KEYWORD"
+CONTENT="cleaner"><META
+NAME="KEYWORD"
+CONTENT="blocker"><META
+NAME="KEYWORD"
+CONTENT="filter"><META
+NAME="KEYWORD"
+CONTENT="proxy"><META
+NAME="KEYWORD"
+CONTENT="junk"><META
+NAME="KEYWORD"
+CONTENT="ad"><META
+NAME="KEYWORD"
+CONTENT="advertisement"><META
+NAME="KEYWORD"
+CONTENT="banner"><META
+NAME="KEYWORD"
+CONTENT="webbugs"><META
+NAME="KEYWORD"
+CONTENT="web-bugs"><META
+NAME="KEYWORD"
+CONTENT="werbung"><META
+NAME="KEYWORD"
+CONTENT="junkbusters"><META
+NAME="KEYWORD"
+CONTENT="junkbuster"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="p_doc.css">
+<meta name="description" content="Privoxy helps consumers reduce unwanted junk email and protect their privacy from direct marketing companies.">
+<meta name="MSSmartTagsPreventParsing" content="TRUE"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="AEN2"
+>Privoxy - Homepage</A
+></H1
+><DIV
+><DIV
+CLASS="ABSTRACT"
+><A
+NAME="AEN28"
+></A
+><P
+></P
+><P
+>   
+  </P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is a web proxy with advanced filtering
+ capabilities for protecting privacy, filtering web page content, managing
+ cookies, controlling access, and removing ads, banners, pop-ups and other
+ obnoxious Internet junk. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has a very
+ flexible configuration and can be customized to suit individual needs and
+ tastes. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has application for both
+ stand-alone systems and multi-user networks.</P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is based on <SPAN
+CLASS="APPLICATION"
+>Internet
+ Junkbuster</SPAN
+> (tm).</P
+><P
+>   The most recent release is 2.9.15 (beta).
+  </P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="SECT1"
+><H2
+CLASS="SECT1"
+><A
+NAME="DOWNLOAD"
+>Download</A
+></H2
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>    <A
+HREF="http://sourceforge.net/project/showfiles.php?group_id=11118"
+TARGET="_top"
+>Download recent releases</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="http://cvs.sourceforge.net/cvstarballs/ijbswa-cvsroot.tar.gz"
+TARGET="_top"
+>Download the latest CVS snapshot (source tarball)</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="user-manual/quickstart.html"
+TARGET="_top"
+>Quickstart after installation</A
+>
+   </P
+></LI
+></UL
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H2
+CLASS="SECT1"
+><A
+NAME="DOCS"
+>Documentation</A
+></H2
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>    <A
+HREF="user-manual/index.html"
+TARGET="_top"
+>User manual</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="faq/index.html"
+TARGET="_top"
+>Frequently Asked Questions</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="developer-manual/index.html"
+TARGET="_top"
+>Developer Manual</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="man-page/privoxy-man-page.html"
+TARGET="_top"
+>Classic Man Page</A
+>
+   </P
+></LI
+></UL
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H2
+CLASS="SECT1"
+><A
+NAME="MOREINFO"
+>More information</A
+></H2
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>    <A
+HREF="user-manual/contact.html"
+TARGET="_top"
+>Support &#38; Service</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="user-manual/copyright.html"
+TARGET="_top"
+>Copyright, License, History &#38; Authors</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="user-manual/introduction.html#FEATURES"
+TARGET="_top"
+>List of (new) Features</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="http://sourceforge.net/projects/ijbswa/"
+TARGET="_top"
+>The project page</A
+> at <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>SourceForge</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="user-manual/seealso.html"
+TARGET="_top"
+>Related links</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="team/index.html"
+TARGET="_top"
+>Pictures of the Privoxy Team</A
+>
+   </P
+></LI
+></UL
+></P
+></DIV
+><DIV
+CLASS="SECT1"
+><HR><H1
+CLASS="SECT1"
+><A
+NAME="AEN91"
+></A
+></H1
+><P
+><DIV
+CLASS="INFORMALTABLE"
+><A
+NAME="AEN94"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+WIDTH="100%"
+CLASS="CALSTABLE"
+><TBODY
+><TR
+><TD
+WIDTH="100%"
+ALIGN="CENTER"
+VALIGN="TOP"
+>Prixoxy is developed on:</TD
+></TR
+><TR
+><TD
+WIDTH="100%"
+ALIGN="CENTER"
+VALIGN="TOP"
+>     <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>      <IMG
+SRC="http://sourceforge.net/sflogo.php?group_id=11118&type=1&dummy=.gif">
+     </A
+>
+    </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></DIV
+></P
+><P
+> <SUB
+>  Copyright Â© 2001, 2002 by Privoxy Developers
+ </SUB
+></P
+></DIV
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/man-page/privoxy-man-page.html b/doc/webserver/man-page/privoxy-man-page.html
new file mode 100644 (file)
index 0000000..c874d0b
--- /dev/null
@@ -0,0 +1,391 @@
+
+<HTML><HEAD><TITLE>Manpage of PRIVOXY</TITLE>
+<LINK REL="STYLESHEET" TYPE="text/css" HREF="../p_doc.css"></HEAD><BODY>
+<H1>PRIVOXY</H1>
+Section:  (1)<BR>Updated: 14 May 2002<BR><A HREF="#index">Index</A>
+<HR>
+
+<A NAME="lbAB">&nbsp;</A>
+<H2>NAME</H2>
+
+privoxy - Privacy Enhancing Proxy
+<A NAME="lbAC">&nbsp;</A>
+<H2>SYNOPSIS</H2>
+
+<P>
+<B>privoxy</B> [<B>--help</B>]  [<B>--version</B>]  [<B>--no-daemon</B>]  [<B>--pidfile </B><I>pidfile</I><B></B>]  [<B>--user </B><I>user[.group]</I><B></B>]  [<B></B><I>configfile</I><B></B>] <B>(UNIX)</B>
+<P>
+<P>
+<B>privoxy.exe</B> [<B></B><I>configfile</I><B></B>] <B>(Windows)</B>
+<P>
+<A NAME="lbAD">&nbsp;</A>
+<H2>OPTIONS</H2>
+
+<P>
+
+<B>Privoxy</B> may be invoked with the following command line
+options:
+<DL COMPACT>
+<DT><B>--help</B><DD>
+Print brief usage info and exit.
+<DT><B>--version</B><DD>
+Print version info and exit.
+<DT><B>--no-daemon</B><DD>
+Don't  become  a daemon, i.e. don't fork and become process group
+leader, don't detach from controlling tty, and do all logging there.
+<DT><B>--pidfile </B><I>pidfile</I><B></B><DD>
+On startup, write the process ID to <I>pidfile</I>.
+Delete the <I>pidfile</I> on exit.
+Failiure to create or delete the <I>pidfile</I>
+is non-fatal. If no <B>--pidfile</B> option is given, no PID file will be used.
+<DT><B>--user </B><I>user[.group]</I><B></B><DD>
+After (optionally) writing the PID file, assume the user ID of
+<I>user</I> and the GID of
+<I>group</I>, or, if the optional
+<I>group</I> was not given, the default group of
+<I>user</I>. Exit if the privileges are not
+sufficient to do so.
+</DL>
+<P>
+
+If the <I>configfile</I> is not specified on  the  command  line,
+<B>Privoxy</B>  will  look for a file named
+<I>config</I> in the current directory (except on Win32 where
+it will try <I>config.txt</I>). If no
+<I>configfile</I> is found, <B>Privoxy</B> will 
+fail to start.
+<A NAME="lbAE">&nbsp;</A>
+<H2>DESCRIPTION</H2>
+
+<P>
+
+<B>Privoxy</B> is a web proxy with advanced filtering
+capabilities for protecting privacy, filtering web page content, managing
+cookies, controlling access, and removing ads, banners, pop-ups and other
+obnoxious Internet junk. <B>Privoxy</B> has a very
+flexible configuration and can be customized to suit individual needs and
+tastes. <B>Privoxy</B> has application for both
+stand-alone systems and multi-user networks.
+<P>
+
+<B>Privoxy</B> is based on <B>Internet
+Junkbuster</B> (tm).
+<A NAME="lbAF">&nbsp;</A>
+<H2>INSTALLATION AND USAGE</H2>
+
+<P>
+
+Browsers must be individually configured to use <B>Privoxy</B> as
+a HTTP proxy.  The default setting is  for  localhost,  on port  8118
+(configurable in the main config file).  To set the HTTP proxy in Netscape
+and Mozilla, go through:  <B>Edit</B>;
+<B>Preferences</B>;  <B>Advanced</B>;
+<B>Proxies</B>;  <B>Manual Proxy Configuration</B>;
+<B>View</B>. 
+<P>
+
+For Internet Explorer, go through: <B>Tools</B>; 
+<B>Internet Properties</B>; <B>Connections</B>;
+<B>LAN Settings</B>. 
+<P>
+
+The Secure (SSL) Proxy should also be set to the same values, otherwise
+https: URLs will not be proxied. 
+<P>
+
+For other browsers, check the documentation.
+<A NAME="lbAG">&nbsp;</A>
+<H2>CONFIGURATION</H2>
+
+<P>
+
+<B>Privoxy</B> can be configured with the various configuration
+files. The default configuration files are: <I>config</I>,
+<I>default.filter</I>, and
+<I>default.action</I>. <I>user.action</I> should 
+be used for locally defined exceptions to the default rules of
+<I>default.action</I> These are all well commented.  On Unix
+and Unix-like systems, these are located in
+<I>/etc/privoxy/</I> by default. On Windows, OS/2 and AmigaOS,
+these files are in the same directory as the <B>Privoxy</B>
+executable.
+<P>
+
+The name and number of configuration files has changed from previous
+versions, and is subject to change as development progresses. In fact, the
+configuration itself is changed  and  much more sophisticated. See the
+user-manual for a
+complete explanation of all configuration options and general usage.
+<P>
+
+The actions list (ad blocks, etc) can also be configured with your
+web browser at <A HREF="http://config.privoxy.org/.">http://config.privoxy.org/.</A>
+<B>Privoxy's</B> configuration parameters  can also  be viewed at
+the same page. In addition, <B>Privoxy</B> can be toggled on/off.
+This is an internal page.
+<A NAME="lbAH">&nbsp;</A>
+<H2>SAMPLE CONFIGURATION</H2>
+
+<P>
+
+A brief example of what a simple <I>default.action</I>
+configuration might look like:
+<P>
+<PRE>
+ # Define a few useful custom aliases for later use
+ {{alias}}
+
+ # Useful aliases
+ +crunch-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+ -crunch-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ +imageblock      = +block +handle-as-image
+
+ # Fragile sites should have the minimum changes
+ fragile     = -block -deanimate-gifs -fast-redirects -filter \
+               -hide-referer -prevent-cookies -kill-popups
+
+ ## Turn some actions on ################################
+ { \
+ -add-header \
+ -block \
+ +deanimate-gifs{last} \
+ -downgrade-http-version \
+ -fast-redirects \
+ +filter{html-annoyances} \
+ +filter{js-annoyances} \
+ +filter{content-cookies} \
+ +filter{webbugs} \
+ +filter{banners-by-size} \
+ +hide-forwarded-for-headers \
+ +hide-from-header{block} \
+ +hide-referrer{forge} \
+ -hide-user-agent \
+ -handle-as-image \
+ +set-image-blocker{pattern} \
+ -limit-connect \
+ +prevent-compression \
+ +session-cookies-only \
+ -crunch-cookies \
+ -kill-popups \
+ }
+ /   # '/' Matches *all* URL patterns
+ # Block, and treat these URL patterns as if they were 'images'.
+ # We would expect these to be ads.
+ {+imageblock}
+  .ad.doubleclick.net
+  .a[0-9].yimg.com/(?:(?!/i/).)*$
+  ad.*.doubleclick.net
+
+ # Block any URLs that match these patterns
+ {+block}
+  ad*.
+  .*ads.
+  banner?.
+  /.*count(er)?\.(pl|cgi|exe|dll|asp|php[34]?)
+  .hitbox.com 
+
+ # Make exceptions for these harmless ones that would be 
+ # caught by our +block patterns just above.
+ {-block}
+  adsl.
+  advice.
+  .*downloads.
+</PRE>
+
+<P>
+
+Then for a <I>user.action</I>, we would put local,
+narrowly defined exceptions:
+<P>
+<PRE>
+ # Re-define aliases as needed here
+ {{alias}}
+
+ # Useful aliases
+ -crunch-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ # Set personal exceptions to the policies in default.action #######
+
+ # Sites where we want persistant cookies, so allow *all* cookies
+ {-crunch-cookies -session-cookies-only}
+  .redhat.com
+  .sun.com
+  .msdn.microsoft.com
+ # This site breaks easily.
+ {-block -fast-redirects}
+  .forbes.com
+</PRE>
+
+<P>
+
+See the comments in the configuration files themselves, or the 
+<I>user-manual</I>
+for explanations of the above syntax, and other <B>Privoxy</B>
+configuration options.
+<A NAME="lbAI">&nbsp;</A>
+<H2>FILES</H2>
+
+<P>
+<PRE>
+ <I>/usr/sbin/privoxy</I>
+ <I>/etc/privoxy/config</I>
+ <I>/etc/privoxy/default.action</I>
+ <I>/etc/privoxy/standard.action</I>
+ <I>/etc/privoxy/user.action</I>
+ <I>/etc/privoxy/default.filter</I>
+ <I>/etc/privoxy/trust</I>
+ <I>/etc/privoxy/templates/*</I>
+ <I>/var/log/privoxy/logfile</I>
+</PRE>
+
+<P>
+
+Various other files should be included, but may vary depending on platform
+and build configuration. More documentation should be included in the local
+documentation directory.
+<A NAME="lbAJ">&nbsp;</A>
+<H2>SIGNALS</H2>
+
+<P>
+
+<B>Privoxy</B> terminates on the <B>SIGINT</B>,
+<B>SIGTERM</B> and <B>SIGABRT</B> signals. Log
+rotation scripts may cause a re-opening of the logfile by sending a 
+<B>SIGHUP</B> to <B>Privoxy</B>. Note that unlike
+other daemons,  <B>Privoxy</B> does not need to be made aware of
+config file changes by <B>SIGHUP</B> -- it will detect them
+automatically. 
+<A NAME="lbAK">&nbsp;</A>
+<H2>NOTES</H2>
+
+<P>
+
+This is a beta version of <B>Privoxy</B>. Not 
+all features are well tested.
+<P>
+
+Please see the <I>user-manual</I> on how to contact the
+developers for feature requests, reporting problems, and other questions.
+<A NAME="lbAL">&nbsp;</A>
+<H2>SEE ALSO</H2>
+
+<P>
+
+Other references and sites of interest to <B>Privoxy</B>
+users:
+<P>
+
+<P>
+<A HREF="http://www.privoxy.org/,">http://www.privoxy.org/,</A> 
+The <B>Privoxy</B> Home page. 
+<P>
+<A HREF="http://sourceforge.net/projects/ijbswa,">http://sourceforge.net/projects/ijbswa,</A> 
+the Project Page for <B>Privoxy</B> on 
+Sourceforge.
+<P>
+<A HREF="http://p.p/,">http://p.p/,</A> access
+<B>Privoxy</B> from your browser. Alternately, 
+<A HREF="http://config.privoxy.org">http://config.privoxy.org</A>
+may work in some situations where the first does not.
+<P>
+<A HREF="http://p.p/">http://p.p/</A> to submit ``misses'' to the developers. 
+<P>
+<A HREF="http://www.junkbusters.com/ht/en/cookies.html">http://www.junkbusters.com/ht/en/cookies.html</A>
+<P>
+<A HREF="http://www.waldherr.org/junkbuster/">http://www.waldherr.org/junkbuster/</A>
+<P>
+<A HREF="http://privacy.net/analyze/">http://privacy.net/analyze/</A>
+<P>
+<A HREF="http://www.squid-cache.org/">http://www.squid-cache.org/</A>
+<A NAME="lbAM">&nbsp;</A>
+<H2>DEVELOPMENT TEAM</H2>
+
+<P>
+<PRE>
+ Jon Foster
+ Andreas Oesterhelt
+ Stefan Waldherr
+ Thomas Steudten
+ Rodney Stromlund
+ Rodrigo Barbosa (RPM specfiles)
+ Hal Burgiss (docs)
+ Alexander Lazic
+ G&#225;bor Lipt&#225;k
+ Guy
+ Haroon Rafique
+ David Schmidt (OS/2, Mac OSX ports)
+ Joerg Strohmayer
+ Sarantis Paskalis
+</PRE>
+
+<A NAME="lbAN">&nbsp;</A>
+<H2>COPYRIGHT AND LICENSE</H2>
+
+<A NAME="lbAO">&nbsp;</A>
+<H3>COPYRIGHT</H3>
+
+<P>
+
+Copyright (C) 2001, 2002 by Privoxy Developers &lt;<A HREF="mailto:developers@privoxy.org">developers@privoxy.org</A>&gt;
+<P>
+
+Some source code is based on code Copyright (C) 1997 by Anonymous Coders
+and Junkbusters, Inc. and licensed under the <I>GNU General Public
+License</I>.
+<A NAME="lbAP">&nbsp;</A>
+<H3>LICENSE</H3>
+
+<P>
+
+<B>Privoxy</B> is free software; you can
+redistribute it and/or modify it under the terms of the 
+<I>GNU General Public
+License</I>, version 2, as published by the Free Software Foundation.
+<P>
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the 
+<I>GNU General Public License</I> for
+more details, which is available from the Free Software Foundation, Inc, 59
+Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+<P>
+
+You should have received a copy of the  <I>GNU General Public License</I>
+along with this program; if not, write to the  Free Software
+Foundation, Inc. 59 Temple Place - Suite 330
+Boston, MA 02111-1307
+USA 
+<P>
+
+<HR>
+<A NAME="index">&nbsp;</A><H2>Index</H2>
+<DL>
+<DT><A HREF="#lbAB">NAME</A><DD>
+<DT><A HREF="#lbAC">SYNOPSIS</A><DD>
+<DT><A HREF="#lbAD">OPTIONS</A><DD>
+<DT><A HREF="#lbAE">DESCRIPTION</A><DD>
+<DT><A HREF="#lbAF">INSTALLATION AND USAGE</A><DD>
+<DT><A HREF="#lbAG">CONFIGURATION</A><DD>
+<DT><A HREF="#lbAH">SAMPLE CONFIGURATION</A><DD>
+<DT><A HREF="#lbAI">FILES</A><DD>
+<DT><A HREF="#lbAJ">SIGNALS</A><DD>
+<DT><A HREF="#lbAK">NOTES</A><DD>
+<DT><A HREF="#lbAL">SEE ALSO</A><DD>
+<DT><A HREF="#lbAM">DEVELOPMENT TEAM</A><DD>
+<DT><A HREF="#lbAN">COPYRIGHT AND LICENSE</A><DD>
+<DL>
+<DT><A HREF="#lbAO">COPYRIGHT</A><DD>
+<DT><A HREF="#lbAP">LICENSE</A><DD>
+</DL>
+</DL>
+<HR>
+This document was created by
+man2html,
+using the manual pages.<BR>
+Time: 00:10:58 GMT, May 15, 2002
+</BODY>
+</HTML>
diff --git a/doc/webserver/p_doc.css b/doc/webserver/p_doc.css
new file mode 100644 (file)
index 0000000..d8e0bd9
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * CSS for Privoxy documentation
+ *
+ * $Id: privoxy.css,v 1.2 2002/04/09 11:55:20 oes Exp $
+ */
+
+/*
+ * Global fonts, colors, margins:
+ */ 
+body,td,th { font-family: arial, helvetica, sans-serif; }
+body { margin: 4%; color: #000000; background-color: #eeeeee; }
+
+/*
+ * Headings hierarchy in terms of size and color:
+ */
+h1 { color: #4c000f; font-size: 160%; }
+h2 { color: #660014; font-size: 140%; }
+h3 { color: #820019; font-size: 120%; }
+h4 { color: #99001d; font-size: 110%; }
+
+/*
+ * Make headings stand out:
+ * Indent all content in chapters, by additional 2%,
+ * and then pull the headings back left.
+ */
+div.sect1 { margin-left: 2%; }
+h1,h2,h3,h4 {margin-left: -2%; }
+h1.title { margin-left: 0; }
+
+/*
+ * Underlined links disturb the examples;
+ * Let them get darker instead of purple after visited.
+ */
+a { text-decoration: none; }
+a:link { color: #0c29ff; }
+a:visited { color: #071899; }
+
+/*
+ * Special highlighting:
+ * Code examples in embedded in the text flow become half-bold,
+ * Emphasis gets h4-red.
+ * Warnings get the same bg as in privoxy.css
+ */
+tt.literal { font-weight: 600; }
+i.emphasis { color: #99001d; }
+table.warning { border: 0; background-color: #ffdddd;}
+span.guibutton { 
+  white-space: nowrap;
+  width: auto;
+  padding: 2px;
+  background-color: #dddddd;
+  color:            #000000;
+  text-decoration: none;
+  border-top:    1px solid #ffffff;
+  border-left:   1px solid #ffffff;
+  border-bottom: 1px solid #000000;
+  border-right:  1px solid #000000;
+}
+
+/*
+ * Misc:
+ */
+ul { list-style-type: square; }
diff --git a/doc/webserver/p_feedback.css b/doc/webserver/p_feedback.css
new file mode 100644 (file)
index 0000000..281b047
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * Vary the gereneral Privoxy Stlyesheet to
+ * meet the needs of small popups:
+ *
+ * $Id: p_feedback.css,v 1.3 2002/04/08 16:59:56 oes Exp $
+ */
+body,td,th  { font-size:10px; }
+div.info    { width: 60%; }
+div.warning { width: 60%; text-align: left; } 
diff --git a/doc/webserver/p_web.css b/doc/webserver/p_web.css
new file mode 100644 (file)
index 0000000..8eb2159
--- /dev/null
@@ -0,0 +1,11 @@
+hr { width: 95% }
+body { background: #EEEEEE; }
+h1, h2, h3, h4 { font-family: arial, helvetica, sans-serif }
+code { color: green }
+pre { margin-left: 2% }
+# p { margin-left:20px }
+body { margin-left:20px }
+h1 { color: #404; font-size: 175%; margin-left:0px }
+h2 { color: #606; margin-left:0px }
+h3, h4 { color: #806; margin-left:0px }
+ul { list-style-type: square }
diff --git a/doc/webserver/privoxy.css b/doc/webserver/privoxy.css
new file mode 100644 (file)
index 0000000..2d33e85
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * CSS for Privoxy CGI and script output
+ *
+ * $Id: $
+ */
+
+/*
+ * General rules: Font, Color, Headings, Margins, Links
+ */
+body,td,th { font-family: arial, helvetica, helv, sans-serif; }
+body { background-color: #ffffff; color: #000000; }
+
+h1 { font-size: 140%; margin: 0px; }
+h2 { font-size: 120%; margin: 0px; }
+h3 { font-size: 110%; margin: 0px; }
+
+p,pre  { margin-left: 15px; }
+li { margin: 2px 15px; }
+dl { margin: 2px 15px; }
+
+a:link    { color: #0000dd; text-decoration: none; }
+a:visited { color: #330099; text-decoration: none; }
+a:active  { color: #3333ff; text-decoration: none; }
+
+/*
+ * Boxen as Table elements:
+ */
+td.title   { border: solid black 1px; background-color: #dddddd; }
+td.box     { border: solid black 1px; background-color: #eeeeee; }
+td.info    { border: solid black 1px; background-color: #ccccff; }
+td.warning { border: solid black 1px; background-color: #ffdddd; }
+
+/*
+ * Special Table Boxen: for nesting, naked container and for
+ * the Status field in CGI Output:
+ */
+td.wrapbox { border: solid black 1px; padding: 5px; }
+td.container { padding: 0px; }
+td.status  { border: solid black 1px; background-color: #ff0000; color: #ffffff; font-size: 300%; font-weight: bolder; }
+
+/*
+ * Same Boxen as <div>s:
+ */
+div.title    { border: solid black 1px; background-color: #dddddd; margin: 20px; padding: 20px; }
+div.box      { border: solid black 1px; background-color: #eeeeee; margin: 20px; padding: 20px; }
+div.info     { border: solid black 1px; background-color: #ccccff; margin: 20px; padding: 20px; }
+div.warning  { border: solid black 1px; background-color: #ffdddd; margin: 20px; padding: 20px; }
+div.wrapbox  { border: solid black 1px;                            margin: 20px; padding:  5px; }
+
+
+/*
+ * Bold definitions in <dl>s, Grey BG for Table headings
+ */
+dt { font-weight: bold; }
+th { background-color: #dddddd; }
+
+/*
+ * Special purpose paragraphs: Small for page footers,
+ * Important for quoting wrong or dangerous examples,
+ * Whiteframed for the toggle?mini=y CGI
+ */
+p.small { font-size: 10px; margin: 0px; }
+p.important { border: solid black 1px; background-color: #ffdddd; font-weight: bold; padding: 2px; }
+p.whiteframed { margin: 5px; padding: 5px; border: solid black 1px; text-align: center; background-color: #eeeeee; }
+
+/*
+ * Special red emphasis:
+ */
+em.warning { color: #ff0000 }
diff --git a/doc/webserver/redirect.php b/doc/webserver/redirect.php
new file mode 100755 (executable)
index 0000000..b00fc9c
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+
+error_reporting(E_ALL);
+
+// redirect.php
+//
+// Copyright (C) 2001 The SourceForge ijbswa team.
+// May be used under the GNU GPL, version 2 or later.
+
+
+// Parse the v= and to= paramaters
+function parse_parameters()
+{
+   global $v, $to;
+   global $version_major, $version_minor, $version_point;
+
+   $version_major = 0;
+   $version_minor = 0;
+   $version_point = 0;
+
+   if (isset($v))
+   {
+      // Version specified
+
+      $v = trim($v);
+
+      // Check if it's valid.
+      // Valid versions have the form "n.n.n", where n=digit(s).
+      if ( (strspn($v,"0123456789.") == strlen($v)) )
+      {
+         // Probably valid.  Copy into globals.
+         $version_pieces = explode (".", $v, 4);
+         if (isset($version_pieces[0]))
+         {
+            $version_major = 0 + $version_pieces[0];
+         }
+         if (isset($version_pieces[1]))
+         {
+            $version_minor = 0 + $version_pieces[1];
+         }
+         if (isset($version_pieces[2]))
+         {
+            $version_point = 0 + $version_pieces[2];
+         }
+      }
+   }
+
+   if (isset($to))
+   {
+      // Trim whitespace and convert to lowercase.
+      $to = strtolower(trim($to));
+
+      // Restrict the characters in the string by removing everything
+      // from the first disallowed character onwards.
+      //
+      // Allowed characters are 0-9, a-z, ".", "_", "-".
+      //
+      $to = substr($to, 0, strspn($to, "0123456789abcdefghijklmnopqrstuvwxyz._-"));
+   }
+   else
+   {
+      $to = "";
+   }
+}
+
+parse_parameters();
+
+// For debugging:
+// print "Version {$version_major}.{$version_minor}.{$version_point}<br>";
+// print "Target \"{$to}\"<br>";
+
+
+// Please do NOT delete any of these redirects.  Even if you take them
+// out of Privoxy, they may be in use by older releases.
+
+// Note 2: Should *not* include #target part in these URLs.
+// (It works with MS IE, but is not valid HTTP.)
+//http://ijbswa.sourceforge.net/user-manual/configuration.html
+switch($to)
+{
+   case "faq":
+      // Used by 2.9.0+
+//      header ("Location: http://www.junkbusters.com/ht/en/ijb2faq.html");
+        header ("Location: http://www.privoxy.org/faq/");
+    exit;
+   case "option":
+      // Used by 2.9.0+
+      // Config file options
+      // called as redirect.php?v=X.X.X&to=option#optionname
+//      header ("Location: http://www.junkbusters.com/ht/en/ijb2man.html");
+      header ("Location: http://www.privoxy.org/user-manual/configuration.html");
+      exit;
+   case "win":
+      // Used by 2.9.0+ on WIN32
+//      header ("Location: http://www.junkbusters.com/ht/en/ijbwin.html");
+      header ("Location: http://www.privoxy.org/user-manual/configuration.html");
+      exit;
+//   case "home":
+//      // Currently hard-wired into the code.
+//      header ("Location: http://ijbswa.sourceforge.net/");
+//      exit;
+//   case "gpl":
+//      // Currently hard-wired into the code.
+//      header ("Location: http://www.fsf.org/copyleft/gpl.html");
+//      exit;
+   default:
+      header ("Location: http://www.privoxy.org/");
+      exit;
+}
+
+exit;
+?>
diff --git a/doc/webserver/robots.txt b/doc/webserver/robots.txt
new file mode 100644 (file)
index 0000000..a9941db
--- /dev/null
@@ -0,0 +1,17 @@
+# This is the Privoxy web site.
+#
+# If the robot is connecting through Privoxy, then the
+# control interface is at /config.   It isn't very useful
+# to index it, and you're likely to break stuff.  So go away!
+#
+# Even if you're not connected through Privoxy, the 
+# one "Privoxy is not working" page there is not very
+# interesting.
+
+User-agent: *
+Disallow: /config/
+Disallow: /actions/
+Disallow: /submit/
+
+
+
diff --git a/doc/webserver/submit/confirmad.php b/doc/webserver/submit/confirmad.php
new file mode 100644 (file)
index 0000000..cfd1eae
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+//  File :  $Source: /cvsroot/ijbswa/current/doc/webserver/submit/confirmad.php,v $
+//
+//  Purpose  :  Confirms ad submission.
+//              This file belongs in
+//              ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+//
+//  $Id: confirmad.php,v 1.1 2002/03/29 09:38:52 swa Exp $
+//
+//  Written by and Copyright (C) 2001 the SourceForge
+//  Privoxy team. http://www.privoxy.org/
+//
+//  Based on the Internet Junkbuster originally written
+//  by and Copyright (C) 1997 Anonymous Coders and
+//  Junkbusters Corporation.  http://www.junkbusters.com
+//
+//  This program is free software; you can redistribute it
+//  and/or modify it under the terms of the GNU General
+//  Public License as published by the Free Software
+//  Foundation; either version 2 of the License, or (at
+//  your option) any later version.
+//
+//  This program is distributed in the hope that it will
+//  be useful, but WITHOUT ANY WARRANTY; without even the
+//  implied warranty of MERCHANTABILITY or FITNESS FOR A
+//  PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  The GNU General Public License should be included with
+//  this file.  If not, you can view it at
+//  http://www.gnu.org/copyleft/gpl.html
+//  or write to the Free Software Foundation, Inc., 59
+//  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+//
+$headers = getallheaders();
+?>
+<html>
+  <head>
+    <title>Privoxy|Confirm ad submission</title>
+    <link rel="stylesheet" type="text/css" href="../p_web.css">
+</head>
+
+<h1>Privoxy Feedback</h1>
+
+<h2>Confirm Ad Submission</h2>
+
+<p>We have detemined that ...</p>
+
+</body>
+</html>
+
+<!--
+       $Log: confirmad.php,v $
+       Revision 1.1  2002/03/29 09:38:52  swa
+       2nd page
+       
+-->
\ No newline at end of file
diff --git a/doc/webserver/submit/index.php b/doc/webserver/submit/index.php
new file mode 100644 (file)
index 0000000..47a7673
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+//  File :  $Source: /cvsroot/ijbswa/current/doc/webserver/submit/index.php,v $
+//
+//  Purpose  :  Submit form for ads and such
+//              This file belongs in
+//              ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
+//
+//  $Id: index.php,v 1.4 2002/03/29 09:55:21 swa Exp $
+//
+//  Written by and Copyright (C) 2001 the SourceForge
+//  Privoxy team. http://www.privoxy.org/
+//
+//  Based on the Internet Junkbuster originally written
+//  by and Copyright (C) 1997 Anonymous Coders and
+//  Junkbusters Corporation.  http://www.junkbusters.com
+//
+//  This program is free software; you can redistribute it
+//  and/or modify it under the terms of the GNU General
+//  Public License as published by the Free Software
+//  Foundation; either version 2 of the License, or (at
+//  your option) any later version.
+//
+//  This program is distributed in the hope that it will
+//  be useful, but WITHOUT ANY WARRANTY; without even the
+//  implied warranty of MERCHANTABILITY or FITNESS FOR A
+//  PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  The GNU General Public License should be included with
+//  this file.  If not, you can view it at
+//  http://www.gnu.org/copyleft/gpl.html
+//  or write to the Free Software Foundation, Inc., 59
+//  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+//
+$headers = getallheaders();
+?>
+<html>
+  <head>
+    <title>Privoxy|Submit</title>
+    <link rel="stylesheet" type="text/css" href="../p_web.css">
+</head>
+
+<h1>Privoxy Feedback</h1>
+
+<p>Compared to <a
+href="http://sourceforge.net/tracker/?group_id=11118&atid=111118">bug
+reports</a> or <a
+href="http://sourceforge.net/tracker/?atid=361118&group_id=11118&func=browse">feature
+requests</a>, this page is intended to optimize the blocking behavior
+of Privoxy. Therefor we need your feedback.</p><p> If you have
+observed and advertisement, that was not blocked or an image that was
+incorrectly blocked, please use the forms below to report this.</p>
+
+<h2>New Advertisement</h2>
+
+<!-- testing mail sending
+// <?
+//$ret_val=mail("stefan@waldherr.org", "Subject", "Message"); echo $ret_val;
+?>
+-->
+
+
+<?
+$cfile  = "counter-data.inc";
+$localip = "127.0.0.1";
+$serverip = "127.0.0.1";
+# Enter information on the next line, but only after you read
+# the "c-readme.txt" file.
+$browser_id = "";
+if (file_exists ($cfile)) {
+       $fp = fopen ($cfile,"r+");
+       $data = fgets ($fp,25);
+       $ip = chop (substr($data,0,15));
+       $count = substr($data,15);
+# Unremark the second "if" statement and remark the first one if
+# your site is on a hosted server and you have a dynamic IP, but
+# only after you read "c-readme.txt" file.
+       if ($REMOTE_ADDR == $localip or $REMOTE_ADDR == $serverip)
+#       if ($REMOTE_ADDR == substr_count($HTTP_USER_AGENT,$browser_id) > 0)
+               $np = $ip;
+       else
+               $np = $REMOTE_ADDR;
+       if ($np != $ip)
+               $count += 1;
+       rewind ($fp);
+       fputs ($fp,substr($np."        ",0,15).$count);
+       fclose ($fp);
+       echo $count;
+}
+else {
+       $fp = fopen($cfile,"w");
+       $np = $REMOTE_ADDR;
+       $count = "1";
+       fputs ($fp,substr($np."        ",0,15).$count);
+       fclose ($fp);
+       echo $count;
+}
+?>
+
+
+<p>
+<form action="http://privox.org/submit/confirmad.php" method="post">
+<table border="0" cellpadding="0" cellspacing="4">
+
+<tr>
+<td align="right">Your name:</td>
+<td>
+<input name="submit_name" value="anonymous" type="text" size="30" maxlength="30">
+</td>
+<td>optional</td>
+</tr>
+
+<tr>
+<td align="right">Your email address:</td>
+<td>
+<input name="submit_email" value="anonymous" type="text" size="30" maxlength="30">
+</td>
+<td>optional</td>
+</tr>
+
+<tr>
+<td align="right">Website, where I observed an ad:</td>
+<td>
+<input name="submit_url" value="prefilled" type="text" size="45" maxlength="255">
+</td>
+<td>Please change, if necessary</td>
+</tr>
+
+<tr>
+<td align="right">How annoying is the ad:</td>
+<td>
+<select name="submit_annoy" size="1">
+<option value="A0">Nice, not to have</option>
+<option selected value="A1">Should be removed</option>
+<option value="A2">Must be removed</option>
+</select>
+</td>
+<td>Please select one</td>
+</tr>
+
+<tr>
+<td align="right">Privoxy Version:</td>
+<td>
+<input name="submit_pversion" value="prefilled" readonly type="text" size="30" maxlength="30">
+</td>
+<td>Automatically determined</td>
+</tr>
+
+<tr>
+<td align="right">Action File:</td>
+<td>
+<input name="submit_actionfile" value="prefilled" readonly type="text" size="30" maxlength="30">
+</td>
+<td>Automatically determined</td>
+</tr>
+
+<tr>
+<td align="right">Action File Version:</td>
+<td>
+<input name="submit_actionversion" value="prefilled" readonly type="text" size="30" maxlength="30">
+</td>
+<td>Automatically determined</td>
+</tr>
+
+<tr>
+<td align="right">Remarks:</td>
+<td>
+<textarea name="submit_remarks" cols="35" rows="3">
+None.
+</textarea>
+</td>
+<td>Please change, if necessary</td>
+</tr>
+
+<tr>
+<td align="right"></td>
+<td>
+<input type="hidden" name="submit_targeturl" value="/submit/confirmad.php">
+<input type=submit value="Submit">
+</td>
+<td></td>
+</tr>
+
+</table>
+</form>
+</p>
+
+<h2>Incorrect blocking</h2>
+<p>We soon present a form where you can submit websites, where the
+default action file was too agressive.</p>
+
+<h2>Misc</h2>
+<p>Bla bla bla</p>
+
+</body>
+</html>
+
+<!--
+       $Log: index.php,v $
+       Revision 1.4  2002/03/29 09:55:21  swa
+       .
+       
+       Revision 1.3  2002/03/29 09:39:48  swa
+       added form
+       
+-->
\ No newline at end of file
diff --git a/doc/webserver/team/01stefanw.jpg b/doc/webserver/team/01stefanw.jpg
new file mode 100644 (file)
index 0000000..920dece
Binary files /dev/null and b/doc/webserver/team/01stefanw.jpg differ
diff --git a/doc/webserver/team/01stefanw_t.jpg b/doc/webserver/team/01stefanw_t.jpg
new file mode 100644 (file)
index 0000000..5a90642
Binary files /dev/null and b/doc/webserver/team/01stefanw_t.jpg differ
diff --git a/doc/webserver/team/02jon.jpg b/doc/webserver/team/02jon.jpg
new file mode 100644 (file)
index 0000000..136b2dd
Binary files /dev/null and b/doc/webserver/team/02jon.jpg differ
diff --git a/doc/webserver/team/02jon_t.jpg b/doc/webserver/team/02jon_t.jpg
new file mode 100644 (file)
index 0000000..32e470b
Binary files /dev/null and b/doc/webserver/team/02jon_t.jpg differ
diff --git a/doc/webserver/team/03andreas.jpg b/doc/webserver/team/03andreas.jpg
new file mode 100644 (file)
index 0000000..78dc102
Binary files /dev/null and b/doc/webserver/team/03andreas.jpg differ
diff --git a/doc/webserver/team/03andreas_t.jpg b/doc/webserver/team/03andreas_t.jpg
new file mode 100644 (file)
index 0000000..e23f580
Binary files /dev/null and b/doc/webserver/team/03andreas_t.jpg differ
diff --git a/doc/webserver/team/04rodney.jpg b/doc/webserver/team/04rodney.jpg
new file mode 100644 (file)
index 0000000..bb4e02d
Binary files /dev/null and b/doc/webserver/team/04rodney.jpg differ
diff --git a/doc/webserver/team/04rodney_t.jpg b/doc/webserver/team/04rodney_t.jpg
new file mode 100644 (file)
index 0000000..bba4f15
Binary files /dev/null and b/doc/webserver/team/04rodney_t.jpg differ
diff --git a/doc/webserver/team/05david.jpg b/doc/webserver/team/05david.jpg
new file mode 100644 (file)
index 0000000..429723f
Binary files /dev/null and b/doc/webserver/team/05david.jpg differ
diff --git a/doc/webserver/team/05david_t.jpg b/doc/webserver/team/05david_t.jpg
new file mode 100644 (file)
index 0000000..c04aa55
Binary files /dev/null and b/doc/webserver/team/05david_t.jpg differ
diff --git a/doc/webserver/team/05member.jpg b/doc/webserver/team/05member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/05member.jpg differ
diff --git a/doc/webserver/team/05member_t.jpg b/doc/webserver/team/05member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/05member_t.jpg differ
diff --git a/doc/webserver/team/06member.jpg b/doc/webserver/team/06member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/06member.jpg differ
diff --git a/doc/webserver/team/06member_t.jpg b/doc/webserver/team/06member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/06member_t.jpg differ
diff --git a/doc/webserver/team/07member.jpg b/doc/webserver/team/07member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/07member.jpg differ
diff --git a/doc/webserver/team/07member_t.jpg b/doc/webserver/team/07member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/07member_t.jpg differ
diff --git a/doc/webserver/team/08member.jpg b/doc/webserver/team/08member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/08member.jpg differ
diff --git a/doc/webserver/team/08member_t.jpg b/doc/webserver/team/08member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/08member_t.jpg differ
diff --git a/doc/webserver/team/09member.jpg b/doc/webserver/team/09member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/09member.jpg differ
diff --git a/doc/webserver/team/09member_t.jpg b/doc/webserver/team/09member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/09member_t.jpg differ
diff --git a/doc/webserver/team/10member.jpg b/doc/webserver/team/10member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/10member.jpg differ
diff --git a/doc/webserver/team/10member_t.jpg b/doc/webserver/team/10member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/10member_t.jpg differ
diff --git a/doc/webserver/team/11member.jpg b/doc/webserver/team/11member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/11member.jpg differ
diff --git a/doc/webserver/team/11member_t.jpg b/doc/webserver/team/11member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/11member_t.jpg differ
diff --git a/doc/webserver/team/12member.jpg b/doc/webserver/team/12member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/12member.jpg differ
diff --git a/doc/webserver/team/12member_t.jpg b/doc/webserver/team/12member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/12member_t.jpg differ
diff --git a/doc/webserver/team/13member.jpg b/doc/webserver/team/13member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/13member.jpg differ
diff --git a/doc/webserver/team/13member_t.jpg b/doc/webserver/team/13member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/13member_t.jpg differ
diff --git a/doc/webserver/team/14member.jpg b/doc/webserver/team/14member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/14member.jpg differ
diff --git a/doc/webserver/team/14member_t.jpg b/doc/webserver/team/14member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/14member_t.jpg differ
diff --git a/doc/webserver/team/15member.jpg b/doc/webserver/team/15member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/15member.jpg differ
diff --git a/doc/webserver/team/15member_t.jpg b/doc/webserver/team/15member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/15member_t.jpg differ
diff --git a/doc/webserver/team/16member.jpg b/doc/webserver/team/16member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/16member.jpg differ
diff --git a/doc/webserver/team/16member_t.jpg b/doc/webserver/team/16member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/16member_t.jpg differ
diff --git a/doc/webserver/team/17member.jpg b/doc/webserver/team/17member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/17member.jpg differ
diff --git a/doc/webserver/team/17member_t.jpg b/doc/webserver/team/17member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/17member_t.jpg differ
diff --git a/doc/webserver/team/18member.jpg b/doc/webserver/team/18member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/18member.jpg differ
diff --git a/doc/webserver/team/18member_t.jpg b/doc/webserver/team/18member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/18member_t.jpg differ
diff --git a/doc/webserver/team/19member.jpg b/doc/webserver/team/19member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/19member.jpg differ
diff --git a/doc/webserver/team/19member_t.jpg b/doc/webserver/team/19member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/19member_t.jpg differ
diff --git a/doc/webserver/team/20member.jpg b/doc/webserver/team/20member.jpg
new file mode 100644 (file)
index 0000000..97042aa
Binary files /dev/null and b/doc/webserver/team/20member.jpg differ
diff --git a/doc/webserver/team/20member_t.jpg b/doc/webserver/team/20member_t.jpg
new file mode 100644 (file)
index 0000000..c9ffd9b
Binary files /dev/null and b/doc/webserver/team/20member_t.jpg differ
diff --git a/doc/webserver/team/index.html b/doc/webserver/team/index.html
new file mode 100644 (file)
index 0000000..fe12d90
--- /dev/null
@@ -0,0 +1,83 @@
+<html>\r
+<head>\r
+\r
+<meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1">\r
+<meta name="GENERATOR" content="IrfanView">\r
+\r
+<title>Privoxy - Team page</title>\r
+<LINK\r
+REL="STYLESHEET"\r
+TYPE="text/css"\r
+HREF="../p_web.css">\r
+<meta name="description" content="Privoxy helps consumers reduce unwanted junk email and protect their privacy from direct marketing companies.">\r
+<meta name="MSSmartTagsPreventParsing" content="TRUE">\r
+</HEAD>\r
+<center>\r
+<h1>Privoxy - Team page</h1>\r
+<hr>\r
+\r
+<TABLE>\r
+\r
+\r
+<TR>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="01stefanw.jpg" target="ImageWindow">\r
+<IMG SRC="01stefanw_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="01stefanw.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="02jon.jpg" target="ImageWindow">\r
+<IMG SRC="02jon_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="02jon.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="03andreas.jpg" target="ImageWindow">\r
+<IMG SRC="03andreas_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="03andreas.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="04rodney.jpg" target="ImageWindow">\r
+<IMG SRC="04rodney_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="04rodney.jpg"></A></FONT></TD>\r
+</TR>\r
+\r
+<TR>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="05david.jpg" target="ImageWindow">\r
+<IMG SRC="05david_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="05david.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="06member.jpg" target="ImageWindow">\r
+<IMG SRC="06member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="06member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="07member.jpg" target="ImageWindow">\r
+<IMG SRC="07member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="07member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="08member.jpg" target="ImageWindow">\r
+<IMG SRC="08member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="08member.jpg"></A></FONT></TD>\r
+</TR>\r
+\r
+<TR>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="09member.jpg" target="ImageWindow">\r
+<IMG SRC="09member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="09member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="10member.jpg" target="ImageWindow">\r
+<IMG SRC="10member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="10member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="11member.jpg" target="ImageWindow">\r
+<IMG SRC="11member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="11member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="12member.jpg" target="ImageWindow">\r
+<IMG SRC="12member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="12member.jpg"></A></FONT></TD>\r
+</TR>\r
+\r
+<TR>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="13member.jpg" target="ImageWindow">\r
+<IMG SRC="13member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="13member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="14member.jpg" target="ImageWindow">\r
+<IMG SRC="14member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="14member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="15member.jpg" target="ImageWindow">\r
+<IMG SRC="15member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="15member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="16member.jpg" target="ImageWindow">\r
+<IMG SRC="16member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="16member.jpg"></A></FONT></TD>\r
+</TR>\r
+\r
+<TR>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="17member.jpg" target="ImageWindow">\r
+<IMG SRC="17member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="17member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="18member.jpg" target="ImageWindow">\r
+<IMG SRC="18member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="18member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="19member.jpg" target="ImageWindow">\r
+<IMG SRC="19member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="19member.jpg"></A></FONT></TD>\r
+<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2"><A HREF="20member.jpg" target="ImageWindow">\r
+<IMG SRC="20member_t.jpg"  WIDTH="80" HEIGHT="80" BORDER="0" ALT="20member.jpg"></A></FONT></TD>\r
+</TR>\r
+\r
+</TABLE>\r
+\r
+<hr>\r
+<b><A HREF="http://www.irfanview.com">Created by IrfanView</A></b>\r
+</center>\r
+</body>\r
+</html>\r
diff --git a/doc/webserver/user-manual/actions-file.html b/doc/webserver/user-manual/actions-file.html
new file mode 100644 (file)
index 0000000..ca87032
--- /dev/null
@@ -0,0 +1,4959 @@
+<HTML
+><HEAD
+><TITLE
+>Actions Files</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="The Main Configuration File"
+HREF="config.html"><LINK
+REL="NEXT"
+TITLE="The Filter File"
+HREF="filter-file.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="config.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="filter-file.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="ACTIONS-FILE"
+>8. Actions Files</A
+></H1
+><P
+> The actions files are used to define what actions
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> takes for which URLs, and thus determine
+ how ad images, cookies and various other aspects of HTTP content and
+ transactions are handled, and on which sites (or even parts thereof). There 
+ are three such files included with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> (as of 
+ version 2.9.15), with differing purposes:
+ </P
+><P
+>  <P
+></P
+><UL
+><LI
+><P
+>     <TT
+CLASS="FILENAME"
+>default.action</TT
+> - is the primary action file 
+     that sets the initial values for all actions. It is intended to 
+     provide a base level of functionality for
+     <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> array of features. So it is 
+     a set of broad rules that should work reasonably well for users everywhere.
+     This is the file that the developers are keeping updated, and making 
+     available to users.
+    </P
+></LI
+><LI
+><P
+>     <TT
+CLASS="FILENAME"
+>user.action</TT
+> - is intended to be for local site 
+     preferences and exceptions. As an example, if your ISP or your bank
+     has specific requirements, and need special handling, this kind of 
+     thing should go here. This file will not be upgraded.
+    </P
+></LI
+><LI
+><P
+>     <TT
+CLASS="FILENAME"
+>standard.action</TT
+> - is used by the web based editor, 
+     to set various pre-defined sets of rules for the default actions section
+     in <TT
+CLASS="FILENAME"
+>default.action</TT
+>. These have increasing levels of
+     aggressiveness <I
+CLASS="EMPHASIS"
+>and have no influence on your browsing unless
+     you select them explicitly in the editor</I
+>. It is not recommend
+     to edit this file.
+    </P
+></LI
+></UL
+>
+ </P
+><P
+> The list of actions files to be used are defined in the main configuration 
+ file, and are processed in the order they are defined. The content of these
+ can all be viewed and edited from <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>http://config.privoxy.org/show-status</A
+>.</P
+><P
+> An actions file typically has multiple sections. If you want to use
+ <SPAN
+CLASS="QUOTE"
+>"aliases"</SPAN
+> in an actions file, you have to place the (optional)
+ <A
+HREF="actions-file.html#ALIASES"
+>alias section</A
+> at the top of that file.
+ Then comes the default set of rules which will apply universally to all
+ sites and pages (be <I
+CLASS="EMPHASIS"
+>very careful</I
+> with using such a
+ universal set in <TT
+CLASS="FILENAME"
+>user.action</TT
+> or any other actions file after 
+ <TT
+CLASS="FILENAME"
+>default.action</TT
+>, because it will override the result
+ from consulting any previous file). And then below that,
+ exceptions to the defined universal policies. You can regard
+ <TT
+CLASS="FILENAME"
+>user.action</TT
+> as an appendix to <TT
+CLASS="FILENAME"
+>default.action</TT
+>,
+ with the advantage that is a separate file, which makes preserving your
+ personal settings across <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> upgrades easier.</P
+><P
+> 
+ Actions can be used to block anything you want, including ads, banners, or
+ just some obnoxious URL that you would rather not see. Cookies can be accepted
+ or rejected, or accepted only during the current browser session (i.e. not
+ written to disk), content can be modified, JavaScripts tamed, user-tracking
+ fooled, and much more. See below for a <A
+HREF="actions-file.html#ACTIONS"
+>complete list
+ of actions</A
+>.</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1553"
+>8.1. Finding the Right Mix</A
+></H2
+><P
+> Note that some <A
+HREF="actions-file.html#ACTIONS"
+>actions</A
+>, like cookie suppression
+ or script disabling, may render some sites unusable that rely on these
+ techniques to work properly. Finding the right mix of actions is not always easy and
+ certainly a matter of personal taste. In general, it can be said that the more
+ <SPAN
+CLASS="QUOTE"
+>"aggressive"</SPAN
+> your default settings (in the top section of the
+ actions file) are, the more exceptions for <SPAN
+CLASS="QUOTE"
+>"trusted"</SPAN
+> sites you
+ will have to make later. If, for example, you want to kill popup windows per
+ default, you'll have to make exceptions from that rule for sites that you
+ regularly use and that require popups for actually useful content, like maybe
+ your bank, favorite shop, or newspaper.</P
+><P
+> We have tried to provide you with reasonable rules to start from in the
+ distribution actions files. But there is no general rule of thumb on these
+ things. There just are too many variables, and sites are constantly changing.
+ Sooner or later you will want to change the rules (and read this chapter again :).</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1560"
+>8.2. How to Edit</A
+></H2
+><P
+> The easiest way to edit the actions files is with a browser by
+ using our browser-based editor, which can be reached from <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>http://config.privoxy.org/show-status</A
+>.
+ The editor allows both fine-grained control over every single feature on a
+ per-URL basis, and easy choosing from wholesale sets of defaults like
+ <SPAN
+CLASS="QUOTE"
+>"Cautious"</SPAN
+>, <SPAN
+CLASS="QUOTE"
+>"Medium"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"Advanced"</SPAN
+>.</P
+><P
+> If you prefer plain text editing to GUIs, you can of course also directly edit the
+ the actions files. Look at <TT
+CLASS="FILENAME"
+>default.action</TT
+> which is richly
+ commented.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="ACTIONS-APPLY"
+>8.3. How Actions are Applied to URLs</A
+></H2
+><P
+> Actions files are divided into sections. There are special sections,
+ like the <SPAN
+CLASS="QUOTE"
+>"<A
+HREF="actions-file.html#ALIASES"
+>alias</A
+>"</SPAN
+> sections which will
+ be discussed later. For now let's concentrate on regular sections: They have a
+ heading line (often split up to multiple lines for readability) which consist
+ of a list of actions, separated by whitespace and enclosed in curly braces.
+ Below that, there is a list of URL patterns, each on a separate line.</P
+><P
+> To determine which actions apply to a request, the URL of the request is
+ compared to all patterns in each action file file. Every time it matches, the list of
+ applicable actions for the URL is incrementally updated, using the heading
+ of the section in which the pattern is located. If multiple matches for
+ the same URL set the same action differently, the last match wins. If not, 
+ the effects are aggregated. E.g. a URL might match a regular section with 
+ a heading line of <TT
+CLASS="LITERAL"
+>{ 
+ +<A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+TARGET="_top"
+>handle-as-image</A
+> }</TT
+>,
+ then later another one with just <TT
+CLASS="LITERAL"
+>{
+ +<A
+HREF="actions-file.html#BLOCK"
+TARGET="_top"
+>block</A
+> }</TT
+>, resulting
+ in <I
+CLASS="EMPHASIS"
+>both</I
+> actions to apply.</P
+><P
+> You can trace this process for any given URL by visiting <A
+HREF="http://config.privoxy.org/show-url-info"
+TARGET="_top"
+>http://config.privoxy.org/show-url-info</A
+>.</P
+><P
+> More detail on this is provided in the Appendix, <A
+HREF="appendix.html#ACTIONSANAT"
+> Anatomy of an Action</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AF-PATTERNS"
+>8.4. Patterns</A
+></H2
+><P
+> Generally, a pattern has the form <TT
+CLASS="LITERAL"
+>&#60;domain&#62;/&#60;path&#62;</TT
+>,
+ where both the <TT
+CLASS="LITERAL"
+>&#60;domain&#62;</TT
+> and <TT
+CLASS="LITERAL"
+>&#60;path&#62;</TT
+>
+ are optional. (This is why the pattern <TT
+CLASS="LITERAL"
+>/</TT
+> matches all URLs).</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="LITERAL"
+>www.example.com/</TT
+></DT
+><DD
+><P
+>    is a domain-only pattern and will match any request to <TT
+CLASS="LITERAL"
+>www.example.com</TT
+>,
+    regardless of which document on that server is requested.
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>www.example.com</TT
+></DT
+><DD
+><P
+>    means exactly the same. For domain-only patterns, the trailing <TT
+CLASS="LITERAL"
+>/</TT
+> may
+    be omitted.
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>www.example.com/index.html</TT
+></DT
+><DD
+><P
+>    matches only the single document <TT
+CLASS="LITERAL"
+>/index.html</TT
+>
+    on <TT
+CLASS="LITERAL"
+>www.example.com</TT
+>.
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>/index.html</TT
+></DT
+><DD
+><P
+>    matches the document <TT
+CLASS="LITERAL"
+>/index.html</TT
+>, regardless of the domain,
+    i.e. on <I
+CLASS="EMPHASIS"
+>any</I
+> web server.
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>index.html</TT
+></DT
+><DD
+><P
+>    matches nothing, since it would be  interpreted as a domain name and
+    there is no top-level domain called <TT
+CLASS="LITERAL"
+>.html</TT
+>.
+   </P
+></DD
+></DL
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="AEN1624"
+>8.4.1. The Domain Pattern</A
+></H3
+><P
+> The matching of the domain part offers some flexible options: if the
+ domain starts or ends with a dot, it becomes unanchored at that end. 
+ For example:</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="LITERAL"
+>.example.com</TT
+></DT
+><DD
+><P
+>    matches any domain that <I
+CLASS="EMPHASIS"
+>ENDS</I
+> in
+    <TT
+CLASS="LITERAL"
+>.example.com</TT
+>
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>www.</TT
+></DT
+><DD
+><P
+>    matches any domain that <I
+CLASS="EMPHASIS"
+>STARTS</I
+> with
+    <TT
+CLASS="LITERAL"
+>www.</TT
+>
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>.example.</TT
+></DT
+><DD
+><P
+>    matches any domain that <I
+CLASS="EMPHASIS"
+>CONTAINS</I
+> <TT
+CLASS="LITERAL"
+>.example.</TT
+>
+    (Correctly speaking: It matches any FQDN that contains <TT
+CLASS="LITERAL"
+>example</TT
+> as a domain.)
+   </P
+></DD
+></DL
+></DIV
+><P
+> Additionally, there are wild-cards that you can use in the domain names
+ themselves. They work pretty similar to shell wild-cards: <SPAN
+CLASS="QUOTE"
+>"*"</SPAN
+>
+ stands for zero or more arbitrary characters, <SPAN
+CLASS="QUOTE"
+>"?"</SPAN
+> stands for
+ any single character, you can define character classes in square
+ brackets and all of that can be freely mixed:</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="LITERAL"
+>ad*.example.com</TT
+></DT
+><DD
+><P
+>    matches <SPAN
+CLASS="QUOTE"
+>"adserver.example.com"</SPAN
+>, 
+    <SPAN
+CLASS="QUOTE"
+>"ads.example.com"</SPAN
+>, etc but not <SPAN
+CLASS="QUOTE"
+>"sfads.example.com"</SPAN
+>
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>*ad*.example.com</TT
+></DT
+><DD
+><P
+>    matches all of the above, and then some.
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>.?pix.com</TT
+></DT
+><DD
+><P
+>    matches <TT
+CLASS="LITERAL"
+>www.ipix.com</TT
+>,
+    <TT
+CLASS="LITERAL"
+>pictures.epix.com</TT
+>, <TT
+CLASS="LITERAL"
+>a.b.c.d.e.upix.com</TT
+> etc. 
+   </P
+></DD
+><DT
+><TT
+CLASS="LITERAL"
+>www[1-9a-ez].example.c*</TT
+></DT
+><DD
+><P
+>     matches <TT
+CLASS="LITERAL"
+>www1.example.com</TT
+>, 
+     <TT
+CLASS="LITERAL"
+>www4.example.cc</TT
+>, <TT
+CLASS="LITERAL"
+>wwwd.example.cy</TT
+>, 
+     <TT
+CLASS="LITERAL"
+>wwwz.example.com</TT
+> etc., but <I
+CLASS="EMPHASIS"
+>not</I
+> 
+     <TT
+CLASS="LITERAL"
+>wwww.example.com</TT
+>.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="AEN1686"
+>8.4.2. The Path Pattern</A
+></H3
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> uses Perl compatible regular expressions
+ (through the <A
+HREF="http://www.pcre.org/"
+TARGET="_top"
+>PCRE</A
+> library) for
+ matching the path.</P
+><P
+> There is an <A
+HREF="appendix.html#REGEX"
+>Appendix</A
+> with a brief quick-start into regular
+ expressions, and full (very technical) documentation on PCRE regex syntax is available on-line
+ at <A
+HREF="http://www.pcre.org/man.txt"
+TARGET="_top"
+>http://www.pcre.org/man.txt</A
+>.
+ You might also find the Perl man page on regular expressions (<TT
+CLASS="LITERAL"
+>man perlre</TT
+>)
+ useful, which is available on-line at <A
+HREF="http://www.perldoc.com/perl5.6/pod/perlre.html"
+TARGET="_top"
+>http://www.perldoc.com/perl5.6/pod/perlre.html</A
+>.</P
+><P
+> Note that the path pattern is automatically left-anchored at the <SPAN
+CLASS="QUOTE"
+>"/"</SPAN
+>,
+ i.e. it matches as if it would start with a <SPAN
+CLASS="QUOTE"
+>"^"</SPAN
+> (regular expression speak 
+ for the beginning of a line).</P
+><P
+> Please also note that matching in the path is <I
+CLASS="EMPHASIS"
+>CASE INSENSITIVE</I
+>
+ by default, but you can switch to case sensitive at any point in the pattern by using the 
+ <SPAN
+CLASS="QUOTE"
+>"(?-i)"</SPAN
+> switch: <TT
+CLASS="LITERAL"
+>www.example.com/(?-i)PaTtErN.*</TT
+> will match
+ only documents whose path starts with <TT
+CLASS="LITERAL"
+>PaTtErN</TT
+> in
+ <I
+CLASS="EMPHASIS"
+>exactly</I
+> this capitalization.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="ACTIONS"
+>8.5. Actions</A
+></H2
+><P
+> All actions are disabled by default, until they are explicitly enabled
+ somewhere in an actions file. Actions are turned on if preceded with a
+ <SPAN
+CLASS="QUOTE"
+>"+"</SPAN
+>, and turned off if preceded with a <SPAN
+CLASS="QUOTE"
+>"-"</SPAN
+>. So a
+ <TT
+CLASS="LITERAL"
+>+action</TT
+> means <SPAN
+CLASS="QUOTE"
+>"do that action"</SPAN
+>, e.g.
+ <TT
+CLASS="LITERAL"
+>+block</TT
+> means <SPAN
+CLASS="QUOTE"
+>"please block URLs that match the
+ following patterns"</SPAN
+>, and <TT
+CLASS="LITERAL"
+>-block</TT
+> means <SPAN
+CLASS="QUOTE"
+>"don't
+ block URLs that match the following patterns, even if <TT
+CLASS="LITERAL"
+>+block</TT
+>
+ previously applied."</SPAN
+>&#13;</P
+><P
+> 
+ Again, actions are invoked by placing them on a line, enclosed in curly braces and
+ separated by whitespace, like in 
+ <TT
+CLASS="LITERAL"
+>{+some-action -some-other-action{some-parameter}}</TT
+>,
+ followed by a list of URL patterns, one per line, to which they apply.
+ Together, the actions line and the following pattern lines make up a section
+ of the actions file. </P
+><P
+> 
+ There are three classes of actions:</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>  
+   Boolean, i.e the action can only be <SPAN
+CLASS="QUOTE"
+>"enabled"</SPAN
+> or
+   <SPAN
+CLASS="QUOTE"
+>"disabled"</SPAN
+>. Syntax:
+  </P
+><P
+>   <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  +<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>        # enable action <TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>
+  -<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>        # disable action <TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+></PRE
+></TD
+></TR
+></TABLE
+>
+  </P
+><P
+>  
+   Example: <TT
+CLASS="LITERAL"
+>+block</TT
+>
+  </P
+></LI
+><LI
+><P
+>  
+   Parameterized, where some value is required in order to enable this type of action.
+   Syntax:
+  </P
+><P
+>   <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  +<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>param</I
+></TT
+>}  # enable action and set parameter to <TT
+CLASS="REPLACEABLE"
+><I
+>param</I
+></TT
+>,
+               # overwriting parameter from previous match if necessary
+  -<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>         # disable action. The parameter can be omitted</PRE
+></TD
+></TR
+></TABLE
+>
+  </P
+><P
+>   Note that if the URL matches multiple positive forms of a parameterized action,
+   the last match wins, i.e. the params from earlier matches are simply ignored.
+  </P
+><P
+>  
+   Example: <TT
+CLASS="LITERAL"
+>+hide-user-agent{ Mozilla 1.0 }</TT
+>
+  </P
+></LI
+><LI
+><P
+>  
+   Multi-value. These look exactly like parameterized actions,
+   but they behave differently: If the action applies multiple times to the
+   same URL, but with different parameters, <I
+CLASS="EMPHASIS"
+>all</I
+> the parameters
+   from <I
+CLASS="EMPHASIS"
+>all</I
+> matches are remembered. This is used for actions
+   that can be executed for the same request repeatedly, like adding multiple
+   headers, or filtering through multiple filters. Syntax:
+  </P
+><P
+>   <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  +<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>param</I
+></TT
+>}   # enable action and add <TT
+CLASS="REPLACEABLE"
+><I
+>param</I
+></TT
+> to the list of parameters
+  -<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>param</I
+></TT
+>}   # remove the parameter <TT
+CLASS="REPLACEABLE"
+><I
+>param</I
+></TT
+> from the list of parameters
+                # If it was the last one left, disable the action.
+  <TT
+CLASS="REPLACEABLE"
+><I
+>-name</I
+></TT
+>          # disable this action completely and remove all parameters from the list</PRE
+></TD
+></TR
+></TABLE
+>
+  </P
+><P
+>  
+   Examples: <TT
+CLASS="LITERAL"
+>+add-header{X-Fun-Header: Some text}</TT
+> and
+   <TT
+CLASS="LITERAL"
+>+filter{html-annoyances}</TT
+>
+  </P
+></LI
+></UL
+></P
+><P
+> If nothing is specified in any actions file, no <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> are
+ taken. So in this case <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> would just be a
+ normal, non-blocking, non-anonymizing proxy. You must specifically enable the
+ privacy and blocking features you need (although the provided default actions
+ files will give a good starting point).</P
+><P
+> Later defined actions always over-ride earlier ones.  So exceptions 
+ to any rules you make, should come in the latter part of the file (or 
+ in a file that is processed later when using multiple actions files). For
+ multi-valued actions, the actions are applied in the order they are specified.
+ Actions files are processed in the order they are defined in
+ <TT
+CLASS="FILENAME"
+>config</TT
+> (the default installation has three actions
+ files). It also quite possible for any given URL pattern to match more than
+ one pattern and thus more than one set of actions!</P
+><P
+> The list of valid <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> actions are:</P
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="ADD-HEADER"
+>8.5.1. add-header</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Confuse log analysis, custom applications</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Sends a user defined HTTP header to the web server.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Multi-value.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    Any string value is possible. Validity of the defined HTTP headers is not checked.
+    It is recommended that you use the <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="LITERAL"
+>X-</TT
+>"</SPAN
+> prefix
+    for custom headers.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This action may be specified multiple times, in order to define multiple 
+    headers. This is rarely needed for the typical user. If you don't know what 
+    <SPAN
+CLASS="QUOTE"
+>"HTTP headers"</SPAN
+> are, you definitely don't need to worry about this 
+    one.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+add-header{X-User-Tracking: sucks}</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="BLOCK"
+>8.5.2. block</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Block ads or other obnoxious content</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Requests for URLs to which this action applies are blocked, i.e. the requests are not
+    forwarded to the remote server, but answered locally with a substitute page or image,
+    as determined by the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+>
+    and <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+></TT
+> actions.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>N/A</P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> sends a special <SPAN
+CLASS="QUOTE"
+>"BLOCKED"</SPAN
+> page
+    for requests to blocked pages. This page contains links to find out why the request
+    was blocked, and a click-through to the blocked content (the latter only if compiled with the
+    force feature enabled). The <SPAN
+CLASS="QUOTE"
+>"BLOCKED"</SPAN
+> page adapts to the available
+    screen space -- it displays full-blown if space allows, or miniaturized and text-only
+    if loaded into a small frame or window. If you are using <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+    right now, you can take a look at the 
+    <A
+HREF="http://ads.bannerserver.example.com/nasty-ads/sponsor.html"
+TARGET="_top"
+><SPAN
+CLASS="QUOTE"
+>"BLOCKED"</SPAN
+>
+    page</A
+>.
+   </P
+><P
+> 
+    A very important exception occurs if <I
+CLASS="EMPHASIS"
+>both</I
+> 
+    <TT
+CLASS="LITERAL"
+>block</TT
+> and <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+>,
+    apply to the same request: it will then be replaced by an image. If 
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+></TT
+>
+    (see below) also applies, the type of image will be determined by its parameter,
+    if not, the standard checkerboard pattern is sent.
+   </P
+><P
+>    It is important to understand this process, in order 
+    to understand how <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> deals with 
+    ads and other unwanted content.
+   </P
+><P
+>    The <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+>
+    action can perform a very similar task, by <SPAN
+CLASS="QUOTE"
+>"blocking"</SPAN
+>
+    banner images and other content through rewriting the relevant URLs in the
+    document's HTML source, so they don't get requested in the first place.
+    Note that this is a totally different technique, and it's easy to confuse the two.
+   </P
+></DD
+><DT
+>Example usage (section):</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{+block}      # Block and replace with "blocked" page
+.nasty-stuff.example.com
+
+{+block +handle-as-image} # Block and replace with image
+.ad.doubleclick.net
+.ads.r.us</PRE
+></TD
+></TR
+></TABLE
+>
+    </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="CRUNCH-INCOMING-COOKIES"
+>8.5.3. crunch-incoming-cookies</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>    Prevent the web server from setting any cookies on your system
+   </P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Deletes any <SPAN
+CLASS="QUOTE"
+>"Set-Cookie:"</SPAN
+> HTTP headers from server replies.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This action is only concerned with <I
+CLASS="EMPHASIS"
+>incoming</I
+> cookies. For
+    <I
+CLASS="EMPHASIS"
+>outgoing</I
+> cookies, use
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#CRUNCH-OUTGOING-COOKIES"
+>crunch-outgoing-cookies</A
+></TT
+>.
+    Use <I
+CLASS="EMPHASIS"
+>both</I
+> to disable cookies completely.
+   </P
+><P
+>    It makes <I
+CLASS="EMPHASIS"
+>no sense at all</I
+> to use this action in conjunction
+    with the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SESSION-COOKIES-ONLY"
+>session-cookies-only</A
+></TT
+> action,
+    since it would prevent the session cookies from being set.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+crunch-incoming-cookies</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="CRUNCH-OUTGOING-COOKIES"
+>8.5.4. crunch-outgoing-cookies</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>    Prevent the web server from reading any cookies from your system
+   </P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Deletes any <SPAN
+CLASS="QUOTE"
+>"Cookie:"</SPAN
+> HTTP headers from client requests.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This action is only concerned with <I
+CLASS="EMPHASIS"
+>outgoing</I
+> cookies. For
+    <I
+CLASS="EMPHASIS"
+>incoming</I
+> cookies, use
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#CRUNCH-INCOMING-COOKIES"
+>crunch-incoming-cookies</A
+></TT
+>.
+    Use <I
+CLASS="EMPHASIS"
+>both</I
+> to disable cookies completely.
+   </P
+><P
+>    It makes <I
+CLASS="EMPHASIS"
+>no sense at all</I
+> to use this action in conjunction
+    with the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SESSION-COOKIES-ONLY"
+>session-cookies-only</A
+></TT
+> action,
+    since it would prevent the session cookies from being read.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+crunch-outgoing-cookies</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="DEANIMATE-GIFS"
+>8.5.5. deanimate-gifs</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Stop those annoying, distracting animated GIF images.</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    De-animate GIF animations, i.e. reduce them to their first or last image.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Parameterized.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    <SPAN
+CLASS="QUOTE"
+>"last"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"first"</SPAN
+>
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This will also shrink the images considerably (in bytes, not pixels!). If
+    the option <SPAN
+CLASS="QUOTE"
+>"first"</SPAN
+> is given, the first frame of the animation
+    is used as the replacement. If <SPAN
+CLASS="QUOTE"
+>"last"</SPAN
+> is given, the last
+    frame of the animation is used instead, which probably makes more sense for
+    most banner animations, but also has the risk of not showing the entire
+    last frame (if it is only a delta to an earlier frame).
+   </P
+><P
+>    You can safely use this action with patterns that will also match non-GIF
+    objects, because no attempt will be made at anything that doesn't look like
+    a GIF.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>      <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+deanimate-gifs{last}</PRE
+></TD
+></TR
+></TABLE
+>
+    </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="DOWNGRADE-HTTP-VERSION"
+>8.5.6. downgrade-http-version</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Work around (very rare) problems with HTTP/1.1</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Downgrades HTTP/1.1 client requests and server replies to HTTP/1.0.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This is a left-over from the time when <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+    didn't support important HTTP/1.1 features well. It is left here for the
+    unlikely case that you experience HTTP/1.1 related problems with some server
+    out there. Not all (optional) HTTP/1.1 features are supported yet, so there
+    is a chance you might need this action.
+   </P
+></DD
+><DT
+>Example usage (section):</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{+downgrade-http-version}
+problem-host.example.com</PRE
+></TD
+></TR
+></TABLE
+>
+    </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="FAST-REDIRECTS"
+>8.5.7. fast-redirects</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Fool some click-tracking scripts and speed up indirect links</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Cut off all but the last valid URL from requests.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>  
+    Many sites, like yahoo.com, don't just link to other sites. Instead, they
+    will link to some script on their own servers, giving the destination as a
+    parameter, which will then redirect you to the final target. URLs
+    resulting from this scheme typically look like:
+    <I
+CLASS="EMPHASIS"
+>http://some.place/click-tracker.cgi?target=http://some.where.else</I
+>.
+  </P
+><P
+>    Sometimes, there are even multiple consecutive redirects encoded in the
+    URL. These redirections via scripts make your web browsing more traceable,
+    since the server from which you follow such a link can see where you go
+    to. Apart from that, valuable bandwidth and time is wasted, while your
+    browser ask the server for one redirect after the other. Plus, it feeds
+    the advertisers.
+   </P
+><P
+>    This feature is currently not very smart and is scheduled for improvement.
+    It is likely to break some sites. You should expect to need possibly 
+    many exceptions to this action, if it is enabled by default in
+    <TT
+CLASS="FILENAME"
+>default.action</TT
+>. Some sites just don't work without 
+    it.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{+fast-redirects}</PRE
+></TD
+></TR
+></TABLE
+>
+    </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="FILTER"
+>8.5.8. filter</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Get rid of HTML and JavaScript annoyances, banner advertisements (by size), do fun text replacements, etc.</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Text documents, including HTML and JavaScript, to which this action applies, are filtered on-the-fly
+    through the specified regular expression based substitutions.    
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Parameterized.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    The name of a filter, as defined in the <A
+HREF="filter-file.html"
+>filter file</A
+>
+    (typically <TT
+CLASS="FILENAME"
+>default.filter</TT
+>, set by the
+    <TT
+CLASS="LITERAL"
+><A
+HREF="config.html#FILTERFILE"
+>filterfile</A
+></TT
+>
+    option in the <A
+HREF="config.html"
+>config file</A
+>)
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    For your convenience, there are a bunch of pre-defined filters available 
+    in the distribution filter file that you can use. See the example below for
+    a list.
+   </P
+><P
+>    This is potentially a very powerful feature!  But <SPAN
+CLASS="QUOTE"
+>"rolling your own"</SPAN
+>
+    filters requires a knowledge of regular expressions and HTML.
+   </P
+><P
+>    Filtering requires buffering the page content, which may appear to
+    slow down page rendering since nothing is displayed until all content has
+    passed the filters. (It does not really take longer, but seems that way
+    since the page is not incrementally displayed.) This effect will be more
+    noticeable on slower connections.
+   </P
+><P
+>    At this time, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> cannot (yet!) uncompress compressed
+    documents. If you want filtering to work on all documents, even those that
+    would normally be sent compressed, use the
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#PREVENT-COMPRESSION"
+>prevent-compression</A
+></TT
+>
+    action in conjunction with <TT
+CLASS="LITERAL"
+>filter</TT
+>.
+   </P
+><P
+>    Filtering can achieve some of the effects as the 
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+>
+    action, i.e. it can be used to block ads and banners. 
+   </P
+><P
+>    <A
+HREF="contact.html"
+>Feedback</A
+> with suggestions for new or improved filters is particularly
+    welcome!
+   </P
+></DD
+><DT
+>Example usage (with filters from the distribution <TT
+CLASS="FILENAME"
+>default.filter</TT
+> file):</DT
+><DD
+><P
+>    <A
+NAME="FILTER-HTML-ANNOYANCES"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{html-annoyances}     # Get rid of particularly annoying HTML abuse.</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-JS-ANNOYANCES"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{js-annoyances}       # Get rid of particularly annoying JavaScript abuse</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-BANNERS-BY-SIZE"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{banners-by-size}     # Kill banners by size (<I
+CLASS="EMPHASIS"
+>very</I
+> efficient!)</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-CONTENT-COOKIES"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{content-cookies}     # Kill cookies that come sneaking in the HTML or JS content</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-POPUPS"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{popups}              # Kill all popups in JS and HTML</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-WEBBUGS"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{webbugs}             # Squish WebBugs (1x1 invisible GIFs used for user tracking)</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-FUN"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{fun}                 # Text replacements for subversive browsing fun!</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-FRAMESET-BORDERS"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{frameset-borders}    # Give frames a border and make them resizeable</PRE
+></TD
+></TR
+></TABLE
+> 
+   </P
+><P
+>    <A
+NAME="FILTER-REFRESH-TAGS"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{refresh-tags}        # Kill automatic refresh tags (for dial-on-demand setups)</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-NIMDA"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{nimda}               # Remove Nimda (virus) code.</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-SHOCKWAVE-FLASH"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{shockwave-flash}     # Kill embedded Shockwave Flash objects</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    <A
+NAME="FILTER-CRUDE-PARENTAL"
+></A
+>
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+filter{crude-parental}      # Kill all web pages that contain the words "sex" or "warez"</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="HANDLE-AS-IMAGE"
+>8.5.9. handle-as-image</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Mark URLs as belonging to images (so they'll be replaced by images <I
+CLASS="EMPHASIS"
+>if they get blocked</I
+>)</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    This action alone doesn't do anything noticeable. It just marks URLs as images.
+    If the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> action <I
+CLASS="EMPHASIS"
+>also applies</I
+>,
+    the presence or absence of this mark decides whether an HTML <SPAN
+CLASS="QUOTE"
+>"blocked"</SPAN
+>
+    page, or a replacement image (as determined by the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+></TT
+> action) will be sent to the
+    client as a substitute for the blocked content.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The below generic example section is actually part of <TT
+CLASS="FILENAME"
+>default.action</TT
+>.
+    It marks all URLs with well-known image file name extensions as images and should
+    be left intact. 
+   </P
+><P
+>    Users will probably only want to use the handle-as-image action in conjunction with
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+>, to block sources of banners, whose URLs don't
+    reflect the file type, like in the second example section.
+   </P
+><P
+>    Note that you cannot treat HTML pages as images in most cases. For instance, (inline) ad
+    frames require an HTML page to be sent, or they won't display properly.
+    Forcing <TT
+CLASS="LITERAL"
+>handle-as-image</TT
+> in this situation will not replace the
+    ad frame with an image, but lead to error messages.
+   </P
+></DD
+><DT
+>Example usage (sections):</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Generic image extensions:
+#
+{+handle-as-image}
+/.*\.(gif|jpg|jpeg|png|bmp|ico)$
+
+# These don't look like images, but they're banners and should be
+# blocked as images:
+#
+{+block +handle-as-image}
+some.nasty-banner-server.com/junk.cgi?output=trash
+
+# Banner source! Who cares if they also have non-image content?
+ad.doubleclick.net </PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="HIDE-FORWARDED-FOR-HEADERS"
+>8.5.10. hide-forwarded-for-headers</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Improve privacy by hiding the true source of the request</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Deletes any existing <SPAN
+CLASS="QUOTE"
+>"X-Forwarded-for:"</SPAN
+> HTTP header from client requests,
+    and prevents adding a new one.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    It is fairly safe to leave this on.
+   </P
+><P
+>    This action is scheduled for improvement: It should be able to generate forged 
+    <SPAN
+CLASS="QUOTE"
+>"X-Forwarded-for:"</SPAN
+> headers using random IP addresses from a specified network,
+    to make successive requests from the same client look like requests from a pool of different
+    users sharing the same proxy.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+hide-forwarded-for-headers</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="HIDE-FROM-HEADER"
+>8.5.11. hide-from-header</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Keep your (old and ill) browser from telling web servers your email address</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Deletes any existing <SPAN
+CLASS="QUOTE"
+>"From:"</SPAN
+> HTTP header, or replaces it with the
+    specified string.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Parameterized.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    Keyword: <SPAN
+CLASS="QUOTE"
+>"block"</SPAN
+>, or any user defined value.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The keyword <SPAN
+CLASS="QUOTE"
+>"block"</SPAN
+> will completely remove the header 
+    (not to be confused with the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+>
+    action).
+   </P
+><P
+>    Alternately, you can specify any value you prefer to be sent to the web
+    server. If you do, it is a matter of fairness not to use any address that
+    is actually used by a real person.
+   </P
+><P
+>    This action is rarely needed, as modern web browsers don't send
+    <SPAN
+CLASS="QUOTE"
+>"From:"</SPAN
+> headers anymore.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+hide-from-header{block}</PRE
+></TD
+></TR
+></TABLE
+> or
+    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+hide-from-header{spam-me-senseless@sittingduck.example.com}</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="HIDE-REFERRER"
+>8.5.12. hide-referrer</A
+></H4
+><A
+NAME="HIDE-REFERER"
+></A
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Conceal which link you followed to get to a particular site</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Deletes the <SPAN
+CLASS="QUOTE"
+>"Referer:"</SPAN
+> (sic) HTTP header from the client request,
+    or replaces it with a forged one.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Parameterized.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+></P
+><UL
+><LI
+><P
+><SPAN
+CLASS="QUOTE"
+>"block"</SPAN
+> to delete the header completely.</P
+></LI
+><LI
+><P
+><SPAN
+CLASS="QUOTE"
+>"forge"</SPAN
+> to pretend to be coming from the homepage of the server we are talking to.</P
+></LI
+><LI
+><P
+>Any other string to set a user defined referrer.</P
+></LI
+></UL
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    <SPAN
+CLASS="QUOTE"
+>"forge"</SPAN
+> is the preferred option here, since some servers will
+    not send images back otherwise, in an attempt to prevent their valuable
+    content from being embedded elsewhere (and hence, without being surrounded
+    by <I
+CLASS="EMPHASIS"
+>their</I
+> banners).
+   </P
+><P
+>  
+   <TT
+CLASS="LITERAL"
+>hide-referer</TT
+> is an alternate spelling of
+   <TT
+CLASS="LITERAL"
+>hide-referrer</TT
+> and the two can be can be freely
+   substituted with each other. (<SPAN
+CLASS="QUOTE"
+>"referrer"</SPAN
+> is the
+   correct English spelling, however the HTTP specification has a bug - it
+   requires it to be spelled as <SPAN
+CLASS="QUOTE"
+>"referer"</SPAN
+>.) 
+  </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+hide-referrer{forge}</PRE
+></TD
+></TR
+></TABLE
+> or
+     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+hide-referrer{http://www.yahoo.com/}</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="HIDE-USER-AGENT"
+>8.5.13. hide-user-agent</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Conceal your type of browser and client operating system</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Replaces the value of the <SPAN
+CLASS="QUOTE"
+>"User-Agent:"</SPAN
+> HTTP header
+    in client requests with the specified value.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Parameterized.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    Any user-defined string.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="90%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Warning</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>     This breaks many web sites that depend on looking at this header in order
+     to customize their content for different browsers (which, by the
+     way, is <I
+CLASS="EMPHASIS"
+>NOT</I
+> a <A
+HREF="http://www.javascriptkit.com/javaindex.shtml"
+TARGET="_top"
+>smart way to do
+     that</A
+>!).
+    </P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>    Using this action in multi-user setups or wherever different types of
+    browsers will access the same <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is
+    <I
+CLASS="EMPHASIS"
+>not recommended</I
+>. In single-user, single-browser
+    setups, you might use it to delete your OS version information from
+    the headers, because it is an invitation to exploit known bugs for your
+    OS. It is also occasionally useful to forge this in order to access 
+    sites that won't let you in otherwise (though there may be a good 
+    reason in some cases). Example of this: some MSN sites will not 
+    let <SPAN
+CLASS="APPLICATION"
+>Mozilla</SPAN
+> enter, yet forging to a 
+    <SPAN
+CLASS="APPLICATION"
+>Netscape 6.1</SPAN
+> user-agent works just fine.
+    (Must be just a silly MS goof, I'm sure :-).
+   </P
+><P
+>    This action is scheduled for improvement.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+hide-user-agent{Netscape 6.1 (X11; I; Linux 2.4.18 i686)}</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="KILL-POPUPS"
+>8.5.14. kill-popups<A
+NAME="KILL-POPUP"
+></A
+></A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Eliminate those annoying pop-up windows</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    While loading the document, replace JavaScript code that opens
+    pop-up windows with (syntactically neutral) dummy code on the fly.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This action is easily confused with the built-in, hardwired <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+>
+    action, but there are important differences: For <TT
+CLASS="LITERAL"
+>kill-popups</TT
+>,
+    the document need not be buffered, so it can be incrementally rendered while
+    downloading. But <TT
+CLASS="LITERAL"
+>kill-popups</TT
+> doesn't catch as many pop-ups as
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>popups</I
+></TT
+>}</TT
+>
+    does. 
+   </P
+><P
+>    Think of it as a fast and efficient replacement for a filter that you
+    can use if you don't want any filtering at all. Note that it doesn't make
+    sense to combine it with any <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+> action,
+    since as soon as one <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+> applies,
+    the whole document needs to be buffered anyway, which destroys the advantage of
+    the <TT
+CLASS="LITERAL"
+>kill-popups</TT
+> action over its filter equivalent.
+   </P
+><P
+>    Killing all pop-ups is a dangerous business. Many shops and banks rely on
+    pop-ups to display forms, shopping carts etc, and killing only the unwanted pop-ups 
+    would require artificial intelligence in <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+    If the only kind of pop-ups that you want to kill are exit consoles (those
+    <I
+CLASS="EMPHASIS"
+>really nasty</I
+> windows that appear when you close an other
+    one), you might want to use
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>js-annoyances</I
+></TT
+>}</TT
+>
+    instead. 
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+kill-popups</PRE
+></TD
+></TR
+></TABLE
+></P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="LIMIT-CONNECT"
+>8.5.15. limit-connect</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Prevent abuse of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> as a TCP proxy relay</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Specifies to which ports HTTP CONNECT requests are allowable.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Parameterized.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    A comma-separated list of ports or port ranges (the latter using dashes, with the minimum
+    defaulting to 0 and the maximum to 65K).
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    By default, i.e. if no <TT
+CLASS="LITERAL"
+>limit-connect</TT
+> action applies,
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> only allows HTTP CONNECT
+    requests to port 443 (the standard, secure HTTPS port). Use 
+    <TT
+CLASS="LITERAL"
+>limit-connect</TT
+> if more fine-grained control is desired
+    for some or all destinations.
+   </P
+><P
+>    The CONNECT methods exists in HTTP to allow access to secure websites
+    (<SPAN
+CLASS="QUOTE"
+>"https://"</SPAN
+> URLs) through proxies. It works very simply:
+    the proxy connects to the server on the specified port, and then
+    short-circuits its connections to the client and to the remote server.
+    This can be a big security hole, since CONNECT-enabled proxies can be
+    abused as TCP relays very easily.
+  </P
+><P
+>   If you don't know what any of this means, there probably is no reason to 
+   change this one, since the default is already very restrictive.
+  </P
+></DD
+><DT
+>Example usages:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+limit-connect{443}                   # This is the default and need not be specified.
++limit-connect{80,443}                # Ports 80 and 443 are OK.
++limit-connect{-3, 7, 20-100, 500-}   # Ports less than 3, 7, 20 to 100 and above 500 are OK.
++limit-connect{-}                     # All ports are OK (gaping security hole!)</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="PREVENT-COMPRESSION"
+>8.5.16. prevent-compression</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>    Ensure that servers send the content uncompressed, so it can be
+    passed through <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+>s
+   </P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Adds a header to the request that asks for uncompressed transfer.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    More and more websites send their content compressed by default, which
+    is generally a good idea and saves bandwidth. But for the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+>, <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#DEANIMATE-GIFS"
+>deanimate-gifs</A
+></TT
+>
+    and <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#KILL-POPUPS"
+>kill-popups</A
+></TT
+> actions to work,
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> needs access to the  uncompressed data.
+    Unfortunately, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can't yet(!)  uncompress, filter, and
+    re-compress the content on the fly. So if you want to ensure that all websites, including
+    those that normally compress, can be filtered, you need to use this action.
+   </P
+><P
+>    This will slow down transfers from those websites, though. If you use any of the above-mentioned
+    actions, you will typically want to use <TT
+CLASS="LITERAL"
+>prevent-compression</TT
+> in conjunction
+    with them.
+   </P
+><P
+>    Note that some (rare) ill-configured sites don't handle requests for uncompressed
+    documents correctly (they send an empty document body). If you use <TT
+CLASS="LITERAL"
+>prevent-compression</TT
+>
+    per default, you'll have to add exceptions for those sites. See the example for how to do that.
+   </P
+></DD
+><DT
+>Example usage (sections):</DT
+><DD
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Set default:
+#
+{+prevent-compression}
+/ # Match all sites
+
+# Make exceptions for ill sites:
+#
+{-prevent-compression}
+www.debianhelp.org
+www.pclinuxonline.com</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="SEND-VANILLA-WAFER"
+>8.5.17. send-vanilla-wafer</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>    Feed log analysis scripts with useless data.
+   </P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Sends a cookie with each request stating that you do not accept any copyright
+    on cookies sent to you, and asking the site operator not to track you.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The vanilla wafer is a (relatively) unique header and could conceivably be used to track you.
+   </P
+><P
+>    This action is rarely used and not enabled in the default configuration.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+send-vanilla-wafer</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="SEND-WAFER"
+>8.5.18. send-wafer</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>    Send custom cookies or feed log analysis scripts with even more useless data.
+   </P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Sends a custom, user-defined cookie with each request.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Multi-value.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    A string of the form <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>=<TT
+CLASS="REPLACEABLE"
+><I
+>value</I
+></TT
+>"</SPAN
+>.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    Being multi-valued, multiple instances of this action can apply to the same request,
+    resulting in multiple cookies being sent.
+   </P
+><P
+>    This action is rarely used and not enabled in the default configuration.
+   </P
+></DD
+><DT
+>Example usage (section):</DT
+><DD
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{+send-wafer{UsingPrivoxy=true}}
+my-internal-testing-server.void</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="SESSION-COOKIES-ONLY"
+>8.5.19. session-cookies-only</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>    Allow only temporary <SPAN
+CLASS="QUOTE"
+>"session"</SPAN
+> cookies (for the current browser session <I
+CLASS="EMPHASIS"
+>only</I
+>).
+   </P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>    Deletes the <SPAN
+CLASS="QUOTE"
+>"expires"</SPAN
+> field from <SPAN
+CLASS="QUOTE"
+>"Set-Cookie:"</SPAN
+> server headers.
+    Most browsers will not store such cookies permanently and forget them in between sessions.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Boolean.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+>    N/A
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This is less strict than <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#CRUNCH-INCOMING-COOKIES"
+>crunch-incoming-cookies</A
+></TT
+> / 
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#CRUNCH-OUTGOING-COOKIES"
+>crunch-outgoing-cookies</A
+></TT
+> and allows you to browse
+    websites that insist or rely on setting cookies, without compromising your privacy too badly.
+   </P
+><P
+>    Most browsers will not permanently store cookies that have been processed by
+    <TT
+CLASS="LITERAL"
+>session-cookies-only</TT
+> and will forget about them between sessions.
+    This makes profiling cookies useless, but won't break sites which require cookies so
+    that you can log in for transactions. This is generally turned on for all 
+    sites, and is the recommended setting.
+   </P
+><P
+>    It makes <I
+CLASS="EMPHASIS"
+>no sense at all</I
+> to use <TT
+CLASS="LITERAL"
+>session-cookies-only</TT
+>
+    together with <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#CRUNCH-INCOMING-COOKIES"
+>crunch-incoming-cookies</A
+></TT
+> or
+    <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#CRUNCH-OUTGOING-COOKIES"
+>crunch-outgoing-cookies</A
+></TT
+>. If you do, cookies
+    will be plainly killed.
+   </P
+><P
+>    Note that it is up to the browser how it handles such cookies without an <SPAN
+CLASS="QUOTE"
+>"expires"</SPAN
+>
+    field. If you use an exotic browser, you might want to try it out to be sure.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>     <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+session-cookies-only</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="SET-IMAGE-BLOCKER"
+>8.5.20. set-image-blocker</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Typical use:</DT
+><DD
+><P
+>Choose the replacement for blocked images</P
+></DD
+><DT
+>Effect:</DT
+><DD
+><P
+>     This action alone doesn't do anything noticeable. If <I
+CLASS="EMPHASIS"
+>both</I
+>
+     <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> <I
+CLASS="EMPHASIS"
+>and</I
+> <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+> <I
+CLASS="EMPHASIS"
+>also</I
+>
+     apply, i.e. if the request is to be blocked as an image,
+     <I
+CLASS="EMPHASIS"
+>then</I
+> the parameter of this action decides what will be
+     sent as a replacement.
+   </P
+></DD
+><DT
+>Type:</DT
+><DD
+><P
+>Parameterized.</P
+></DD
+><DT
+>Parameter:</DT
+><DD
+><P
+></P
+><UL
+><LI
+><P
+>      <SPAN
+CLASS="QUOTE"
+>"pattern"</SPAN
+> to send a built-in checkerboard pattern image. The image is visually
+      decent, scales very well, and makes it obvious where banners were busted.
+     </P
+></LI
+><LI
+><P
+>      <SPAN
+CLASS="QUOTE"
+>"blank"</SPAN
+> to send a built-in transparent image. This makes banners disappear
+      completely, but makes it hard to detect where <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has blocked
+      images on a given page and complicates troubleshooting if <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+      has blocked innocent images, like navigation icons.
+     </P
+></LI
+><LI
+><P
+>      <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="REPLACEABLE"
+><I
+>target-url</I
+></TT
+>"</SPAN
+> to
+      send a redirect to <TT
+CLASS="REPLACEABLE"
+><I
+>target-url</I
+></TT
+>. You can redirect
+      to any image anywhere, even in your local filesystem (via <SPAN
+CLASS="QUOTE"
+>"file:///"</SPAN
+> URL).
+     </P
+><P
+>      A good application of redirects is to use special <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>-built-in
+      URLs, which send the built-in images, as <TT
+CLASS="REPLACEABLE"
+><I
+>target-url</I
+></TT
+>.
+      This has the same visual effect as specifying <SPAN
+CLASS="QUOTE"
+>"blank"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"pattern"</SPAN
+> in
+      the first place, but enables your browser to cache the replacement image, instead of requesting
+      it over and over again.
+     </P
+></LI
+></UL
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The URLs for the built-in images are <SPAN
+CLASS="QUOTE"
+>"http://config.privoxy.org/send-banner?type=<TT
+CLASS="REPLACEABLE"
+><I
+>type</I
+></TT
+>"</SPAN
+>, where <TT
+CLASS="REPLACEABLE"
+><I
+>type</I
+></TT
+> is
+    either <SPAN
+CLASS="QUOTE"
+>"blank"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"pattern"</SPAN
+>.
+   </P
+><P
+>    There is a third (advanced) type, called <SPAN
+CLASS="QUOTE"
+>"auto"</SPAN
+>. It is <I
+CLASS="EMPHASIS"
+>NOT</I
+> to be
+    used in <TT
+CLASS="LITERAL"
+>set-image-blocker</TT
+>, but meant for use from <A
+HREF="filter-file.html"
+>filters</A
+>.
+    Auto will select the type of image that would have applied to the referring page, had it been an image.
+   </P
+></DD
+><DT
+>Example usage:</DT
+><DD
+><P
+>    Built-in pattern:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+set-image-blocker{pattern}</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    Redirect to the BSD devil:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+set-image-blocker{http://www.freebsd.org/gifs/dae_up3.gif}</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    Redirect to the built-in pattern for better caching:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>+set-image-blocker{http://config.privoxy.org/send-banner?type=pattern}</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="AEN2600"
+>8.5.21. Summary</A
+></H3
+><P
+> Note that many of these actions have the potential to cause a page to
+ misbehave, possibly even not to display at all. There are many ways 
+ a site designer may choose to design his site, and what HTTP header 
+ content, and other criteria, he may depend on. There is no way to have hard
+ and fast rules for all sites. See the <A
+HREF="appendix.html#ACTIONSANAT"
+>Appendix</A
+> for a brief example on troubleshooting
+ actions.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="ALIASES"
+>8.6. Aliases</A
+></H2
+><P
+> Custom <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+>, known to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ as <SPAN
+CLASS="QUOTE"
+>"aliases"</SPAN
+>, can be defined by combining other actions.
+ These can in turn be invoked just like the built-in actions.
+ Currently, an alias name can contain any character except space, tab,
+ <SPAN
+CLASS="QUOTE"
+>"="</SPAN
+>,
+ <SPAN
+CLASS="QUOTE"
+>"{"</SPAN
+> and <SPAN
+CLASS="QUOTE"
+>"}"</SPAN
+>, but we <I
+CLASS="EMPHASIS"
+>strongly 
+ recommend</I
+> that you only use <SPAN
+CLASS="QUOTE"
+>"a"</SPAN
+> to <SPAN
+CLASS="QUOTE"
+>"z"</SPAN
+>,
+ <SPAN
+CLASS="QUOTE"
+>"0"</SPAN
+> to <SPAN
+CLASS="QUOTE"
+>"9"</SPAN
+>, <SPAN
+CLASS="QUOTE"
+>"+"</SPAN
+>, and <SPAN
+CLASS="QUOTE"
+>"-"</SPAN
+>.
+ Alias names are not case sensitive, and are not required to start with a
+ <SPAN
+CLASS="QUOTE"
+>"+"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"-"</SPAN
+> sign, since they are merely textually
+ expanded.</P
+><P
+> Aliases can be used throughout the actions file, but they <I
+CLASS="EMPHASIS"
+>must be
+ defined in a special section at the top of the file!</I
+>
+ And there can only be one such section per actions file. Each actions file may
+ have its own alias section, and the aliases defined in it are only visible
+ within that file.</P
+><P
+> There are two main reasons to use aliases: One is to save typing for frequently
+ used combinations of actions, the other one is a gain in flexibility: If you
+ decide once how you want to handle shops by defining an alias called
+ <SPAN
+CLASS="QUOTE"
+>"shop"</SPAN
+>, you can later change your policy on shops in
+ <I
+CLASS="EMPHASIS"
+>one</I
+> place, and your changes will take effect everywhere
+ in the actions file where the <SPAN
+CLASS="QUOTE"
+>"shop"</SPAN
+> alias is used. Calling aliases
+ by their purpose also makes your actions files more readable.</P
+><P
+> Currently, there is one big drawback to using aliases, though:
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s built-in web-based action file
+ editor honors aliases when reading the actions files, but it expands
+ them before writing. So the effects of your aliases are of course preserved,
+ but the aliases themselves are lost when you edit sections that use aliases
+ with it.
+ This is likely to change in future versions of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.</P
+><P
+> Now let's define some aliases...</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> # Useful custom aliases we can use later.
+ #
+ # Note the (required!) section header line and that this section
+ # must be at the top of the actions file!
+ #
+ {{alias}}
+
+ # These aliases just save typing later:
+ # (Note that some already use other aliases!)
+ #
+ +crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+ -crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ block-as-image      = +block +handle-as-image
+ mercy-for-cookies   = -crunch-all-cookies -session-cookies-only
+
+ # These aliases define combinations of actions
+ # that are useful for certain types of sites:
+ #
+ fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups
+ shop        = -crunch-all-cookies -filter{popups} -kill-popups
+
+ # Short names for other aliases, for really lazy people ;-)
+ #
+ c0 = +crunch-all-cookies
+ c1 = -crunch-all-cookies</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> ...and put them to use. These sections would appear in the lower part of an 
+ actions file and define exceptions to the default actions (as specified further
+ up for the <SPAN
+CLASS="QUOTE"
+>"/"</SPAN
+> pattern):</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> # These sites are either very complex or very keen on
+ # user data and require minimal interference to work:
+ #
+ {fragile}
+ .office.microsoft.com
+ .windowsupdate.microsoft.com
+ .nytimes.com
+
+ # Shopping sites:
+ # Allow cookies (for setting and retrieving your customer data)
+ #           
+ {shop}
+ .quietpc.com
+ .worldpay.com   # for quietpc.com
+ .scan.co.uk
+
+ # These shops require pop-ups:
+ #
+ {shop -kill-popups -filter{popups}}
+  .dabs.com
+  .overclockers.co.uk</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Aliases like <SPAN
+CLASS="QUOTE"
+>"shop"</SPAN
+> and <SPAN
+CLASS="QUOTE"
+>"fragile"</SPAN
+> are often used for 
+ <SPAN
+CLASS="QUOTE"
+>"problem"</SPAN
+> sites that require some actions to be disabled 
+ in order to function properly.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="ACT-EXAMPLES"
+>8.7. Actions Files Tutorial</A
+></H2
+><P
+> The above chapters have shown <A
+HREF="actions-file.html"
+>which actions files
+ there are and how they are organized</A
+>, how actions are <A
+HREF="actions-file.html#ACTIONS"
+>specified</A
+> and <A
+HREF="actions-file.html#ACTIONS-APPLY"
+>applied
+ to URLs</A
+>, how <A
+HREF="actions-file.html#AF-PATTERNS"
+>patterns</A
+> work, and how to
+ define and use <A
+HREF="actions-file.html#ALIASES"
+>aliases</A
+>. Now, let's look at an
+ example <TT
+CLASS="FILENAME"
+>default.action</TT
+> and <TT
+CLASS="FILENAME"
+>user.action</TT
+>
+ file and see how all these pieces come together:</P
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="AEN2652"
+>8.7.1. default.action</A
+></H3
+><P
+>Every config file should start with a short comment stating its purpose:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Sample default.action file &#60;developers@privoxy.org&#62;</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>Then, since this is the <TT
+CLASS="FILENAME"
+>default.action</TT
+> file, the
+first section is a special section for internal use that you needn't
+change or worry about:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>##########################################################################
+# Settings -- Don't change! For internal Privoxy use ONLY.
+##########################################################################
+
+{{settings}}
+for-privoxy-version=3.0</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>After that comes the (optional) alias section. We'll use the example
+section from the above <A
+HREF="actions-file.html#ALIASES"
+>chapter on aliases</A
+>,
+that also explains why and how aliases are used:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>##########################################################################
+# Aliases
+##########################################################################
+{{alias}}
+
+# These aliases just save typing later:
+# (Note that some already use other aliases!)
+#
++crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+block-as-image      = +block +handle-as-image
+mercy-for-cookies   = -crunch-all-cookies -session-cookies-only
+
+# These aliases define combinations of actions
+# that are useful for certain types of sites:
+#
+fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups
+shop        = mercy-for-cookies -filter{popups} -kill-popups</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Now come the regular sections, i.e. sets of actions, accompanied
+ by URL patterns to which they apply. Remember <I
+CLASS="EMPHASIS"
+>all actions
+ are disabled when matching starts</I
+>, so we have to explicitly
+ enable the ones we want.</P
+><P
+> The first regular section is probably the most important. It has only
+ one pattern, <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="LITERAL"
+>/</TT
+>"</SPAN
+>, but this pattern
+ <A
+HREF="actions-file.html#AF-PATTERNS"
+>matches all URLs.</A
+>. Therefore, the
+ set of actions used in this <SPAN
+CLASS="QUOTE"
+>"default"</SPAN
+> section <I
+CLASS="EMPHASIS"
+>will
+ be applied to all requests as a start</I
+>. It can  be partly or
+ wholly overridden by later matches further down this file, or in user.action,
+ but it will still be largely responsible for your overall browsing
+ experience.</P
+><P
+> Again, at the start of matching, all actions are disabled, so there is
+ no real need to disable any actions here, but we will do that nonetheless,
+ to have a complete listing for your reference. (Remember: A <SPAN
+CLASS="QUOTE"
+>"+"</SPAN
+>
+ preceding the action name enables the action, a <SPAN
+CLASS="QUOTE"
+>"-"</SPAN
+> disables!).
+ Also note how this long line has been made more readable by splitting it into
+ multiple lines with line continuation.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>##########################################################################
+# "Defaults" section:
+##########################################################################
+ { \
+ -<A
+HREF="actions-file.html#ADD-HEADER"
+>add-header</A
+> \
+ -<A
+HREF="actions-file.html#BLOCK"
+>block</A
+> \
+ -<A
+HREF="actions-file.html#CRUNCH-INCOMING-COOKIES"
+>crunch-incoming-cookies</A
+> \
+ -<A
+HREF="actions-file.html#CRUNCH-OUTGOING-COOKIES"
+>crunch-outgoing-cookies</A
+> \
+ +<A
+HREF="actions-file.html#DEANIMATE-GIFS"
+>deanimate-gifs</A
+> \
+ -<A
+HREF="actions-file.html#DOWNGRADE-HTTP-VERSION"
+>downgrade-http-version</A
+> \
+ +<A
+HREF="actions-file.html#FAST-REDIRECTS"
+>fast-redirects</A
+> \
+ +<A
+HREF="actions-file.html#FILTER-HTML-ANNOYANCES"
+>filter{html-annoyances}</A
+> \
+ +<A
+HREF="actions-file.html#FILTER-JS-ANNOYANCES"
+>filter{js-annoyances}</A
+> \
+ -<A
+HREF="actions-file.html#FILTER-CONTENT-COOKIES"
+>filter{content-cookies}</A
+> \
+ +<A
+HREF="actions-file.html#FILTER-POPUPS"
+>filter{popups}</A
+> \
+ +<A
+HREF="actions-file.html#FILTER-WEBBUGS"
+>filter{webbugs}</A
+> \
+ -<A
+HREF="actions-file.html#FILTER-REFRESH-TAGS"
+>filter{refresh-tags}</A
+> \
+ -<A
+HREF="actions-file.html#FILTER-FUN"
+>filter{fun}</A
+> \
+ +<A
+HREF="actions-file.html#FILTER-NIMDA"
+>filter{nimda}</A
+> \
+ +<A
+HREF="actions-file.html#FILTER-BANNERS-BY-SIZE"
+>filter{banners-by-size}</A
+> \
+ -<A
+HREF="actions-file.html#FILTER-SHOCKWAVE-FLASH"
+>filter{shockwave-flash}</A
+> \
+ -<A
+HREF="actions-file.html#FILTER-CRUDE-PARENTAL"
+>filter{crude-parental}</A
+> \
+ -<A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+> \
+ +<A
+HREF="actions-file.html#HIDE-FORWARDED-FOR-HEADERS"
+>hide-forwarded-for-headers</A
+> \
+ +<A
+HREF="actions-file.html#HIDE-FROM-HEADER"
+>hide-from-header{block}</A
+> \
+ +<A
+HREF="actions-file.html#HIDE-REFERER"
+>hide-referrer{forge}</A
+> \
+ -<A
+HREF="actions-file.html#HIDE-USER-AGENT"
+>hide-user-agent</A
+> \
+ -<A
+HREF="actions-file.html#KILL-POPUPS"
+>kill-popups</A
+> \
+ -<A
+HREF="actions-file.html#LIMIT-CONNECT"
+>limit-connect</A
+> \
+ +<A
+HREF="actions-file.html#PREVENT-COMPRESSION"
+>prevent-compression</A
+> \
+ -<A
+HREF="actions-file.html#SEND-VANILLA-WAFER"
+>send-vanilla-wafer</A
+> \
+ -<A
+HREF="actions-file.html#SEND-WAFER"
+>send-wafer</A
+> \
+ +<A
+HREF="actions-file.html#SESSION-COOKIES-ONLY"
+>session-cookies-only</A
+> \
+ +<A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker{pattern}</A
+> \
+ }
+ / # forward slash will match *all* potential URL patterns.</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> The default behavior is now set. Note that some actions, like not hiding
+ the user agent, are part of a <SPAN
+CLASS="QUOTE"
+>"general policy"</SPAN
+> that applies
+ universally and won't get any exceptions defined later. Other choices,
+ like not blocking (which is <I
+CLASS="EMPHASIS"
+>understandably</I
+> the
+ default!) need exceptions, i.e. we need to specify explicitly what we
+ want to block in later sections.
+ We will also want to make exceptions from our general pop-up-killing,
+ and use our defined aliases for that.</P
+><P
+> The first of our specialized sections is concerned with <SPAN
+CLASS="QUOTE"
+>"fragile"</SPAN
+>
+ sites, i.e. sites that require minimum interference, because they are either
+ very complex or very keen on tracking you (and have mechanisms in place that
+ make them unusable for people who avoid being tracked). We will simply use
+ our pre-defined <TT
+CLASS="LITERAL"
+>fragile</TT
+> alias instead of stating the list
+ of actions explicitly:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>##########################################################################
+# Exceptions for sites that'll break under the default action set:
+##########################################################################
+
+# "Fragile" Use a minimum set of actions for these sites (see alias above):
+#
+{ fragile }
+.office.microsoft.com           # surprise, surprise!
+.windowsupdate.microsoft.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Shopping sites are not as fragile, but they typically
+ require cookies to log in, and pop-up windows for shopping
+ carts or item details. Again, we'll use a pre-defined alias:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Shopping sites:
+#
+{ shop }
+.quietpc.com 
+.worldpay.com   # for quietpc.com
+.jungle.com
+.scan.co.uk</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Then, there are sites which rely on pop-up windows (yuck!) to work.
+ Since we made pop-up-killing our default above, we need to make exceptions
+ now. <A
+HREF="http://www.mozilla.org/"
+TARGET="_top"
+>Mozilla</A
+> users, who
+ can turn on smart handling of unwanted pop-ups in their browsers, can
+ safely choose
+ -<TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER-POPUPS"
+>filter{popups}</A
+></TT
+> (and
+ -<TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#KILL-POPUPS"
+>kill-popups</A
+></TT
+>) above
+ and hence don't need this section. Anyway, disabling an already disabled
+ action doesn't hurt, so we'll define our exceptions regardless of what was
+ chosen in the defaults section:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># These sites require pop-ups too :( 
+#
+{ -<A
+HREF="actions-file.html#KILL-POPUPS"
+>kill-popups</A
+> -<A
+HREF="actions-file.html#FILTER-POPUPS"
+>filter{popups}</A
+> }
+.dabs.com
+.overclockers.co.uk
+.deutsche-bank-24.de</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> The <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FAST-REDIRECTS"
+>fast-redirects</A
+></TT
+>
+ action, which we enabled per default above,  breaks some sites. So disable
+ it for popular sites where we know it misbehaves:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{ -<A
+HREF="actions-file.html#FAST-REDIRECTS"
+>fast-redirects</A
+> }
+login.yahoo.com
+edit.*.yahoo.com
+.google.com
+.altavista.com/.*(like|url|link):http
+.altavista.com/trans.*urltext=http
+.nytimes.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> It is important that <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> knows which
+ URLs belong to images, so that <I
+CLASS="EMPHASIS"
+>if</I
+> they are to
+ be blocked, a substitute image can be sent, rather than an HTML page.
+ Contacting the remote site to find out is not an option, since it
+ would destroy the loading time advantage of banner blocking, and it
+ would feed the advertisers (in terms of money <I
+CLASS="EMPHASIS"
+>and</I
+>
+ information). We can mark any URL as an image with the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+> action,
+ and marking all URLs that end in a known image file extension is a
+ good start:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>##########################################################################
+# Images:
+##########################################################################
+
+# Define which file types will be treated as images, in case they get
+# blocked further down this file:
+#
+{ +<A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+> }
+/.*\.(gif|jpe?g|png|bmp|ico)$</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> And then there are known banner sources. They often use scripts to
+ generate the banners, so it won't be visible from the URL that the
+ request is for an image. Hence we block them <I
+CLASS="EMPHASIS"
+>and</I
+>
+ mark them as images in one go, with the help of our
+ <TT
+CLASS="LITERAL"
+>block-as-image</TT
+> alias defined above. (We could of
+ course just as well use <TT
+CLASS="LITERAL"
+>+<A
+HREF="actions-file.html#BLOCK"
+>block</A
+>
+ +<A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+> here.)
+ Remember that the type of the replacement image is chosen by the
+ <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+></TT
+>
+ action. Since all URLs have matched the default section with its
+ <TT
+CLASS="LITERAL"
+>+<A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+>{pattern}</TT
+>
+ action before, it still applies and needn't be repeated:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Known ad generators:
+#
+{ block-as-image }
+ar.atwola.com 
+.ad.doubleclick.net
+.ad.*.doubleclick.net
+.a.yimg.com/(?:(?!/i/).)*$
+.a[0-9].yimg.com/(?:(?!/i/).)*$
+bs*.gsanet.com
+bs*.einets.com
+.qkimg.net</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> One of the most important jobs of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ is to block banners. A huge bunch of them are already <SPAN
+CLASS="QUOTE"
+>"blocked"</SPAN
+>
+ by the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+>{banners-by-size}</TT
+>
+ action, which we enabled above, and which deletes the references to banner
+ images from the pages while they are loaded, so the browser doesn't request
+ them anymore, and hence they don't need to be blocked here. But this naturally
+ doesn't catch all banners, and some people choose not to use filters, so we
+ need a comprehensive list of patterns for banner URLs here, and apply the
+ <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> action to them.</P
+><P
+> First comes a bunch of generic patterns, which do most of the work, by
+ matching typical domain and path name components of banners. Then comes
+ a list of individual patterns for specific sites, which is omitted here
+ to keep the example short:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>##########################################################################
+# Block these fine banners:
+##########################################################################
+{ <A
+HREF="actions-file.html#BLOCK"
+>+block</A
+> }
+
+# Generic patterns:
+# 
+ad*.
+.*ads.
+banner?.
+count*.
+/.*count(er)?\.(pl|cgi|exe|dll|asp|php[34]?)
+/(?:.*/)?(publicite|werbung|rekla(ma|me|am)|annonse|maino(kset|nta|s)?)/
+
+# Site-specific patterns (abbreviated):
+#
+.hitbox.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> You wouldn't believe how many advertisers actually call their banner
+ servers ads.<TT
+CLASS="REPLACEABLE"
+><I
+>company</I
+></TT
+>.com, or call the directory
+ in which the banners are stored simply <SPAN
+CLASS="QUOTE"
+>"banners"</SPAN
+>. So the above
+ generic patterns are surprisingly effective.</P
+><P
+> But being very generic, they necessarily also catch URLs that we don't want
+ to block. The pattern <TT
+CLASS="LITERAL"
+>.*ads.</TT
+> e.g. catches 
+ <SPAN
+CLASS="QUOTE"
+>"nasty-<I
+CLASS="EMPHASIS"
+>ads</I
+>.nasty-corp.com"</SPAN
+> as intended,
+ but also <SPAN
+CLASS="QUOTE"
+>"downlo<I
+CLASS="EMPHASIS"
+>ads</I
+>.sourcefroge.net"</SPAN
+> or
+ <SPAN
+CLASS="QUOTE"
+>"<I
+CLASS="EMPHASIS"
+>ads</I
+>l.some-provider.net."</SPAN
+> So here come some
+ well-known exceptions to the <TT
+CLASS="LITERAL"
+>+<A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+>
+ section above.</P
+><P
+> Note that these are exceptions to exceptions from the default! Consider the URL
+ <SPAN
+CLASS="QUOTE"
+>"downloads.sourcefroge.net"</SPAN
+>: Initially, all actions are deactivated,
+ so it wouldn't get blocked. Then comes the defaults section, which matches the
+ URL, but just deactivates the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+>
+ action once again. Then it matches <TT
+CLASS="LITERAL"
+>.*ads.</TT
+>, an exception to the
+ general non-blocking policy, and suddenly
+ <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>+block</A
+></TT
+> applies. And now, it'll match
+ <TT
+CLASS="LITERAL"
+>.*loads.</TT
+>, where <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>-block</A
+></TT
+>
+ applies, so (unless it matches <I
+CLASS="EMPHASIS"
+>again</I
+> further down) it ends up
+ with no <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> action applying.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>##########################################################################
+# Save some innocent victims of the above generic block patterns:
+##########################################################################
+
+# By domain:
+# 
+{ -<A
+HREF="actions-file.html#BLOCK"
+>block</A
+> }
+adv[io]*.  # (for advogato.org and advice.*)
+adsl.      # (has nothing to do with ads)
+ad[ud]*.   # (adult.* and add.*)
+.edu       # (universities don't host banners (yet!))
+.*loads.   # (downloads, uploads etc)
+
+# By path:
+#
+/.*loads/
+
+# Site-specific:
+#
+www.globalintersec.com/adv # (adv = advanced)
+www.ugu.com/sui/ugu/adv</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Filtering source code can have nasty side effects,
+ so make an exception for our friends at sourceforge.net,
+ and all paths with <SPAN
+CLASS="QUOTE"
+>"cvs"</SPAN
+> in them. Note that
+ <TT
+CLASS="LITERAL"
+>-<A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+>
+ disables <I
+CLASS="EMPHASIS"
+>all</I
+> filters in one fell swoop!</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Don't filter code!
+#
+{ -<A
+HREF="actions-file.html#FILTER"
+>filter</A
+> }
+/.*cvs
+.sourceforge.net</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> The actual <TT
+CLASS="FILENAME"
+>default.action</TT
+> is of course more
+ comprehensive, but we hope this example made clear how it works.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="AEN2806"
+>8.7.2. user.action</A
+></H3
+><P
+> So far we are painting with a broad brush by setting general policies,
+ which would be a reasonable starting point for many people. Now, 
+ you'd maybe want to be more specific and have customized rules that
+ are more suitable to your personal habits and preferences. These would
+ be for narrowly defined situations like your ISP or your bank, and should
+ be placed in <TT
+CLASS="FILENAME"
+>user.action</TT
+>, which is parsed after all other 
+ actions files and hence has the last word, over-riding any previously
+ defined actions. <TT
+CLASS="FILENAME"
+>user.action</TT
+> is also a 
+ <I
+CLASS="EMPHASIS"
+>safe</I
+> place for your personal settings, since
+ <TT
+CLASS="FILENAME"
+>default.action</TT
+> is actively maintained by the
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> developers and you'll probably want
+ to install updated versions from time to time.</P
+><P
+> So let's look at a few examples of things that one might typically do in
+ <TT
+CLASS="FILENAME"
+>user.action</TT
+>: </P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># My user.action file. &#60;fred@foobar.com&#62;</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> As <A
+HREF="actions-file.html#ALIASES"
+>aliases</A
+> are local to the actions
+ file that they are defined in, you can't use the ones from
+ <TT
+CLASS="FILENAME"
+>default.action</TT
+>, unless you repeat them here:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># (Re-)define aliases for this file:
+#
+{{alias}}
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+mercy-for-cookies   = -crunch-all-cookies -session-cookies-only
+fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -kill-popups
+shop        = mercy-for-cookies -filter{popups} -kill-popups
+allow-ads   = -block -filter{banners-by-size} # (see below)</PRE
+></TD
+></TR
+></TABLE
+>
+ </P
+><P
+> Say you have accounts on some sites that you visit regularly, and
+ you don't want to have to log in manually each time. So you'd like
+ to allow persistent cookies for these sites. The
+ <TT
+CLASS="LITERAL"
+>mercy-for-cookies</TT
+> alias defined above does exactly
+ that, i.e. it disables crunching of cookies in any direction, and
+ processing of cookies to make them temporary.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{ mercy-for-cookies }
+sunsolve.sun.com
+slashdot.org
+.yahoo.com
+.msdn.microsoft.com
+.redhat.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Your bank needs popups and is allergic to some filter, but you don't
+ know which, so you disable them all:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{ -<A
+HREF="actions-file.html#FILTER"
+>filter</A
+> -<A
+HREF="actions-file.html#KILL-POPUPS"
+>kill-popups</A
+> }
+.your-home-banking-site.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> While browsing the web with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> you
+ noticed some ads that sneaked through, but you were too lazy to
+ report them through our fine and easy <A
+HREF="contact.html"
+>feedback</A
+>
+ system, so you have added them here:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{ +<A
+HREF="actions-file.html#BLOCK"
+>block</A
+> }
+www.a-popular-site.com/some/unobvious/path
+another.popular.site.net/more/junk/here/</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Note that, assuming the banners in the above example have regular image
+ extensions (most do),
+ <TT
+CLASS="LITERAL"
+>+<A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+>
+ need not be specified, since all URLs ending in these extensions will
+ already have been tagged as images in the relevant section of 
+ <TT
+CLASS="FILENAME"
+>default.action</TT
+> by now.</P
+><P
+> Then you noticed that the default configuration breaks Forbes Magazine,
+ but you were too lazy to find out which action is the culprit, and you
+ were again too lazy to give <A
+HREF="contact.html"
+>feedback</A
+>, so
+ you just used the <TT
+CLASS="LITERAL"
+>fragile</TT
+> alias on the site, and
+ -- whoa! -- it worked:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{ fragile }
+.forbes.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> You like the <SPAN
+CLASS="QUOTE"
+>"fun"</SPAN
+> text replacements in <TT
+CLASS="FILENAME"
+>default.filter</TT
+>,
+ but it is disabled in the distributed actions file. (My colleagues on the team just
+ don't have a sense of humour, that's why! ;-). So you'd like to turn it on in your private,
+ update-safe config, once and for all:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{ +<A
+HREF="actions-file.html#FILTER-FUN"
+>filter{fun}</A
+> }
+/ # For ALL sites!</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Note that the above is not really a good idea: There are exceptions
+ to the filters in <TT
+CLASS="FILENAME"
+>default.action</TT
+> for things that
+ really shouldn't be filtered, like code on CVS-&#62;Web interfaces. Since
+ <TT
+CLASS="FILENAME"
+>user.action</TT
+> has the last word, these exceptions
+ won't be valid for the <SPAN
+CLASS="QUOTE"
+>"fun"</SPAN
+> filtering specified here.</P
+><P
+> Finally, you might think about how your favourite free websites are
+ funded, and find that they rely on displaying banner advertisements
+ to survive. So you might want to specifically allow banners for those
+ sites that you feel provide value to you:</P
+><P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>{ allow-ads }
+.sourceforge.net
+.slashdot.org
+.osdn.net</PRE
+></TD
+></TR
+></TABLE
+>   </P
+><P
+> Note that <TT
+CLASS="LITERAL"
+>allow-ads</TT
+> has been aliased to 
+ <TT
+CLASS="LITERAL"
+>-<A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+>
+ <TT
+CLASS="LITERAL"
+>-<A
+HREF="actions-file.html#FILTER-BANNERS-BY-SIZE"
+>filter{banners-by-size}</A
+></TT
+>
+ above.</P
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="config.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="filter-file.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>The Main Configuration File</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The Filter File</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/appendix.html b/doc/webserver/user-manual/appendix.html
new file mode 100644 (file)
index 0000000..9985300
--- /dev/null
@@ -0,0 +1,1918 @@
+<HTML
+><HEAD
+><TITLE
+>Appendix</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="See Also"
+HREF="seealso.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="seealso.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+>&nbsp;</TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="APPENDIX"
+>14. Appendix</A
+></H1
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="REGEX"
+>14.1. Regular Expressions</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> uses Perl-style <SPAN
+CLASS="QUOTE"
+>"regular
+ expressions"</SPAN
+> in its <A
+HREF="actions-file.html"
+>actions
+ files</A
+> and <A
+HREF="filter-file.html"
+>filter file</A
+>,
+ through the <A
+HREF="http://www.pcre.org/"
+TARGET="_top"
+>PCRE</A
+> and
+ <A
+HREF="http://www.oesterhelt.org/pcrs/"
+TARGET="_top"
+>PCRS</A
+> libraries.</P
+><P
+> If you are reading this, you probably don't understand what <SPAN
+CLASS="QUOTE"
+>"regular
+ expressions"</SPAN
+> are, or what they can do. So this will be a very brief
+ introduction only. A full explanation would require a <A
+HREF="http://www.oreilly.com/catalog/regex/"
+TARGET="_top"
+>book</A
+> ;-)</P
+><P
+> Regular expressions provide a language to describe patterns that can be
+ run against strings of characters (letter, numbers, etc), to see if they
+ match the string or not. The  patterns are themselves (sometimes complex)
+ strings of literal characters, combined with  wild-cards, and other special
+ characters, called meta-characters. The <SPAN
+CLASS="QUOTE"
+>"meta-characters"</SPAN
+> have
+ special meanings and are used to build complex patterns to be matched against.
+ Perl Compatible Regular Expressions are an especially convenient
+ <SPAN
+CLASS="QUOTE"
+>"dialect"</SPAN
+> of the regular expression language.</P
+><P
+> To make a simple analogy, we do something similar when we use wild-card
+ characters when listing files with the <B
+CLASS="COMMAND"
+>dir</B
+> command in DOS. 
+ <TT
+CLASS="LITERAL"
+>*.*</TT
+> matches all filenames. The <SPAN
+CLASS="QUOTE"
+>"special"</SPAN
+>
+ character here is the asterisk which matches any and all characters. We can be
+ more specific and use <TT
+CLASS="LITERAL"
+>?</TT
+> to match just individual
+ characters. So <SPAN
+CLASS="QUOTE"
+>"dir file?.text"</SPAN
+> would match
+ <SPAN
+CLASS="QUOTE"
+>"file1.txt"</SPAN
+>, <SPAN
+CLASS="QUOTE"
+>"file2.txt"</SPAN
+>, etc. We are pattern
+ matching, using a similar technique to <SPAN
+CLASS="QUOTE"
+>"regular expressions"</SPAN
+>!</P
+><P
+> Regular expressions do essentially the same thing, but are much, much more
+ powerful. There are many more <SPAN
+CLASS="QUOTE"
+>"special characters"</SPAN
+> and ways of 
+ building complex patterns however. Let's look at a few of the common ones,
+ and then some examples:</P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>.</I
+> - Matches any single character, e.g. <SPAN
+CLASS="QUOTE"
+>"a"</SPAN
+>,
+  <SPAN
+CLASS="QUOTE"
+>"A"</SPAN
+>, <SPAN
+CLASS="QUOTE"
+>"4"</SPAN
+>, <SPAN
+CLASS="QUOTE"
+>":"</SPAN
+>, or <SPAN
+CLASS="QUOTE"
+>"@"</SPAN
+>.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>?</I
+> - The preceding character or expression is matched ZERO or ONE
+  times. Either/or.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>+</I
+> - The preceding character or expression is matched ONE or MORE
+  times.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>*</I
+> - The preceding character or expression is matched ZERO or MORE
+  times.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>\</I
+> - The <SPAN
+CLASS="QUOTE"
+>"escape"</SPAN
+> character denotes that
+  the following character should be taken literally. This is used where one of the 
+  special characters (e.g. <SPAN
+CLASS="QUOTE"
+>"."</SPAN
+>) needs to be taken literally and
+  not as a special meta-character. Example: <SPAN
+CLASS="QUOTE"
+>"example\.com"</SPAN
+>, makes 
+  sure the period is recognized only as a period (and not expanded to its 
+  meta-character meaning of any single character).
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>[]</I
+> - Characters enclosed in brackets will be matched if
+  any of the enclosed characters are encountered. For instance, <SPAN
+CLASS="QUOTE"
+>"[0-9]"</SPAN
+>
+  matches any numeric digit (zero through nine). As an example, we can combine 
+  this with <SPAN
+CLASS="QUOTE"
+>"+"</SPAN
+> to match any digit one of more times: <SPAN
+CLASS="QUOTE"
+>"[0-9]+"</SPAN
+>.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>()</I
+> - parentheses are used to group a sub-expression,
+  or multiple sub-expressions.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  <I
+CLASS="EMPHASIS"
+>|</I
+> - The <SPAN
+CLASS="QUOTE"
+>"bar"</SPAN
+> character works like an
+  <SPAN
+CLASS="QUOTE"
+>"or"</SPAN
+> conditional statement. A match is successful if the
+  sub-expression on either side of <SPAN
+CLASS="QUOTE"
+>"|"</SPAN
+> matches. As an example:
+  <SPAN
+CLASS="QUOTE"
+>"/(this|that) example/"</SPAN
+> uses grouping and the bar character 
+  and would match either <SPAN
+CLASS="QUOTE"
+>"this example"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"that
+  example"</SPAN
+>, and nothing else.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+><P
+> These are just some of the ones you are likely to use when matching URLs with 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and is a long way from a definitive
+ list. This is enough to get us started with a few simple examples which may
+ be more illuminating:</P
+><P
+> <I
+CLASS="EMPHASIS"
+><TT
+CLASS="LITERAL"
+>/.*/banners/.*</TT
+></I
+> - A  simple example
+ that uses the common combination of <SPAN
+CLASS="QUOTE"
+>"."</SPAN
+> and <SPAN
+CLASS="QUOTE"
+>"*"</SPAN
+> to 
+ denote any character, zero or more times. In other words, any string at all.
+ So we start with a literal forward slash, then our regular expression pattern 
+ (<SPAN
+CLASS="QUOTE"
+>".*"</SPAN
+>) another literal forward slash, the string
+ <SPAN
+CLASS="QUOTE"
+>"banners"</SPAN
+>, another forward slash, and lastly another
+ <SPAN
+CLASS="QUOTE"
+>".*"</SPAN
+>. We are building 
+ a directory path here. This will match any file with the path that has a
+ directory named <SPAN
+CLASS="QUOTE"
+>"banners"</SPAN
+> in it. The <SPAN
+CLASS="QUOTE"
+>".*"</SPAN
+> matches
+ any characters, and this could conceivably be more forward slashes, so it
+ might expand into a much longer looking path. For example, this could match:
+ <SPAN
+CLASS="QUOTE"
+>"/eye/hate/spammers/banners/annoy_me_please.gif"</SPAN
+>, or just
+ <SPAN
+CLASS="QUOTE"
+>"/banners/annoying.html"</SPAN
+>, or almost an infinite number of other
+ possible combinations, just so it has <SPAN
+CLASS="QUOTE"
+>"banners"</SPAN
+> in the path
+ somewhere.</P
+><P
+> A now something a little more complex:</P
+><P
+> <I
+CLASS="EMPHASIS"
+><TT
+CLASS="LITERAL"
+>/.*/adv((er)?ts?|ertis(ing|ements?))?/</TT
+></I
+> - 
+ We have several literal forward slashes again (<SPAN
+CLASS="QUOTE"
+>"/"</SPAN
+>), so we are
+ building another expression that is a file path statement. We have another 
+ <SPAN
+CLASS="QUOTE"
+>".*"</SPAN
+>, so we are matching against any conceivable sub-path, just so
+ it matches our expression. The only true literal that <I
+CLASS="EMPHASIS"
+>must
+ match</I
+> our pattern is <SPAN
+CLASS="APPLICATION"
+>adv</SPAN
+>, together with
+ the forward slashes. What comes after the <SPAN
+CLASS="QUOTE"
+>"adv"</SPAN
+> string is the
+ interesting part. </P
+><P
+> Remember the <SPAN
+CLASS="QUOTE"
+>"?"</SPAN
+> means the preceding expression (either a
+ literal character or anything grouped with <SPAN
+CLASS="QUOTE"
+>"(...)"</SPAN
+> in this case)
+ can exist or not, since this means either zero or one match. So
+ <SPAN
+CLASS="QUOTE"
+>"((er)?ts?|ertis(ing|ements?))"</SPAN
+> is optional, as are the
+ individual sub-expressions: <SPAN
+CLASS="QUOTE"
+>"(er)"</SPAN
+>,
+ <SPAN
+CLASS="QUOTE"
+>"(ing|ements?)"</SPAN
+>, and the <SPAN
+CLASS="QUOTE"
+>"s"</SPAN
+>. The <SPAN
+CLASS="QUOTE"
+>"|"</SPAN
+>
+ means <SPAN
+CLASS="QUOTE"
+>"or"</SPAN
+>. We have two of those. For instance, 
+ <SPAN
+CLASS="QUOTE"
+>"(ing|ements?)"</SPAN
+>, can expand to match either <SPAN
+CLASS="QUOTE"
+>"ing"</SPAN
+> 
+ <I
+CLASS="EMPHASIS"
+>OR</I
+> <SPAN
+CLASS="QUOTE"
+>"ements?"</SPAN
+>. What is being done here, is an
+ attempt at matching as many variations of <SPAN
+CLASS="QUOTE"
+>"advertisement"</SPAN
+>, and 
+ similar, as possible. So this would expand to match just <SPAN
+CLASS="QUOTE"
+>"adv"</SPAN
+>,
+ or <SPAN
+CLASS="QUOTE"
+>"advert"</SPAN
+>, or <SPAN
+CLASS="QUOTE"
+>"adverts"</SPAN
+>, or
+ <SPAN
+CLASS="QUOTE"
+>"advertising"</SPAN
+>, or <SPAN
+CLASS="QUOTE"
+>"advertisement"</SPAN
+>, or
+ <SPAN
+CLASS="QUOTE"
+>"advertisements"</SPAN
+>. You get the idea. But it would not match 
+ <SPAN
+CLASS="QUOTE"
+>"advertizements"</SPAN
+> (with a <SPAN
+CLASS="QUOTE"
+>"z"</SPAN
+>). We could fix that by
+ changing our regular expression to: 
+ <SPAN
+CLASS="QUOTE"
+>"/.*/adv((er)?ts?|erti(s|z)(ing|ements?))?/"</SPAN
+>, which would then match
+ either spelling.</P
+><P
+> <I
+CLASS="EMPHASIS"
+><TT
+CLASS="LITERAL"
+>/.*/advert[0-9]+\.(gif|jpe?g)</TT
+></I
+> - Again 
+ another path statement with forward slashes. Anything in the square brackets 
+ <SPAN
+CLASS="QUOTE"
+>"[]"</SPAN
+> can be matched. This is using <SPAN
+CLASS="QUOTE"
+>"0-9"</SPAN
+> as a
+ shorthand expression to mean any digit one through nine. It is the same as
+ saying <SPAN
+CLASS="QUOTE"
+>"0123456789"</SPAN
+>. So any digit matches. The <SPAN
+CLASS="QUOTE"
+>"+"</SPAN
+>
+ means one or more of the preceding expression must be included. The preceding 
+ expression here is what is in the square brackets -- in this case, any digit 
+ one through nine. Then, at the end, we have a grouping: <SPAN
+CLASS="QUOTE"
+>"(gif|jpe?g)"</SPAN
+>. 
+ This includes a <SPAN
+CLASS="QUOTE"
+>"|"</SPAN
+>, so this needs to match the expression on
+ either side of that bar character also. A simple <SPAN
+CLASS="QUOTE"
+>"gif"</SPAN
+> on one side, and the other
+ side will in turn match either <SPAN
+CLASS="QUOTE"
+>"jpeg"</SPAN
+> or <SPAN
+CLASS="QUOTE"
+>"jpg"</SPAN
+>,
+ since the <SPAN
+CLASS="QUOTE"
+>"?"</SPAN
+> means the letter <SPAN
+CLASS="QUOTE"
+>"e"</SPAN
+> is optional and
+ can be matched once or not at all. So we are building an expression here to
+ match image GIF or JPEG type image file. It must include the literal
+ string <SPAN
+CLASS="QUOTE"
+>"advert"</SPAN
+>, then one or more digits, and a <SPAN
+CLASS="QUOTE"
+>"."</SPAN
+>
+ (which is now a literal, and not a special character, since it is escaped
+ with <SPAN
+CLASS="QUOTE"
+>"\"</SPAN
+>), and lastly either <SPAN
+CLASS="QUOTE"
+>"gif"</SPAN
+>, or
+ <SPAN
+CLASS="QUOTE"
+>"jpeg"</SPAN
+>, or <SPAN
+CLASS="QUOTE"
+>"jpg"</SPAN
+>. Some possible matches would
+ include: <SPAN
+CLASS="QUOTE"
+>"//advert1.jpg"</SPAN
+>,
+ <SPAN
+CLASS="QUOTE"
+>"/nasty/ads/advert1234.gif"</SPAN
+>,
+ <SPAN
+CLASS="QUOTE"
+>"/banners/from/hell/advert99.jpg"</SPAN
+>. It would not match
+ <SPAN
+CLASS="QUOTE"
+>"advert1.gif"</SPAN
+> (no leading slash), or
+ <SPAN
+CLASS="QUOTE"
+>"/adverts232.jpg"</SPAN
+> (the expression does not include an
+ <SPAN
+CLASS="QUOTE"
+>"s"</SPAN
+>), or <SPAN
+CLASS="QUOTE"
+>"/advert1.jsp"</SPAN
+> (<SPAN
+CLASS="QUOTE"
+>"jsp"</SPAN
+> is not
+ in the expression anywhere).</P
+><P
+> We are barely scratching the surface of regular expressions here so that you
+ can understand the default <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ configuration files, and maybe use this knowledge to customize your own
+ installation. There is much, much more that can be done with regular
+ expressions. Now that you know enough to get started, you can learn more on
+ your own :/</P
+><P
+> More reading on Perl Compatible Regular expressions: 
+ <A
+HREF="http://www.perldoc.com/perl5.6/pod/perlre.html"
+TARGET="_top"
+>http://www.perldoc.com/perl5.6/pod/perlre.html</A
+></P
+><P
+> For information on regular expression based substititions and their applications
+ in filters, please see the <A
+HREF="filter-file.html"
+>filter file tutorial</A
+>
+ in this manual.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN3353"
+>14.2. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s Internal Pages</A
+></H2
+><P
+> Since <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> proxies each requested 
+ web page, it is easy for <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to 
+ trap certain special URLs. In this way, we can talk directly to
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and see how it is 
+ configured, see how our rules are being applied, change these 
+ rules and other configuration options, and even turn
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> filtering off, all with 
+ a web browser.&#13;</P
+><P
+> The URLs listed below are the special ones that allow direct access 
+ to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Of course,
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> must be running to access these. If 
+ not, you will get a friendly error message. Internet access is not 
+ necessary either.</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>  
+   Privoxy main page: 
+  </P
+><A
+NAME="AEN3368"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+     <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>
+   </P
+></BLOCKQUOTE
+><P
+>   There is a shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+> (But it
+   doesn't provide a fallback to a real page, in case the request is not
+   sent through <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>)
+  </P
+></LI
+><LI
+><P
+>  
+    Show information about the current configuration, including viewing and 
+    editing of actions files:
+  </P
+><A
+NAME="AEN3376"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+    <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>http://config.privoxy.org/show-status</A
+>
+   </P
+></BLOCKQUOTE
+></LI
+><LI
+><P
+>  
+    Show the source code version numbers:
+  </P
+><A
+NAME="AEN3381"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+    <A
+HREF="http://config.privoxy.org/show-version"
+TARGET="_top"
+>http://config.privoxy.org/show-version</A
+>
+   </P
+></BLOCKQUOTE
+></LI
+><LI
+><P
+>  
+   Show the browser's request headers:
+  </P
+><A
+NAME="AEN3386"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+    <A
+HREF="http://config.privoxy.org/show-request"
+TARGET="_top"
+>http://config.privoxy.org/show-request</A
+>
+   </P
+></BLOCKQUOTE
+></LI
+><LI
+><P
+>  
+   Show which actions apply to a URL and why:
+  </P
+><A
+NAME="AEN3391"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+    <A
+HREF="http://config.privoxy.org/show-url-info"
+TARGET="_top"
+>http://config.privoxy.org/show-url-info</A
+>
+   </P
+></BLOCKQUOTE
+></LI
+><LI
+><P
+>  
+   Toggle Privoxy on or off. In this case, <SPAN
+CLASS="QUOTE"
+>"Privoxy"</SPAN
+> continues 
+   to run, but only as a pass-through proxy, with no actions taking place:
+  </P
+><A
+NAME="AEN3397"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+    <A
+HREF="http://config.privoxy.org/toggle"
+TARGET="_top"
+>http://config.privoxy.org/toggle</A
+>
+   </P
+></BLOCKQUOTE
+><P
+>   Short cuts. Turn off, then on: 
+  </P
+><A
+NAME="AEN3401"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+     <A
+HREF="http://config.privoxy.org/toggle?set=disable"
+TARGET="_top"
+>http://config.privoxy.org/toggle?set=disable</A
+>
+   </P
+></BLOCKQUOTE
+><A
+NAME="AEN3404"
+></A
+><BLOCKQUOTE
+CLASS="BLOCKQUOTE"
+><P
+> 
+     <A
+HREF="http://config.privoxy.org/toggle?set=enable"
+TARGET="_top"
+>http://config.privoxy.org/toggle?set=enable</A
+>
+   </P
+></BLOCKQUOTE
+></LI
+></UL
+></P
+><P
+> These may be bookmarked for quick reference. See next.&#13;</P
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="BOOKMARKLETS"
+>14.2.1. Bookmarklets</A
+></H3
+><P
+> Below are some <SPAN
+CLASS="QUOTE"
+>"bookmarklets"</SPAN
+> to allow you to easily access a
+ <SPAN
+CLASS="QUOTE"
+>"mini"</SPAN
+> version of some of <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+>
+ special pages. They are designed for MS Internet Explorer, but should work
+ equally well in Netscape, Mozilla, and other browsers which support
+ JavaScript. They are designed to run directly from your bookmarks - not by
+ clicking the links below (although that should work for testing).</P
+><P
+> To save them, right-click the link and choose <SPAN
+CLASS="QUOTE"
+>"Add to Favorites"</SPAN
+>
+ (IE) or <SPAN
+CLASS="QUOTE"
+>"Add Bookmark"</SPAN
+> (Netscape). You will get a warning that
+ the bookmark <SPAN
+CLASS="QUOTE"
+>"may not be safe"</SPAN
+> - just click OK. Then you can run the
+ Bookmarklet directly from your favorites/bookmarks. For even faster access,
+ you can put them on the <SPAN
+CLASS="QUOTE"
+>"Links"</SPAN
+> bar (IE) or the <SPAN
+CLASS="QUOTE"
+>"Personal
+ Toolbar"</SPAN
+> (Netscape), and run them with a single click. </P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>    <A
+HREF="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&set=enabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>Privoxy - Enable</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>Privoxy - Disable</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&set=toggle','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>Privoxy - Toggle Privoxy</A
+> (Toggles between enabled and disabled)
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y','ijbstatus','width=250,height=2,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>Privoxy- View Status</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions/index.php?url='+escape(location.href),'Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>Privoxy - Submit Actions File Feedback</A
+>
+   </P
+></LI
+><LI
+><P
+>    <A
+HREF="javascript:void(window.open('http://config.privoxy.org/show-url-info?url='+escape(location.href),'Why').focus());"
+TARGET="_top"
+>Privoxy - Why?</A
+>
+   </P
+></LI
+></UL
+></P
+><P
+> Credit: The site which gave us the general idea for these bookmarklets is
+ <A
+HREF="http://www.bookmarklets.com"
+TARGET="_top"
+>www.bookmarklets.com</A
+>. They
+ have more information about bookmarklets. </P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CHAIN"
+>14.3. Chain of Events</A
+></H2
+><P
+> Let's take a quick look at the basic sequence of events when a web page is 
+ requested by your browser and <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is on duty:</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>   First, your web browser requests a web page. The browser knows to send 
+   the request to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, which will in turn, 
+   relay the request to the remote web server after passing the following 
+   tests: 
+  </P
+></LI
+><LI
+><P
+>   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> traps any request for its own internal CGI 
+   pages (e.g http://p.p/) and sends the CGI page back to the browser.
+  </P
+></LI
+><LI
+><P
+>   Next, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> checks to see if the URL 
+   matches any <A
+HREF="actions-file.html#BLOCK"
+><SPAN
+CLASS="QUOTE"
+>"+block"</SPAN
+></A
+> patterns. If
+   so, the URL is then blocked, and the remote web server will not be contacted.
+   <A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+><SPAN
+CLASS="QUOTE"
+>"+handle-as-image"</SPAN
+></A
+> 
+   is then checked and if it does not match, an 
+   HTML <SPAN
+CLASS="QUOTE"
+>"BLOCKED"</SPAN
+> page is sent back. Otherwise, if it does match,
+   an image is returned. The type of image depends on the setting of <A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+><SPAN
+CLASS="QUOTE"
+>"+set-image-blocker"</SPAN
+></A
+>
+   (blank, checkerboard pattern, or an HTTP redirect to an image elsewhere).
+  </P
+></LI
+><LI
+><P
+>   Untrusted URLs are blocked. If URLs are being added to the
+   <TT
+CLASS="FILENAME"
+>trust</TT
+> file, then that is done.
+  </P
+></LI
+><LI
+><P
+>   If the URL pattern matches the <A
+HREF="actions-file.html#FAST-REDIRECTS"
+><SPAN
+CLASS="QUOTE"
+>"+fast-redirects"</SPAN
+></A
+> action,
+   it is then processed. Unwanted parts of the requested URL are stripped.
+  </P
+></LI
+><LI
+><P
+>   Now the rest of the client browser's request headers are processed. If any
+   of these match any of the relevant actions (e.g. <A
+HREF="actions-file.html#HIDE-USER-AGENT"
+><SPAN
+CLASS="QUOTE"
+>"+hide-user-agent"</SPAN
+></A
+>,
+   etc.), headers are suppressed or forged as determined by these actions and
+   their parameters.
+  </P
+></LI
+><LI
+><P
+>   Now the web server starts sending its response back (i.e. typically a web page and related 
+   data).
+  </P
+></LI
+><LI
+><P
+>   First, the server headers are read and processed to determine, among other
+   things, the MIME type (document type) and encoding. The headers are then
+   filtered as deterimed by the 
+   <A
+HREF="actions-file.html#CRUNCH-INCOMING-COOKIES"
+><SPAN
+CLASS="QUOTE"
+>"+crunch-incoming-cookies"</SPAN
+></A
+>,
+   <A
+HREF="actions-file.html#SESSION-COOKIES-ONLY"
+><SPAN
+CLASS="QUOTE"
+>"+session-cookies-only"</SPAN
+></A
+>,
+   and <A
+HREF="actions-file.html#DOWNGRADE-HTTP-VERSION"
+><SPAN
+CLASS="QUOTE"
+>"+downgrade-http-version"</SPAN
+></A
+>
+   actions.
+  </P
+></LI
+><LI
+><P
+>   If the <A
+HREF="actions-file.html#KILL-POPUPS"
+><SPAN
+CLASS="QUOTE"
+>"+kill-popups"</SPAN
+></A
+>
+   action applies, and it is an HTML or JavaScript document, the popup-code in the
+   response is filtered on-the-fly as it is received.
+  </P
+></LI
+><LI
+><P
+>   If a <A
+HREF="actions-file.html#FILTER"
+><SPAN
+CLASS="QUOTE"
+>"+filter"</SPAN
+></A
+>
+   or <A
+HREF="actions-file.html#DEANIMATE-GIFS"
+><SPAN
+CLASS="QUOTE"
+>"+deanimate-gifs"</SPAN
+></A
+>
+   action applies (and the document type fits the action), the rest of the page is
+   read into memory (up to a configurable limit). Then the filter rules (from
+   <TT
+CLASS="FILENAME"
+>default.filter</TT
+>) are processed against the buffered
+   content. Filters are applied in the order they are specified in the
+   <TT
+CLASS="FILENAME"
+>default.filter</TT
+> file. Animated GIFs, if present, are
+   reduced to either the first or last frame, depending on the action
+   setting.The entire page, which is now filtered, is then sent by
+   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> back to your browser. 
+  </P
+><P
+>   If neither <A
+HREF="actions-file.html#FILTER"
+><SPAN
+CLASS="QUOTE"
+>"+filter"</SPAN
+></A
+>
+   or <A
+HREF="actions-file.html#DEANIMATE-GIFS"
+><SPAN
+CLASS="QUOTE"
+>"+deanimate-gifs"</SPAN
+></A
+>
+   matches, then <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> passes the raw data through 
+   to the client browser as it becomes available.
+  </P
+></LI
+><LI
+><P
+>   As the browser receives the now (probably filtered) page content, it 
+   reads and then requests any URLs that may be embedded within the page
+   source, e.g. ad images, stylesheets, JavaScript, other HTML documents (e.g.
+   frames), sounds, etc. For each of these objects, the browser issues a new
+   request. And each such request is in turn processed as above. Note that a
+   complex web page may have many such embedded URLs.
+  </P
+></LI
+></UL
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="ACTIONSANAT"
+>14.4. Anatomy of an Action</A
+></H2
+><P
+> The way <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> applies 
+ <A
+HREF="actions-file.html#ACTIONS"
+>actions</A
+> and <A
+HREF="actions-file.html#FILTER"
+>filters</A
+>
+ to any given URL can be complex, and not always so
+ easy to understand what is happening. And sometimes we need to be able to
+ <I
+CLASS="EMPHASIS"
+>see</I
+> just what <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is
+ doing. Especially, if something <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is doing
+ is causing us a problem inadvertently. It can be a little daunting to look at
+ the actions and filters files themselves, since they tend to be filled with
+ <A
+HREF="appendix.html#REGEX"
+>regular expressions</A
+> whose consequences are not
+ always so obvious. </P
+><P
+> One quick test to see if <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is causing a problem 
+ or not, is to disable it temporarily. This should be the first troubleshooting 
+ step. See <A
+HREF="appendix.html#BOOKMARKLETS"
+>the Bookmarklets</A
+> section on a quick 
+ and easy way to do this (be sure to flush caches afterward!).</P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> also provides the 
+ <A
+HREF="http://config.privoxy.org/show-url-info"
+TARGET="_top"
+>http://config.privoxy.org/show-url-info</A
+>
+ page that can show us very specifically how <SPAN
+CLASS="APPLICATION"
+>actions</SPAN
+>
+ are being applied to any given URL. This is a big help for troubleshooting.</P
+><P
+> First, enter one URL (or partial URL) at the prompt, and then
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will tell us 
+ how the current configuration will handle it. This will not
+ help with filtering effects (i.e. the <A
+HREF="actions-file.html#FILTER"
+><SPAN
+CLASS="QUOTE"
+>"+filter"</SPAN
+></A
+> action) from
+ the <TT
+CLASS="FILENAME"
+>default.filter</TT
+> file since this is handled very
+ differently and not so easy to trap! It also will not tell you about any other
+ URLs that may be embedded within the URL you are testing. For instance, images
+ such as ads are expressed as URLs within the raw page source of HTML pages. So
+ you will only get info for the actual URL that is pasted into the prompt area
+ -- not any sub-URLs. If you want to know about embedded URLs like ads, you
+ will have to dig those out of the HTML source. Use your browser's <SPAN
+CLASS="QUOTE"
+>"View
+ Page Source"</SPAN
+> option for this. Or right click on the ad, and grab the
+ URL.</P
+><P
+> Let's try an example, <A
+HREF="http://google.com"
+TARGET="_top"
+>google.com</A
+>, 
+ and look at it one section at a time:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> Matches for http://google.com:
+
+ In file: default.action <SPAN
+CLASS="GUIBUTTON"
+>[ View ]</SPAN
+> <SPAN
+CLASS="GUIBUTTON"
+>[ Edit ]</SPAN
+>
+
+{-add-header 
+ -block 
+ -crunch-outgoing-cookies 
+ -crunch-incoming-cookies 
+ +deanimate-gifs{last} 
+ -downgrade-http-version 
+ +fast-redirects 
+ -filter{popups} 
+ -filter{fun} 
+ -filter{shockwave-flash} 
+ -filter{crude-parental} 
+ +filter{html-annoyances} 
+ +filter{js-annoyances} 
+ +filter{content-cookies} 
+ +filter{webbugs} 
+ +filter{refresh-tags} 
+ +filter{nimda} 
+ +filter{banners-by-size} 
+ +hide-forwarded-for-headers 
+ +hide-from-header{block} 
+ +hide-referer{forge} 
+ -hide-user-agent 
+ -handle-as-image 
+ -kill-popups 
+ -limit-connect 
+ +prevent-compression 
+ -send-vanilla-wafer 
+ -send-wafer 
+ +session-cookies-only 
+ +set-image-blocker{pattern} }
+/
+
+ { -session-cookies-only }
+ .google.com
+
+ { -fast-redirects }
+ .google.com
+
+In file: user.action <SPAN
+CLASS="GUIBUTTON"
+>[ View ]</SPAN
+> <SPAN
+CLASS="GUIBUTTON"
+>[ Edit ]</SPAN
+>
+(no matches in this file)  </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> This tells us how we have defined our 
+ <A
+HREF="actions-file.html#ACTIONS"
+><SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+></A
+>, and
+ which ones match for our example, <SPAN
+CLASS="QUOTE"
+>"google.com"</SPAN
+>. The first listing
+ is any matches for the <TT
+CLASS="FILENAME"
+>standard.action</TT
+> file. No hits at
+ all here on <SPAN
+CLASS="QUOTE"
+>"standard"</SPAN
+>. Then next is <SPAN
+CLASS="QUOTE"
+>"default"</SPAN
+>, or
+ our <TT
+CLASS="FILENAME"
+>default.action</TT
+> file. The large, multi-line listing,
+ is how the actions are set to match for all URLs, i.e. our default settings.
+ If you look at your <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> file, this would be the section
+ just below the <SPAN
+CLASS="QUOTE"
+>"aliases"</SPAN
+> section near the top. This will apply to
+ all URLs as signified by the single forward slash at the end of the listing
+ -- <SPAN
+CLASS="QUOTE"
+>"/"</SPAN
+>.</P
+><P
+> But we can define additional actions that would be exceptions to these general
+ rules, and then list specific URLs (or patterns) that these exceptions would
+ apply to. Last match wins. Just below this then are two explicit matches for
+ <SPAN
+CLASS="QUOTE"
+>".google.com"</SPAN
+>. The first is negating our previous cookie setting, 
+ which was for <A
+HREF="actions-file.html#SESSION-COOKIES-ONLY"
+><SPAN
+CLASS="QUOTE"
+>"+session-cookies-only"</SPAN
+></A
+>
+ (i.e. not persistent). So we will allow persistent cookies for google. The
+ second turns <I
+CLASS="EMPHASIS"
+>off</I
+> any 
+ <A
+HREF="actions-file.html#FAST-REDIRECTS"
+><SPAN
+CLASS="QUOTE"
+>"+fast-redirects"</SPAN
+></A
+>
+ action, allowing this to take place unmolested. Note that there is a leading
+ dot here -- <SPAN
+CLASS="QUOTE"
+>".google.com"</SPAN
+>. This will match any hosts and
+ sub-domains, in the google.com domain also, such as
+ <SPAN
+CLASS="QUOTE"
+>"www.google.com"</SPAN
+>. So, apparently, we have these two actions
+ defined somewhere in the lower part of our <TT
+CLASS="FILENAME"
+>default.action</TT
+>
+ file, and <SPAN
+CLASS="QUOTE"
+>"google.com"</SPAN
+> is referenced somewhere in these latter
+ sections.</P
+><P
+> Then, for our <TT
+CLASS="FILENAME"
+>user.action</TT
+> file, we again have no hits.</P
+><P
+> And finally we pull it all together in the bottom section and summarize how
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is applying all its <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> 
+ to <SPAN
+CLASS="QUOTE"
+>"google.com"</SPAN
+>:&#13;</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#13; Final results:
+ -add-header 
+ -block 
+ -crunch-outgoing-cookies 
+ -crunch-incoming-cookies 
+ +deanimate-gifs{last} 
+ -downgrade-http-version 
+ -fast-redirects 
+ -filter{popups} 
+ -filter{fun} 
+ -filter{shockwave-flash} 
+ -filter{crude-parental} 
+ +filter{html-annoyances} 
+ +filter{js-annoyances} 
+ +filter{content-cookies} 
+ +filter{webbugs} 
+ +filter{refresh-tags} 
+ +filter{nimda} 
+ +filter{banners-by-size} 
+ +hide-forwarded-for-headers 
+ +hide-from-header{block} 
+ +hide-referer{forge} 
+ -hide-user-agent 
+ -handle-as-image 
+ -kill-popups 
+ -limit-connect 
+ +prevent-compression 
+ -send-vanilla-wafer 
+ -send-wafer
+ -session-cookies-only 
+ +set-image-blocker{pattern} </PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Notice the only difference here to the previous listing, is to 
+ <SPAN
+CLASS="QUOTE"
+>"fast-redirects"</SPAN
+> and <SPAN
+CLASS="QUOTE"
+>"session-cookies-only"</SPAN
+>.</P
+><P
+> Now another example, <SPAN
+CLASS="QUOTE"
+>"ad.doubleclick.net"</SPAN
+>:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#13; { +block +handle-as-image }
+  .ad.doubleclick.net
+
+ { +block +handle-as-image }
+  ad*.
+
+ { +block +handle-as-image }
+  .doubleclick.net</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> We'll just show the interesting part here, the explicit matches. It is 
+ matched three different times. Each as an <SPAN
+CLASS="QUOTE"
+>"+block +handle-as-image"</SPAN
+>,
+ which is the expanded form of one of our aliases that had been defined as: 
+ <SPAN
+CLASS="QUOTE"
+>"+imageblock"</SPAN
+>. (<A
+HREF="actions-file.html#ALIASES"
+><SPAN
+CLASS="QUOTE"
+>"Aliases"</SPAN
+></A
+> are defined in
+ the first section of the actions file and typically used to combine more 
+ than one action.)</P
+><P
+> Any one of these would have done the trick and blocked this as an unwanted 
+ image. This is unnecessarily redundant since the last case effectively 
+ would also cover the first. No point in taking chances with these guys 
+ though ;-) Note that if you want an ad or obnoxious 
+ URL to be invisible, it should be defined as <SPAN
+CLASS="QUOTE"
+>"ad.doubleclick.net"</SPAN
+>
+ is done here -- as both a <A
+HREF="actions-file.html#BLOCK"
+><SPAN
+CLASS="QUOTE"
+>"+block"</SPAN
+></A
+>
+ <I
+CLASS="EMPHASIS"
+>and</I
+> an 
+ <A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+><SPAN
+CLASS="QUOTE"
+>"+handle-as-image"</SPAN
+></A
+>.
+ The custom alias <SPAN
+CLASS="QUOTE"
+>"+imageblock"</SPAN
+> just simplifies the process and make 
+ it more readable.</P
+><P
+> One last example. Let's try <SPAN
+CLASS="QUOTE"
+>"http://www.rhapsodyk.net/adsl/HOWTO/"</SPAN
+>.
+ This one is giving us problems. We are getting a blank page. Hmmm...</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#13; Matches for http://www.rhapsodyk.net/adsl/HOWTO/:
+
+ In file: default.action <SPAN
+CLASS="GUIBUTTON"
+>[ View ]</SPAN
+> <SPAN
+CLASS="GUIBUTTON"
+>[ Edit ]</SPAN
+>
+
+ {-add-header 
+  -block 
+  -crunch-incoming-cookies 
+  -crunch-outgoing-cookies 
+  +deanimate-gifs 
+  -downgrade-http-version 
+  +fast-redirects 
+  +filter{html-annoyances} 
+  +filter{js-annoyances} 
+  +filter{kill-popups} 
+  +filter{webbugs} 
+  +filter{nimda} 
+  +filter{banners-by-size} 
+  +filter{hal} 
+  +filter{fun} 
+  +hide-forwarded-for-headers 
+  +hide-from-header{block} 
+  +hide-referer{forge} 
+  -hide-user-agent 
+  -handle-as-image 
+  +kill-popups 
+  +prevent-compression 
+  -send-vanilla-wafer 
+  -send-wafer 
+  +session-cookies-only 
+  +set-image-blocker{blank} }
+   /
+
+ { +block +handle-as-image }
+  /ads</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Ooops, the <SPAN
+CLASS="QUOTE"
+>"/adsl/"</SPAN
+> is matching <SPAN
+CLASS="QUOTE"
+>"/ads"</SPAN
+>! But 
+ we did not want this at all! Now we see why we get the blank page. We could
+ now add a new action below this that explicitly does <I
+CLASS="EMPHASIS"
+>not</I
+>
+ block (<SPAN
+CLASS="QUOTE"
+>"{-block}"</SPAN
+>) paths with <SPAN
+CLASS="QUOTE"
+>"adsl"</SPAN
+>. There are
+ various ways to handle such exceptions. Example:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#13; { -block }
+  /adsl</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Now the page displays ;-) Be sure to flush your browser's caches when 
+ making such changes. Or, try using <TT
+CLASS="LITERAL"
+>Shift+Reload</TT
+>.</P
+><P
+> But now what about a situation where we get no explicit matches like 
+ we did with:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#13; { +block +handle-as-image }
+ /ads</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> That actually was very telling and pointed us quickly to where the problem
+ was. If you don't get this kind of match, then it means one of the default 
+ rules in the first section is causing the problem. This would require some 
+ guesswork, and maybe a little trial and error to isolate the offending rule.
+ One likely cause would be one of the <SPAN
+CLASS="QUOTE"
+>"{+filter}"</SPAN
+> actions. Try 
+ adding the URL for the site to one of aliases that turn off <SPAN
+CLASS="QUOTE"
+>"+filter"</SPAN
+>:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#13; {shop}
+ .quietpc.com
+ .worldpay.com   # for quietpc.com
+ .jungle.com
+ .scan.co.uk
+ .forbes.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> <SPAN
+CLASS="QUOTE"
+>"{shop}"</SPAN
+> is an <SPAN
+CLASS="QUOTE"
+>"alias"</SPAN
+> that expands to 
+ <SPAN
+CLASS="QUOTE"
+>"{ -filter -session-cookies-only }"</SPAN
+>.
+ Or you could do your own exception to negate filtering:&#13;</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#13; {-filter}
+ .forbes.com</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> This would probably be most appropriately put in <TT
+CLASS="FILENAME"
+>user.action</TT
+>, 
+ for local site exceptions.</P
+><P
+> <SPAN
+CLASS="QUOTE"
+>"{fragile}"</SPAN
+> is an alias that disables most actions. This can be 
+ used as a last resort for problem sites. Remember to flush caches! If this 
+ still does not work, you will have to go through the remaining actions one by
+ one to find which one(s) is causing the problem.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="seealso.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>See Also</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/config.html b/doc/webserver/user-manual/config.html
new file mode 100644 (file)
index 0000000..1e7d197
--- /dev/null
@@ -0,0 +1,2959 @@
+<HTML
+><HEAD
+><TITLE
+>The Main Configuration File</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Privoxy Configuration"
+HREF="configuration.html"><LINK
+REL="NEXT"
+TITLE="Actions Files"
+HREF="actions-file.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="configuration.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="actions-file.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CONFIG"
+>7. The Main Configuration File</A
+></H1
+><P
+> Again, the main configuration file is named <TT
+CLASS="FILENAME"
+>config</TT
+> on
+ Linux/Unix/BSD and OS/2, and <TT
+CLASS="FILENAME"
+>config.txt</TT
+> on Windows.
+ Configuration lines consist of an initial keyword followed by a list of
+ values, all separated by whitespace (any number of spaces or tabs). For
+ example:</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>confdir /etc/privoxy</I
+></P
+>
+ </TT
+> </P
+><P
+> Assigns the value <TT
+CLASS="LITERAL"
+>/etc/privoxy</TT
+> to the option
+ <TT
+CLASS="LITERAL"
+>confdir</TT
+> and thus indicates that the configuration
+ directory is named <SPAN
+CLASS="QUOTE"
+>"/etc/privoxy/"</SPAN
+>.</P
+><P
+> All options in the config file except for <TT
+CLASS="LITERAL"
+>confdir</TT
+> and
+ <TT
+CLASS="LITERAL"
+>logdir</TT
+> are optional. Watch out in the below description
+ for what happens if you leave them unset.</P
+><P
+> The main config file controls all aspects of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s
+ operation that are not location dependent (i.e. they apply universally, no matter
+ where you may be surfing).</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONF-LOG-LOC"
+>7.1. Configuration and Log File Locations</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can (and normally does) use a number of
+ other files for additional configuration, help and logging.
+ This section of the configuration file tells <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ where to find those other files. </P
+><P
+> The user running Privoxy, must have read permission for all 
+ configuration files, and write permission to any files that would 
+ be modified, such as log files.</P
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="CONFDIR"
+>7.1.1. confdir</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>The directory where the other configuration files are located</P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>Path name</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>/etc/privoxy (Unix) <I
+CLASS="EMPHASIS"
+>or</I
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> installation dir (Windows) </P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Mandatory</I
+></P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    No trailing <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="LITERAL"
+>/</TT
+>"</SPAN
+>, please
+   </P
+><P
+>    When development goes modular and multi-user, the blocker, filter, and
+    per-user config will be stored in subdirectories of <SPAN
+CLASS="QUOTE"
+>"confdir"</SPAN
+>.
+    For now, the configuration directory structure is flat, except for 
+    <TT
+CLASS="FILENAME"
+>confdir/templates</TT
+>, where the HTML templates for CGI 
+    output reside (e.g. <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> 404 error page). 
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="LOGDIR"
+>7.1.2. logdir</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    The directory where all logging takes place (i.e. where <TT
+CLASS="FILENAME"
+>logfile</TT
+> and 
+    <TT
+CLASS="FILENAME"
+>jarfile</TT
+> are located) 
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>Path name</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>/var/log/privoxy (Unix) <I
+CLASS="EMPHASIS"
+>or</I
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> installation dir (Windows) </P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Mandatory</I
+></P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    No trailing <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="LITERAL"
+>/</TT
+>"</SPAN
+>, please
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="ACTIONSFILE"
+>7.1.3. actionsfile</A
+></H4
+><A
+NAME="DEFAULT.ACTION"
+></A
+><A
+NAME="STANDARD.ACTION"
+></A
+><A
+NAME="USER.ACTION"
+></A
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    The <A
+HREF="actions-file.html"
+>actions file(s)</A
+> to use
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>File name, relative to <TT
+CLASS="LITERAL"
+>confdir</TT
+>, without the <TT
+CLASS="LITERAL"
+>.action</TT
+> suffix</P
+></DD
+><DT
+>Default values:</DT
+><DD
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>     <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;standard&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Internal&nbsp;purposes,&nbsp;no&nbsp;editing&nbsp;recommended</P
+>
+    </TD
+></TR
+><TR
+><TD
+>     <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;default&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Main&nbsp;actions&nbsp;file</P
+>
+    </TD
+></TR
+><TR
+><TD
+>     <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;user&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;User&nbsp;customizations</P
+>
+    </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    No actions are taken at all. Simple neutral proxying. 
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    Multiple <TT
+CLASS="LITERAL"
+>actionsfile</TT
+> lines are permitted, and are in fact recommended!
+   </P
+><P
+> 
+    The default values include standard.action, which is used for internal
+    purposes and should be loaded, default.action, which is the
+    <SPAN
+CLASS="QUOTE"
+>"main"</SPAN
+> actions file maintained by the developers, and
+    <TT
+CLASS="FILENAME"
+>user.action</TT
+>, where you can make your personal additions.
+   </P
+><P
+> 
+    Actions files are where all the per site and per URL configuration is done for 
+    ad blocking, cookie management, privacy considerations, etc.
+    There is no point in using <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> without at 
+    least one actions file.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="FILTERFILE"
+>7.1.4. filterfile</A
+></H4
+><A
+NAME="DEFAULT.FILTER"
+></A
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    The <A
+HREF="filter-file.html"
+>filter file</A
+> to use
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>File name, relative to <TT
+CLASS="LITERAL"
+>confdir</TT
+></P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>default.filter (Unix) <I
+CLASS="EMPHASIS"
+>or</I
+> default.filter.txt (Windows)</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    No textual content filtering takes place, i.e. all
+    <TT
+CLASS="LITERAL"
+>+<A
+HREF="actions-file.html#FILTER"
+>filter</A
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>}</TT
+>
+    actions in the actions files are turned neutral.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The <A
+HREF="filter-file.html"
+>filter file</A
+> contains content modification
+    rules that use <A
+HREF="appendix.html#REGEX"
+>regular expressions</A
+>. These rules permit
+    powerful changes on the content of Web pages, e.g., you could disable your favorite
+    JavaScript annoyances, re-write the actual displayed text, or just have some
+    fun replacing <SPAN
+CLASS="QUOTE"
+>"Microsoft"</SPAN
+> with <SPAN
+CLASS="QUOTE"
+>"MicroSuck"</SPAN
+> wherever
+    it appears on a Web page.
+   </P
+><P
+>    The
+    <TT
+CLASS="LITERAL"
+>+<A
+HREF="actions-file.html#FILTER"
+>filter</A
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>}</TT
+>
+    actions rely on the relevant filter (<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>)
+    to be defined in the filter file!
+   </P
+><P
+>    A pre-defined filter file called <TT
+CLASS="FILENAME"
+>default.filter</TT
+> that contains
+    a bunch of handy filters for common problems is included in the distribution.
+    See the section on the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+>
+    action for a list.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="LOGFILE"
+>7.1.5. logfile</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    The log file to use
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>File name, relative to <TT
+CLASS="LITERAL"
+>logdir</TT
+></P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>logfile (Unix) <I
+CLASS="EMPHASIS"
+>or</I
+> privoxy.log (Windows)</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    No log file is used, all log messages go to the console (<TT
+CLASS="LITERAL"
+>stderr</TT
+>).
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The windows version will additionally log to the console.
+   </P
+><P
+>    The logfile is where all logging and error messages are written. The level
+    of detail and number of messages are set with the <TT
+CLASS="LITERAL"
+>debug</TT
+>
+    option (see below). The logfile can be useful for tracking down a problem with
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> (e.g., it's not blocking an ad you
+    think it should block) but in most cases you probably will never look at it.
+   </P
+><P
+>    Your logfile will grow indefinitely, and you will probably want to
+    periodically remove it.  On Unix systems, you can do this with a cron job
+    (see <SPAN
+CLASS="QUOTE"
+>"man cron"</SPAN
+>). For Red Hat, a <B
+CLASS="COMMAND"
+>logrotate</B
+> 
+    script has been included.
+   </P
+><P
+>    On SuSE Linux systems, you can place a line like <SPAN
+CLASS="QUOTE"
+>"/var/log/privoxy.*
+    +1024k 644 nobody.nogroup"</SPAN
+> in <TT
+CLASS="FILENAME"
+>/etc/logfiles</TT
+>, with
+    the effect that cron.daily will automatically archive, gzip, and empty the
+    log, when it exceeds 1M size.
+   </P
+><P
+>    Any log files must be writable by whatever user <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+    is being run as (default on UNIX, user id is <SPAN
+CLASS="QUOTE"
+>"privoxy"</SPAN
+>).
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="JARFILE"
+>7.1.6. jarfile</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    The file to store intercepted cookies in
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>File name, relative to <TT
+CLASS="LITERAL"
+>logdir</TT
+></P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>jarfile (Unix) <I
+CLASS="EMPHASIS"
+>or</I
+> privoxy.jar (Windows)</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Intercepted cookies are not stored at all.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The jarfile may grow to ridiculous sizes over time.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="TRUSTFILE"
+>7.1.7. trustfile</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    The trust file to use
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>File name, relative to <TT
+CLASS="LITERAL"
+>confdir</TT
+></P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset (commented out)</I
+>. When activated: trust (Unix) <I
+CLASS="EMPHASIS"
+>or</I
+> trust.txt (Windows)</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    The whole trust mechanism is turned off.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The trust mechanism is an experimental feature for building white-lists and should
+    be used with care. It is <I
+CLASS="EMPHASIS"
+>NOT</I
+> recommended for the casual user.
+   </P
+><P
+>    If you specify a trust file, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will only allow
+    access to sites that are named in the trustfile. 
+    You can also mark sites as trusted referrers (with <TT
+CLASS="LITERAL"
+>+</TT
+>), with
+    the effect that access to untrusted sites will be granted, if a link from a
+    trusted referrer was used.
+    The link target will then be added to the <SPAN
+CLASS="QUOTE"
+>"trustfile"</SPAN
+>.
+    Possible applications include limiting Internet access for children.
+   </P
+><P
+>    If you use <TT
+CLASS="LITERAL"
+>+</TT
+> operator in the trust file, it may grow considerably over time.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="LOCAL-SET-UP"
+>7.2. Local Set-up Documentation</A
+></H2
+><P
+>    If you intend to operate <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> for more users
+    than just yourself, it might be a good idea to let them know how to reach
+    you, what you block and why you do that, your policies, etc.
+   </P
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="USER-MANUAL"
+>7.2.1. user-manual</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Location of the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> User Manual.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>A fully qualified URI</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset</I
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    <A
+HREF="http://www.privoxy.org/user-manual/"
+TARGET="_top"
+>http://www.privoxy.org/<TT
+CLASS="REPLACEABLE"
+><I
+>version</I
+></TT
+>/user-manual/</A
+>
+    will be used, where <TT
+CLASS="REPLACEABLE"
+><I
+>version</I
+></TT
+> is the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> version.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The User Manual URI is used for help links from some of the internal CGI pages. 
+    The manual itself is normally packaged with the binary distributions, so you probably want
+    to set this to a locally installed copy. For multi-user setups, you could provide a copy on
+    a local webserver for all your users and use the corresponding URL here.
+   </P
+><P
+>    Examples:
+   </P
+><P
+>   Unix, in local filesystem:
+  </P
+><P
+>   <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>user-manual  file:///usr/share/doc/privoxy-2.9.15/user-manual/</PRE
+></TD
+></TR
+></TABLE
+>
+  </P
+><P
+>   Any platform, on local webserver (called <SPAN
+CLASS="QUOTE"
+>"local-webserver"</SPAN
+>):
+  </P
+><P
+>   <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>user-manual  http://local-webserver/privoxy-user-manual/</PRE
+></TD
+></TR
+></TABLE
+>
+  </P
+><DIV
+CLASS="WARNING"
+><P
+></P
+><TABLE
+CLASS="WARNING"
+BORDER="1"
+WIDTH="90%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Warning</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>     If set, this option should be <I
+CLASS="EMPHASIS"
+>the first option in the config file</I
+>, because
+     it is used while the config file is being read.
+   </P
+></TD
+></TR
+></TABLE
+></DIV
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="TRUST-INFO-URL"
+>7.2.2. trust-info-url</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    A URL to be displayed in the error page that users will see if access to an untrusted page is denied.    
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>URL</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>Two example URL are provided</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    No links are displayed on the "untrusted" error page.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The value of this option only matters if the experimental trust mechanism has been
+    activated. (See <A
+HREF="config.html#TRUSTFILE"
+><I
+CLASS="EMPHASIS"
+>trustfile</I
+></A
+> above.)
+   </P
+><P
+>    If you use the trust mechanism, it is a good idea to write up some on-line
+    documentation about your trust policy and to specify the URL(s) here.
+    Use multiple times for multiple URLs.
+   </P
+><P
+>    The URL(s) should be added to the trustfile as well, so users don't end up
+    locked out from the information on why they were locked out in the first place!
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="ADMIN-ADDRESS"
+>7.2.3. admin-address</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    An email address to reach the proxy administrator.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>Email address</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset</I
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    No email address is displayed on error pages and the CGI user interface.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    If both <TT
+CLASS="LITERAL"
+>admin-address</TT
+> and <TT
+CLASS="LITERAL"
+>proxy-info-url</TT
+>
+    are unset, the whole "Local Privoxy Support" box on all generated pages will
+    not be shown.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="PROXY-INFO-URL"
+>7.2.4. proxy-info-url</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    A URL to documentation about the local <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> setup,
+    configuration or policies.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>URL</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset</I
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    No link to local documentation is displayed on error pages and the CGI user interface.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    If both <TT
+CLASS="LITERAL"
+>admin-address</TT
+> and <TT
+CLASS="LITERAL"
+>proxy-info-url</TT
+>
+    are unset, the whole "Local Privoxy Support" box on all generated pages will
+    not be shown.
+   </P
+><P
+>    This URL shouldn't be blocked ;-)
+   </P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="DEBUGGING"
+>7.3. Debugging</A
+></H2
+><P
+>  These options are mainly useful when tracing a problem.
+  Note that you might also want to invoke
+  <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with the <TT
+CLASS="LITERAL"
+>--no-daemon</TT
+>
+  command line option when debugging.
+ </P
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="DEBUG"
+>7.3.1. debug</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Key values that determine what information gets logged to the 
+    <A
+HREF="config.html#LOGFILE"
+><I
+CLASS="EMPHASIS"
+>logfile</I
+></A
+>.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>Integer values</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>12289 (i.e.: URLs plus informational and warning messages)</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Nothing gets logged.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    The available debug levels are:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  debug         1 # show each GET/POST/CONNECT request
+  debug         2 # show each connection status
+  debug         4 # show I/O status
+  debug         8 # show header parsing
+  debug        16 # log all data into the logfile
+  debug        32 # debug force feature
+  debug        64 # debug regular expression filter 
+  debug       128 # debug fast redirects
+  debug       256 # debug GIF de-animation
+  debug       512 # Common Log Format
+  debug      1024 # debug kill pop-ups
+  debug      4096 # Startup banner and warnings.
+  debug      8192 # Non-fatal errors</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    To select multiple debug levels, you can either add them or use
+    multiple <TT
+CLASS="LITERAL"
+>debug</TT
+> lines.
+   </P
+><P
+>    A debug level of 1 is informative because it will show you each request
+    as it happens. <I
+CLASS="EMPHASIS"
+>1, 4096 and 8192 are highly recommended</I
+>
+    so that you will notice when things go wrong. The other levels are probably
+    only of interest if you are hunting down a specific problem. They can produce
+    a hell of an output (especially 16).
+    
+   </P
+><P
+>    The reporting of <I
+CLASS="EMPHASIS"
+>fatal</I
+> errors (i.e. ones which crash 
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>) is always on and cannot be disabled.
+   </P
+><P
+>    If you want to use CLF (Common Log Format), you should set <SPAN
+CLASS="QUOTE"
+>"debug
+    512"</SPAN
+> <I
+CLASS="EMPHASIS"
+>ONLY</I
+> and not enable anything else.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="SINGLE-THREADED"
+>7.3.2. single-threaded</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Whether to run only one server thread
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>None</I
+></P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset</I
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Multi-threaded (or, where unavailable: forked) operation, i.e. the ability to
+    serve multiple requests simultaneously.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    This option is only there for debug purposes and you should never
+    need to use it. <I
+CLASS="EMPHASIS"
+>It will drastically reduce performance.</I
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="ACCESS-CONTROL"
+>7.4. Access Control and Security</A
+></H2
+><P
+>  This section of the config file controls the security-relevant aspects
+  of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s configuration.
+ </P
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="LISTEN-ADDRESS"
+>7.4.1. listen-address</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    The IP address and TCP port on which <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will
+    listen for client requests.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>[<TT
+CLASS="REPLACEABLE"
+><I
+>IP-Address</I
+></TT
+>]:<TT
+CLASS="REPLACEABLE"
+><I
+>Port</I
+></TT
+></P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>127.0.0.1:8118</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Bind to 127.0.0.1 (localhost), port 8118. This is suitable and recommended for
+    home users who run <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> on the same machine as
+    their browser.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    You will need to configure your browser(s) to this proxy address and port.
+   </P
+><P
+>    If you already have another service running on port 8118, or if you want to
+    serve requests from other machines (e.g. on your local network) as well, you
+    will need to override the default.
+   </P
+><P
+>    If you leave out the IP address, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will
+    bind to all interfaces (addresses) on your machine and may become reachable
+    from the Internet. In that case, consider using <A
+HREF="config.html#ACLS"
+>access control lists</A
+> (ACL's, see below), and/or
+    a firewall.
+   </P
+><P
+>    If you open <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to untrusted users, you will
+    also want to turn off the <TT
+CLASS="LITERAL"
+><A
+HREF="config.html#ENABLE-EDIT-ACTIONS"
+>enable-edit-actions</A
+></TT
+> and
+    <TT
+CLASS="LITERAL"
+><A
+HREF="config.html#ENABLE-REMOTE-TOGGLE"
+>enable-remote-toggle</A
+></TT
+>
+    options!
+   </P
+></DD
+><DT
+>Example:</DT
+><DD
+><P
+>     Suppose you are running <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> on
+     a machine which has the address 192.168.0.1 on your local private network
+     (192.168.0.0) and has another outside connection with a different address.
+     You want it to serve requests from inside only:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>  listen-address  192.168.0.1:8118</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="TOGGLE"
+>7.4.2. toggle</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Initial state of "toggle" status
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>1 or 0</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>1</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Act as if toggled on
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    If set to 0, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will start in
+    <SPAN
+CLASS="QUOTE"
+>"toggled off"</SPAN
+> mode, i.e. behave like a normal, content-neutral
+    proxy where all ad blocking, filtering, etc are disabled. See
+    <TT
+CLASS="LITERAL"
+>enable-remote-toggle</TT
+> below. This is not really useful
+    anymore, since toggling is much easier via <A
+HREF="http://config.privoxy.org/toggle"
+TARGET="_top"
+>the web interface</A
+> than via
+    editing the <TT
+CLASS="FILENAME"
+>conf</TT
+> file.
+   </P
+><P
+>    The windows version will only display the toggle icon in the system tray
+    if this option is present.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="ENABLE-REMOTE-TOGGLE"
+>7.4.3. enable-remote-toggle</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Whether or not the <A
+HREF="http://config.privoxy.org/toggle"
+TARGET="_top"
+>web-based toggle
+    feature</A
+> may be used
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>0 or 1</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>1</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    The web-based toggle feature is disabled.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    When toggled off, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> acts like a normal,
+    content-neutral proxy, i.e. it acts as if none of the actions applied to
+    any URL.
+   </P
+><P
+>    For the time being, access to the toggle feature can <I
+CLASS="EMPHASIS"
+>not</I
+> be
+    controlled separately by <SPAN
+CLASS="QUOTE"
+>"ACLs"</SPAN
+> or HTTP authentication,
+    so that everybody who can access <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> (see
+    <SPAN
+CLASS="QUOTE"
+>"ACLs"</SPAN
+> and <TT
+CLASS="LITERAL"
+>listen-address</TT
+> above) can
+    toggle it for all users. So this option is <I
+CLASS="EMPHASIS"
+>not recommended</I
+>
+    for multi-user environments with untrusted users.
+   </P
+><P
+>    Note that you must have compiled <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with
+    support for this feature, otherwise this option has no effect. 
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="ENABLE-EDIT-ACTIONS"
+>7.4.4. enable-edit-actions</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Whether or not the <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>web-based actions
+    file editor</A
+> may be used
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>0 or 1</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>1</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    The web-based actions file editor is disabled.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    For the time being, access to the editor can <I
+CLASS="EMPHASIS"
+>not</I
+> be
+    controlled separately by <SPAN
+CLASS="QUOTE"
+>"ACLs"</SPAN
+> or HTTP authentication,
+    so that everybody who can access <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> (see
+    <SPAN
+CLASS="QUOTE"
+>"ACLs"</SPAN
+> and <TT
+CLASS="LITERAL"
+>listen-address</TT
+> above) can
+    modify its configuration for all users. So this option is <I
+CLASS="EMPHASIS"
+>not
+    recommended</I
+> for multi-user environments with untrusted users.
+   </P
+><P
+>    Note that you must have compiled <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with
+    support for this feature, otherwise this option has no effect. 
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="ACLS"
+>7.4.5. ACLs: permit-access and deny-access</A
+></H4
+><A
+NAME="PERMIT-ACCESS"
+></A
+><A
+NAME="DENY-ACCESS"
+></A
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Who can access what.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>    <TT
+CLASS="REPLACEABLE"
+><I
+>src_addr</I
+></TT
+>[/<TT
+CLASS="REPLACEABLE"
+><I
+>src_masklen</I
+></TT
+>]
+    [<TT
+CLASS="REPLACEABLE"
+><I
+>dst_addr</I
+></TT
+>[/<TT
+CLASS="REPLACEABLE"
+><I
+>dst_masklen</I
+></TT
+>]]
+   </P
+><P
+>    Where <TT
+CLASS="REPLACEABLE"
+><I
+>src_addr</I
+></TT
+> and 
+   <TT
+CLASS="REPLACEABLE"
+><I
+>dst_addr</I
+></TT
+> are IP addresses in dotted decimal notation or valid
+    DNS names, and <TT
+CLASS="REPLACEABLE"
+><I
+>src_masklen</I
+></TT
+> and
+    <TT
+CLASS="REPLACEABLE"
+><I
+>dst_masklen</I
+></TT
+> are subnet masks in CIDR notation, i.e. integer
+    values from 2 to 30 representing the length (in bits) of the network address. The masks and the whole
+    destination part are optional.
+   </P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset</I
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Don't restrict access further than implied by <TT
+CLASS="LITERAL"
+>listen-address</TT
+>
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    Access controls are included at the request of ISPs and systems
+    administrators, and <I
+CLASS="EMPHASIS"
+>are not usually needed by individual users</I
+>.
+    For a typical home user, it will normally suffice to ensure that 
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> only listens on the localhost
+    (127.0.0.1) or internal (home) network address by means of the
+    <A
+HREF="config.html#LISTEN-ADDRESS"
+><I
+CLASS="EMPHASIS"
+>listen-address</I
+></A
+>
+    option. 
+   </P
+><P
+>    Please see the warnings in the FAQ that this proxy is not intended to be a substitute
+    for a firewall or to encourage anyone to defer addressing basic security
+    weaknesses.
+   </P
+><P
+>    Multiple ACL lines are OK.
+    If any ACLs are specified, then the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+    talks only to IP addresses that match at least one <TT
+CLASS="LITERAL"
+>permit-access</TT
+> line
+    and don't match any subsequent <TT
+CLASS="LITERAL"
+>deny-access</TT
+> line. In other words, the
+    last match wins, with the default being <TT
+CLASS="LITERAL"
+>deny-access</TT
+>.
+   </P
+><P
+>    If <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is using a forwarder (see <TT
+CLASS="LITERAL"
+>forward</TT
+> below)
+    for a particular destination URL, the <TT
+CLASS="REPLACEABLE"
+><I
+>dst_addr</I
+></TT
+>
+    that is examined is the address of the forwarder and <I
+CLASS="EMPHASIS"
+>NOT</I
+> the address
+    of the ultimate target. This is necessary because it may be impossible for the local
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to determine the IP address of the
+    ultimate target (that's often what gateways are used for).
+   </P
+><P
+>    You should prefer using IP addresses over DNS names, because the address lookups take
+    time. All DNS names must resolve! You can <I
+CLASS="EMPHASIS"
+>not</I
+> use domain patterns
+    like <SPAN
+CLASS="QUOTE"
+>"*.org"</SPAN
+> or partial domain names. If a DNS name resolves to multiple
+    IP addresses, only the first one is used.
+   </P
+><P
+>    Denying access to particular sites by ACL may have undesired side effects
+    if the site in question is hosted on a machine which also hosts other sites.
+   </P
+></DD
+><DT
+>Examples:</DT
+><DD
+><P
+>    Explicitly define the default behavior if no ACL and
+    <TT
+CLASS="LITERAL"
+>listen-address</TT
+> are set: <SPAN
+CLASS="QUOTE"
+>"localhost"</SPAN
+>
+    is OK. The absence of a <TT
+CLASS="REPLACEABLE"
+><I
+>dst_addr</I
+></TT
+> implies that
+    <I
+CLASS="EMPHASIS"
+>all</I
+> destination addresses are OK:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  permit-access  localhost</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    Allow any host on the same class C subnet as www.privoxy.org access to
+    nothing but www.example.com:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  permit-access  www.privoxy.org/24 www.example.com/32</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    Allow access from any host on the 26-bit subnet 192.168.45.64 to anywhere,
+    with the exception that 192.168.45.73 may not access www.dirty-stuff.example.com:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  permit-access  192.168.45.64/26
+  deny-access    192.168.45.73    www.dirty-stuff.example.com</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="BUFFER-LIMIT"
+>7.4.6. buffer-limit</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Maximum size of the buffer for content filtering.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>Size in Kbytes</P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+>4096</P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Use a 4MB (4096 KB) limit.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    For content filtering, i.e. the <TT
+CLASS="LITERAL"
+>+filter</TT
+> and
+    <TT
+CLASS="LITERAL"
+>+deanimate-gif</TT
+> actions, it is necessary that 
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> buffers the entire document body.
+    This can be potentially dangerous, since a server could just keep sending
+    data indefinitely and wait for your RAM to exhaust -- with nasty consequences.
+    Hence this option.
+   </P
+><P
+>    When a document buffer size reaches the <TT
+CLASS="LITERAL"
+>buffer-limit</TT
+>, it is
+    flushed to the client unfiltered and no further attempt to
+    filter the rest of the document is made. Remember that there may be multiple threads
+    running, which might require up to <TT
+CLASS="LITERAL"
+>buffer-limit</TT
+> Kbytes
+    <I
+CLASS="EMPHASIS"
+>each</I
+>, unless you have enabled <SPAN
+CLASS="QUOTE"
+>"single-threaded"</SPAN
+>
+    above.
+   </P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="FORWARDING"
+>7.5. Forwarding</A
+></H2
+><P
+> This feature allows routing of HTTP requests through a chain of
+ multiple proxies.
+ It can be used to better protect privacy and confidentiality when
+ accessing specific domains by routing requests to those domains
+ through an anonymous public proxy (see e.g. <A
+HREF="http://www.multiproxy.org/anon_list.htm"
+TARGET="_top"
+>http://www.multiproxy.org/anon_list.htm</A
+>)
+ Or to use a caching proxy to speed up browsing. Or chaining to a parent
+ proxy may be necessary because the machine that <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ runs on has no direct Internet access.</P
+><P
+> Also specified here are SOCKS proxies. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ supports the SOCKS 4 and SOCKS 4A protocols.</P
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="FORWARD"
+>7.5.1. forward</A
+></H4
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    To which parent HTTP proxy specific requests should be routed.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>    <TT
+CLASS="REPLACEABLE"
+><I
+>target_domain</I
+></TT
+>[:<TT
+CLASS="REPLACEABLE"
+><I
+>port</I
+></TT
+>]
+    <TT
+CLASS="REPLACEABLE"
+><I
+>http_parent</I
+></TT
+>[/<TT
+CLASS="REPLACEABLE"
+><I
+>port</I
+></TT
+>]
+   </P
+><P
+>    Where <TT
+CLASS="REPLACEABLE"
+><I
+>target_domain</I
+></TT
+> is a domain name pattern (see the
+    chapter on domain matching in the <TT
+CLASS="FILENAME"
+>default.action</TT
+> file),
+    <TT
+CLASS="REPLACEABLE"
+><I
+>http_parent</I
+></TT
+> is the address of the parent HTTP proxy
+    as an IP addresses in dotted decimal notation or as a valid DNS name (or <SPAN
+CLASS="QUOTE"
+>"."</SPAN
+> to denote
+    <SPAN
+CLASS="QUOTE"
+>"no forwarding"</SPAN
+>, and the optional 
+    <TT
+CLASS="REPLACEABLE"
+><I
+>port</I
+></TT
+> parameters are TCP ports, i.e. integer
+    values from 1 to 64535
+   </P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset</I
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Don't use parent HTTP proxies.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    If <TT
+CLASS="REPLACEABLE"
+><I
+>http_parent</I
+></TT
+> is <SPAN
+CLASS="QUOTE"
+>"."</SPAN
+>, then requests are not
+    forwarded to another HTTP proxy but are made directly to the web servers.
+   </P
+><P
+>    Multiple lines are OK, they are checked in sequence, and the last match wins.
+   </P
+></DD
+><DT
+>Examples:</DT
+><DD
+><P
+>    Everything goes to an example anonymizing proxy, except SSL on port 443 (which it doesn't handle):
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  forward   .*     anon-proxy.example.org:8080
+  forward   :443   .</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    Everything goes to our example ISP's caching proxy, except for requests
+    to that ISP's sites:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  forward   .*.                caching-proxy.example-isp.net:8000
+  forward   .example-isp.net   .</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="SOCKS"
+>7.5.2. forward-socks4 and forward-socks4a</A
+></H4
+><A
+NAME="FORWARD-SOCKS4"
+></A
+><A
+NAME="FORWARD-SOCKS4A"
+></A
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>Specifies:</DT
+><DD
+><P
+>    Through which SOCKS proxy (and to which parent HTTP proxy) specific requests should be routed.
+   </P
+></DD
+><DT
+>Type of value:</DT
+><DD
+><P
+>    <TT
+CLASS="REPLACEABLE"
+><I
+>target_domain</I
+></TT
+>[:<TT
+CLASS="REPLACEABLE"
+><I
+>port</I
+></TT
+>]
+    <TT
+CLASS="REPLACEABLE"
+><I
+>socks_proxy</I
+></TT
+>[/<TT
+CLASS="REPLACEABLE"
+><I
+>port</I
+></TT
+>]
+    <TT
+CLASS="REPLACEABLE"
+><I
+>http_parent</I
+></TT
+>[/<TT
+CLASS="REPLACEABLE"
+><I
+>port</I
+></TT
+>]
+   </P
+><P
+>    Where <TT
+CLASS="REPLACEABLE"
+><I
+>target_domain</I
+></TT
+> is a domain name pattern (see the
+    chapter on domain matching in the <TT
+CLASS="FILENAME"
+>default.action</TT
+> file),
+    <TT
+CLASS="REPLACEABLE"
+><I
+>http_parent</I
+></TT
+> and <TT
+CLASS="REPLACEABLE"
+><I
+>socks_proxy</I
+></TT
+>
+    are IP addresses in dotted decimal notation or valid DNS names (<TT
+CLASS="REPLACEABLE"
+><I
+>http_parent</I
+></TT
+>
+    may be <SPAN
+CLASS="QUOTE"
+>"."</SPAN
+> to denote <SPAN
+CLASS="QUOTE"
+>"no HTTP forwarding"</SPAN
+>), and the optional 
+    <TT
+CLASS="REPLACEABLE"
+><I
+>port</I
+></TT
+> parameters are TCP ports, i.e. integer values from 1 to 64535
+   </P
+></DD
+><DT
+>Default value:</DT
+><DD
+><P
+><I
+CLASS="EMPHASIS"
+>Unset</I
+></P
+></DD
+><DT
+>Effect if unset:</DT
+><DD
+><P
+>    Don't use SOCKS proxies.
+   </P
+></DD
+><DT
+>Notes:</DT
+><DD
+><P
+>    Multiple lines are OK, they are checked in sequence, and the last match wins.
+   </P
+><P
+>    The difference between <TT
+CLASS="LITERAL"
+>forward-socks4</TT
+> and <TT
+CLASS="LITERAL"
+>forward-socks4a</TT
+>
+    is that in the SOCKS 4A protocol, the DNS resolution of the target hostname happens on the SOCKS
+    server, while in SOCKS 4 it happens locally.
+   </P
+><P
+>    If <TT
+CLASS="REPLACEABLE"
+><I
+>http_parent</I
+></TT
+> is <SPAN
+CLASS="QUOTE"
+>"."</SPAN
+>, then requests are not
+    forwarded to another HTTP proxy but are made (HTTP-wise) directly to the web servers, albeit through
+    a SOCKS proxy.
+   </P
+></DD
+><DT
+>Examples:</DT
+><DD
+><P
+>     From the company example.com, direct connections are made to all
+     <SPAN
+CLASS="QUOTE"
+>"internal"</SPAN
+> domains, but everything outbound goes through
+     their ISP's proxy by way of example.com's corporate SOCKS 4A gateway to
+     the Internet.
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  forward-socks4a   .*.            socks-gw.example.com:1080  www-cache.example-isp.net:8080
+  forward           .example.com   .</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+><P
+>    A rule that uses a SOCKS 4 gateway for all destinations but no HTTP parent looks like this:
+   </P
+><P
+>    <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="90%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  forward-socks4   .*.            socks-gw.example.com:1080  .</PRE
+></TD
+></TR
+></TABLE
+>
+   </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECT3"
+><H4
+CLASS="SECT3"
+><A
+NAME="ADVANCED-FORWARDING-EXAMPLES"
+>7.5.3. Advanced Forwarding Examples</A
+></H4
+><P
+> If you have links to multiple ISPs that provide various special content 
+ only to their subscribers, you can configure multiple <SPAN
+CLASS="APPLICATION"
+>Privoxies</SPAN
+>
+ which have connections to the respective ISPs to act as forwarders to each other, so that
+ <I
+CLASS="EMPHASIS"
+>your</I
+> users can see the internal content of all ISPs.</P
+><P
+> Assume that host-a has a PPP connection to isp-a.net. And host-b has a PPP connection to
+ isp-b.net. Both run <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. Their forwarding
+ configuration can look like this:</P
+><P
+> host-a:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  forward    .*.         .
+  forward    .isp-b.net  host-b:8118</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> host-b:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  forward    .*.         .
+  forward    .isp-a.net  host-a:8118</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Now, your users can set their browser's proxy to use either
+ host-a or host-b and be able to browse the internal content
+ of both isp-a and isp-b.</P
+><P
+> If you intend to chain <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> and 
+ <SPAN
+CLASS="APPLICATION"
+>squid</SPAN
+> locally, then chain as 
+ <TT
+CLASS="LITERAL"
+>browser -&#62; squid -&#62; privoxy</TT
+> is the recommended way. </P
+><P
+> Assuming that <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> and <SPAN
+CLASS="APPLICATION"
+>squid</SPAN
+>
+ run on the same box, your squid configuration could then look like this:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  # Define Privoxy as parent proxy (without ICP) 
+  cache_peer 127.0.0.1 parent 8118 7 no-query 
+
+  # Define ACL for protocol FTP 
+  acl ftp proto FTP 
+
+  # Do not forward FTP requests to Privoxy
+  always_direct allow ftp 
+
+  # Forward all the rest to Privoxy
+  never_direct allow all</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> You would then need to change your browser's proxy settings to <SPAN
+CLASS="APPLICATION"
+>squid</SPAN
+>'s address and port.
+ Squid normally uses port 3128. If unsure consult <TT
+CLASS="LITERAL"
+>http_port</TT
+> in <TT
+CLASS="FILENAME"
+>squid.conf</TT
+>.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="WINDOWS-GUI"
+>7.6. Windows GUI Options</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has a number of options specific to the
+ Windows GUI interface:</P
+><A
+NAME="ACTIVITY-ANIMATION"
+></A
+><P
+> If <SPAN
+CLASS="QUOTE"
+>"activity-animation"</SPAN
+> is set to 1, the
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> icon will animate when
+ <SPAN
+CLASS="QUOTE"
+>"Privoxy"</SPAN
+> is active. To turn off, set to 0.</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>activity-animation   1</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="LOG-MESSAGES"
+></A
+><P
+> If <SPAN
+CLASS="QUOTE"
+>"log-messages"</SPAN
+> is set to 1,
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will log messages to the console
+ window:</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>log-messages       1</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="LOG-BUFFER-SIZE"
+></A
+><P
+> 
+ If <SPAN
+CLASS="QUOTE"
+>"log-buffer-size"</SPAN
+> is set to 1, the size of the log buffer,
+ i.e. the amount of memory used for the log messages displayed in the
+ console window, will be limited to <SPAN
+CLASS="QUOTE"
+>"log-max-lines"</SPAN
+> (see below).</P
+><P
+> Warning: Setting this to 0 will result in the buffer to grow infinitely and
+ eat up all your memory!</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>log-buffer-size      1</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="LOG-MAX-LINES"
+></A
+><P
+> <SPAN
+CLASS="APPLICATION"
+>log-max-lines</SPAN
+> is the maximum number of lines held
+ in the log buffer. See above.</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>log-max-lines      200</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="LOG-HIGHLIGHT-MESSAGES"
+></A
+><P
+> If <SPAN
+CLASS="QUOTE"
+>"log-highlight-messages"</SPAN
+> is set to 1,
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will highlight portions of the log
+ messages with a bold-faced font:</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>log-highlight-messages   1</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="LOG-FONT-NAME"
+></A
+><P
+> The font used in the console window:</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>log-font-name        Comic Sans MS</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="LOG-FONT-SIZE"
+></A
+><P
+> Font size used in the console window:</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>log-font-size        8</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="SHOW-ON-TASK-BAR"
+></A
+><P
+>  
+ <SPAN
+CLASS="QUOTE"
+>"show-on-task-bar"</SPAN
+> controls whether or not
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will appear as a button on the Task bar
+ when minimized:</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>show-on-task-bar     0</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="CLOSE-BUTTON-MINIMIZES"
+></A
+><P
+> If <SPAN
+CLASS="QUOTE"
+>"close-button-minimizes"</SPAN
+> is set to 1, the Windows close
+ button will minimize <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> instead of closing
+ the program (close with the exit option on the File menu).</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;<I
+CLASS="EMPHASIS"
+>close-button-minimizes  1</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+><A
+NAME="HIDE-CONSOLE"
+></A
+><P
+> The <SPAN
+CLASS="QUOTE"
+>"hide-console"</SPAN
+> option is specific to the MS-Win console
+ version of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. If this option is used,
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will disconnect from and hide  the
+ command console.</P
+><P
+> <TT
+CLASS="LITERAL"
+>  <P
+CLASS="LITERALLAYOUT"
+>&nbsp;&nbsp;#<I
+CLASS="EMPHASIS"
+>hide-console</I
+><br>
+&nbsp;&nbsp;&nbsp;</P
+> 
+ </TT
+></P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="configuration.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="actions-file.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Configuration</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Actions Files</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/configuration.html b/doc/webserver/user-manual/configuration.html
new file mode 100644 (file)
index 0000000..e4bbe09
--- /dev/null
@@ -0,0 +1,481 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy Configuration</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Starting Privoxy"
+HREF="startup.html"><LINK
+REL="NEXT"
+TITLE="The Main Configuration File"
+HREF="config.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="startup.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="config.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CONFIGURATION"
+>6. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Configuration</A
+></H1
+><P
+>  All <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> configuration is stored  
+  in text files. These files can be edited with a text editor.
+  Many important aspects of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> can 
+  also be controlled easily with a web browser.
+ </P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN501"
+>6.1. Controlling <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with Your Web Browser</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s user interface can be reached through the special 
+ URL <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>
+ (shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>), 
+ which is a built-in page and works without Internet access.
+ You will see the following section:&#13;</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> <H3
+CLASS="BRIDGEHEAD"
+>Privoxy Menu</H3
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>  Â Â Â Â Â Â Â Â &#9642;  <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>View &#38; change the current configuration</A
+>
+ </TD
+></TR
+><TR
+><TD
+>  Â Â Â Â Â Â Â Â &#9642;  <A
+HREF="http://config.privoxy.org/show-version"
+TARGET="_top"
+>View the source code version numbers</A
+>
+ </TD
+></TR
+><TR
+><TD
+>  Â Â Â Â Â Â Â Â &#9642;  <A
+HREF="http://config.privoxy.org/show-request"
+TARGET="_top"
+>View the request headers.</A
+>
+ </TD
+></TR
+><TR
+><TD
+>  Â Â Â Â Â Â Â Â &#9642;  <A
+HREF="http://config.privoxy.org/show-url-info"
+TARGET="_top"
+>Look up which actions apply to a URL and why</A
+>
+ </TD
+></TR
+><TR
+><TD
+>  Â Â Â Â Â Â Â Â &#9642;  <A
+HREF="http://config.privoxy.org/toggle"
+TARGET="_top"
+>Toggle Privoxy on or off</A
+>
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></PRE
+></TD
+></TR
+></TABLE
+><P
+> This should be self-explanatory. Note the first item leads to an editor for the
+ <A
+HREF="actions-file.html"
+>actions files</A
+>, which is where the ad, banner,
+ cookie, and URL blocking magic is configured as well as other advanced features of
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. This is an easy way to adjust various
+ aspects of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> configuration. The actions
+ file, and other configuration files, are explained in detail below. </P
+><P
+> <SPAN
+CLASS="QUOTE"
+>"Toggle Privoxy On or Off"</SPAN
+> is handy for sites that might 
+ have problems with your current actions and filters. You can in fact use
+ it as a test to see whether it is <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> 
+ causing the problem or not. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> continues 
+ to run as a proxy in this case, but all manipulation is disabled, i.e.
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> acts like a normal forwarding proxy. There
+ is even a toggle <A
+HREF="appendix.html#BOOKMARKLETS"
+>Bookmarklet</A
+> offered, so
+ that you can toggle <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with one click from
+ your browser.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONFOVERVIEW"
+>6.2. Configuration Files Overview</A
+></H2
+><P
+> For Unix, *BSD and Linux, all configuration files are located in
+ <TT
+CLASS="FILENAME"
+>/etc/privoxy/</TT
+> by default. For MS Windows, OS/2, and
+ AmigaOS these are all in the same directory as the 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> executable.  The name
+ and number of configuration files has changed from previous versions, and is
+ subject to change as development progresses.</P
+><P
+> The installed defaults provide a reasonable starting point, though 
+ some settings may be aggressive by some standards. For the time being, the
+ principle configuration files are:</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>     The <A
+HREF="config.html"
+>main configuration file</A
+> is named <TT
+CLASS="FILENAME"
+>config</TT
+>
+     on Linux, Unix, BSD, OS/2, and AmigaOS and <TT
+CLASS="FILENAME"
+>config.txt</TT
+>
+     on Windows. This is a required file.
+   </P
+></LI
+><LI
+><P
+>    <TT
+CLASS="FILENAME"
+>default.action</TT
+> (the main <A
+HREF="actions-file.html"
+>actions file</A
+>)
+    is used to define which <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> relating to banner-blocking, images, pop-ups,
+    content modification, cookie handling etc should be applied by default. It also defines many
+    exceptions (both positive and negative) from this default set of actions that enable 
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to selectively eliminate the junk, and only the junk, on
+    as many websites as possible.
+   </P
+><P
+>    Multiple actions files may be defined in <TT
+CLASS="FILENAME"
+>config</TT
+>. These 
+    are processed in the order they are defined. Local customizations and locally 
+    preferred exceptions to the default policies  as defined in
+    <TT
+CLASS="FILENAME"
+>default.action</TT
+> (which you will most probably want
+    to define sooner or later) are probably best applied in
+    <TT
+CLASS="FILENAME"
+>user.action</TT
+>, where you can preserve them across
+    upgrades. <TT
+CLASS="FILENAME"
+>standard.action</TT
+> is for
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> internal use.
+   </P
+><P
+>    
+    There is also a web based editor that can be accessed from
+    <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>http://config.privoxy.org/show-status</A
+>
+    (Shortcut: <A
+HREF="http://p.p/show-status"
+TARGET="_top"
+>http://p.p/show-status</A
+>) for the
+    various actions files. 
+   </P
+></LI
+><LI
+><P
+>    <TT
+CLASS="FILENAME"
+>default.filter</TT
+> (the <A
+HREF="filter-file.html"
+>filter
+    file</A
+>) can be used to re-write the raw page content, including
+    viewable text as well as embedded HTML and JavaScript, and whatever else
+    lurks on any given web page. The filtering jobs are only pre-defined here;
+    whether to apply them or not is up to the actions files.
+   </P
+></LI
+></UL
+></P
+><P
+> All files use the <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="LITERAL"
+>#</TT
+>"</SPAN
+> character to denote a
+ comment (the rest of the line will be ignored) and understand line continuation
+ through placing a backslash ("<TT
+CLASS="LITERAL"
+>\</TT
+>") as the very last character
+ in a line. If the <TT
+CLASS="LITERAL"
+>#</TT
+> is preceded by a backslash, it looses
+ its special function. Placing a <TT
+CLASS="LITERAL"
+>#</TT
+> in front of an otherwise
+ valid configuration line to prevent it from being interpreted is called "commenting
+ out" that line.</P
+><P
+> The actions files and <TT
+CLASS="FILENAME"
+>default.filter</TT
+> 
+ can use Perl style <A
+HREF="appendix.html#REGEX"
+>regular expressions</A
+> for
+ maximum flexibility. </P
+><P
+> After making any changes, there is no need to restart
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> in order for the changes to take
+ effect. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> detects such changes 
+ automatically. Note, however, that it may take one or two additional
+ requests for the change to take effect. When changing the listening address
+ of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, these <SPAN
+CLASS="QUOTE"
+>"wake up"</SPAN
+> requests
+ must obviously be sent to the <I
+CLASS="EMPHASIS"
+>old</I
+> listening address.</P
+><P
+> While under development, the configuration content is subject to change. 
+ The below documentation may not be accurate by the time you read this. 
+ Also, what constitutes a <SPAN
+CLASS="QUOTE"
+>"default"</SPAN
+> setting, may change, so 
+ please check all your configuration files on important issues.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="startup.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="config.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Starting <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The Main Configuration File</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/contact.html b/doc/webserver/user-manual/contact.html
new file mode 100644 (file)
index 0000000..8e67ad8
--- /dev/null
@@ -0,0 +1,313 @@
+<HTML
+><HEAD
+><TITLE
+>Contacting the Developers, Bug Reporting and Feature
+Requests</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Templates"
+HREF="templates.html"><LINK
+REL="NEXT"
+TITLE="Privoxy Copyright, License and History"
+HREF="copyright.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="templates.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="copyright.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="CONTACT"
+>11. Contacting the Developers, Bug Reporting and Feature
+Requests</A
+></H1
+><P
+> We value your feedback. In fact, we rely on it to improve
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> and its configuration.
+ However, please note the following hints, so we can 
+ provide you with the best support:</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-SUPPORT"
+>11.1. Get Support</A
+></H2
+><P
+> For casual users, our support forum at
+ <A
+HREF="http://sourceforge.net/"
+TARGET="_top"
+>SourceForge</A
+>
+ is probably best suited:
+ <A
+HREF="http://sourceforge.net/tracker/?group_id=11118&atid=211118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?group_id=11118&#38;atid=211118</A
+></P
+><P
+> All users are of course welcome to discuss their issues on the <A
+HREF="http://lists.sourceforge.net/lists/listinfo/ijbswa-users"
+TARGET="_top"
+>users
+ mailing list</A
+>, where the developers also hang around.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-BUGS"
+>11.2. Report Bugs</A
+></H2
+><P
+> Please report all bugs <I
+CLASS="EMPHASIS"
+>only</I
+> through our
+ bug tracker: 
+ <A
+HREF="http://sourceforge.net/tracker/?group_id=11118&atid=111118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?group_id=11118&#38;atid=111118</A
+>. </P
+><P
+>  Before doing so, please make sure that the bug has not already been submitted
+  and observe the aditional hints at the top of the <A
+HREF="http://sourceforge.net/tracker/?func=add&group_id=11118&atid=111118"
+TARGET="_top"
+>submit
+  form</A
+>.</P
+><P
+> 
+  Please try to verify that it is a <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> bug,
+  and not a browser or site bug first. If unsure,
+  try <A
+HREF="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>toggling
+  off</A
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, and see if the problem persists.
+  The <A
+HREF="http://www.privoxy.org/user-manual/appendix.html#ACTIONSANAT"
+TARGET="_top"
+>appendix
+  of the user manual</A
+> also has helpful information 
+  on action debugging. If you are using your own custom configuration, please try
+  the stock configs to see if the problem is configuration related.</P
+><P
+>  If not using the latest version, chances are that the bug has been found
+  and fixed in the meantime. We would appreciate if you could take the time
+  to <A
+HREF="http://www.privoxy.org/user-manual/installation.html"
+TARGET="_top"
+>upgrade
+  to the latest version</A
+> (or  even the latest CVS snapshot) and verify
+  your bug, but this is not required for reporting.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-FEATURE"
+>11.3. Request New Features</A
+></H2
+><P
+> You are welcome to submit ideas on new features or other proposals
+ for improvement through our feature request tracker at
+ <A
+HREF="http://sourceforge.net/tracker/?atid=361118&group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/tracker/?atid=361118&#38;group_id=11118</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-ADS"
+>11.4. Report Ads or Other Actions-Related Problems</A
+></H2
+><P
+> Please send feedback on ads that slipped through, innocent images that were blocked,
+ and any other problems relating to the <TT
+CLASS="FILENAME"
+>default.action</TT
+> file through
+ our actions feedback mechanism located at
+ <A
+HREF="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>http://www.privoxy.org/actions/</A
+>.
+ On this page, you will also find a bookmark which will take you back there from
+ any troubled site and even pre-fill the form!</P
+><P
+> New, improved <TT
+CLASS="FILENAME"
+>default.action</TT
+> files will occasionally be made
+ available based on your feedback. These will be announced on the <A
+HREF="http://lists.sourceforge.net/lists/listinfo/ijbswa-announce"
+TARGET="_top"
+>ijbswa-announce</A
+>
+ list and available from our <A
+HREF="http://sf.net/projects/ijbswa/"
+TARGET="_top"
+>project page</A
+>.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CONTACT-OTHER"
+>11.5. Other</A
+></H2
+><P
+>For any other issues, feel free to use the mailing lists. Technically interested users
+and people who wish to contribute to the project are also welcome on the developers list!
+You can find an overview of all <SPAN
+CLASS="APPLICATION"
+>Prixoxy</SPAN
+>-related mailing lists,
+including list archives, at:
+<A
+HREF="http://sourceforge.net/mail/?group_id=11118"
+TARGET="_top"
+>http://sourceforge.net/mail/?group_id=11118</A
+>.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="templates.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="copyright.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Templates</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Copyright, License and History</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/copyright.html b/doc/webserver/user-manual/copyright.html
new file mode 100644 (file)
index 0000000..81cbf4a
--- /dev/null
@@ -0,0 +1,354 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy Copyright, License and History</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Contacting the Developers, Bug Reporting and Feature
+Requests"
+HREF="contact.html"><LINK
+REL="NEXT"
+TITLE="See Also"
+HREF="seealso.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="contact.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="seealso.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="COPYRIGHT"
+>12. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Copyright, License and History</A
+></H1
+><P
+> Copyright Â© 2001, 2002 by Privoxy Developers <TT
+CLASS="EMAIL"
+>&#60;<A
+HREF="mailto:developers@privoxy.org"
+>developers@privoxy.org</A
+>&#62;</TT
+></P
+><P
+> Some source code is based on code Copyright Â© 1997 by Anonymous Coders
+ and Junkbusters, Inc. and licensed under the <I
+CLASS="CITETITLE"
+>GNU General Public
+ License</I
+>.</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN3103"
+>12.1. License</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is free software; you can
+ redistribute it and/or modify it under the terms of the 
+ <I
+CLASS="CITETITLE"
+>GNU General Public
+ License</I
+>, version 2, as published by the Free Software Foundation.</P
+><P
+> This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ <I
+CLASS="CITETITLE"
+>GNU General Public License</I
+> for
+ more details, which is available from the Free Software Foundation, Inc, 59
+ Temple Place - Suite 330, Boston, MA  02111-1307, USA.</P
+><P
+> You should have received a copy of the <A
+HREF="http://www.gnu.org/copyleft/gpl.html"
+TARGET="_top"
+> <I
+CLASS="CITETITLE"
+>GNU General Public License</I
+></A
+>
+ along with this program; if not, write to the <P
+CLASS="ADDRESS"
+>&nbsp;Free&nbsp;Software<br>
+&nbsp;Foundation,&nbsp;Inc.&nbsp;<SPAN
+CLASS="STREET"
+>59 Temple Place</SPAN
+>&nbsp;-&nbsp;Suite&nbsp;330<br>
+&nbsp;<SPAN
+CLASS="CITY"
+>Boston</SPAN
+>,&nbsp;<SPAN
+CLASS="STATE"
+>MA</SPAN
+>&nbsp;<SPAN
+CLASS="POSTCODE"
+>02111-1307</SPAN
+><br>
+&nbsp;<SPAN
+CLASS="COUNTRY"
+>USA</SPAN
+>&nbsp;</P
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="HISTORY"
+>12.2. History</A
+></H2
+><P
+> In the beginning, there was the
+ <A
+HREF="http://www.junkbusters.com/ijb.html"
+TARGET="_top"
+><SPAN
+CLASS="APPLICATION"
+>Internet Junkbuster</SPAN
+></A
+>, 
+ by Anonymous Coders and <A
+HREF="http://www.junkbusters.com/"
+TARGET="_top"
+>Junkbusters
+ Corporation</A
+>. It saved many users a lot of pain in the early days of
+ web advertising and user tracking.</P
+><P
+> But the web, its protocols and standards, and with it, the techniques for
+ forcing  users to consume ads, give up autonomy over their browsing, and
+ for spying on them, kept evolving. Unfortunately, the <SPAN
+CLASS="APPLICATION"
+>Internet
+ Junkbuster</SPAN
+> did not. Version 2.0.2, published in 1998, was 
+ (and is) the last official
+ <A
+HREF="http://www.junkbusters.com/ijbdist.html#release"
+TARGET="_top"
+>release</A
+>
+ available from <A
+HREF="http://www.junkbusters.com"
+TARGET="_top"
+>Junkbusters Corporation</A
+>.
+ Fortunately, it had been released under the GNU
+ <A
+HREF="http://www.gnu.org/licenses/gpl.html"
+TARGET="_top"
+> GPL</A
+>, which allowed further
+ development by others.</P
+><P
+> So Stefan Waldherr started maintaining an
+ <A
+HREF="http://www.waldherr.org/junkbuster/"
+TARGET="_top"
+>improved version of the
+ software</A
+>, to which eventually a number of people contributed patches.
+ It could already replace banners with a transparent image, and had a first
+ version of pop-up killing, but it was still very closely based on the
+ original, with all its limitations, such as the lack of HTTP/1.1 support,
+ flexible per-site configuration, or content modification. The last release
+ from this effort was version 2.0.2-10, published in 2000.</P
+><P
+> Then, some
+ <A
+HREF="http://www.privoxy.org/user-manual/copyright.html#AUTHORS"
+TARGET="_top"
+>developers</A
+>
+ picked up the thread, and started turning the software inside out, upside down,
+ and then reassembled it, adding many
+ <A
+HREF="http://www.privoxy.org/user-manual/introduction.html#FEATURES"
+TARGET="_top"
+>new
+ features</A
+> along the way.</P
+><P
+> The result of this is <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, whose first
+ stable release, 3.0, is due in May 2002.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AUTHORS"
+>12.3. Authors</A
+></H2
+><P
+> Current Project Developers:</P
+><P
+CLASS="LITERALLAYOUT"
+>&nbsp;Jon&nbsp;Foster<br>
+&nbsp;Andreas&nbsp;Oesterhelt<br>
+&nbsp;Stefan&nbsp;Waldherr<br>
+&nbsp;<br>
+&nbsp;Thomas&nbsp;Steudten<br>
+&nbsp;Rodney&nbsp;Stromlund</P
+><P
+> Current Project Contributors:</P
+><P
+CLASS="LITERALLAYOUT"
+>&nbsp;Rodrigo&nbsp;Barbosa&nbsp;(RPM&nbsp;specfiles)<br>
+&nbsp;Hal&nbsp;Burgiss&nbsp;(docs)<br>
+&nbsp;Alexander&nbsp;Lazic<br>
+&nbsp;Gábor&nbsp;Lipták<br>
+&nbsp;Guy<br>
+&nbsp;Haroon&nbsp;Rafique<br>
+&nbsp;David&nbsp;Schmidt&nbsp;(OS/2,&nbsp;Mac&nbsp;OSX&nbsp;ports)<br>
+&nbsp;Joerg&nbsp;Strohmayer<br>
+&nbsp;Sarantis&nbsp;Paskalis</P
+><P
+> Originally developed by:</P
+><P
+CLASS="LITERALLAYOUT"
+>&nbsp;Junkbusters&nbsp;Corp.<br>
+&nbsp;Anonymous&nbsp;Coders</P
+><P
+> Thanks to the many people who have tested Privoxy, reported bugs, or made
+ suggestions. These include (in alphabetical order):</P
+><P
+CLASS="LITERALLAYOUT"
+>&nbsp;Ken&nbsp;Arromdee<br>
+&nbsp;Reiner&nbsp;Buehl<br>
+&nbsp;Andrew&nbsp;J.&nbsp;Caines<br>
+&nbsp;Clifford&nbsp;Caoile<br>
+&nbsp;Peter&nbsp;E<br>
+&nbsp;Aaron&nbsp;Hamid<br>
+&nbsp;Magnus&nbsp;Holmgren<br>
+&nbsp;Paul&nbsp;Lieverse<br>
+&nbsp;Roberto&nbsp;Ragusa<br>
+&nbsp;Bart&nbsp;Schelstraete<br>
+&nbsp;Darren&nbsp;Wiebe</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="contact.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="seealso.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Contacting the Developers, Bug Reporting and Feature
+Requests</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>See Also</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/filter-file.html b/doc/webserver/user-manual/filter-file.html
new file mode 100644 (file)
index 0000000..64b2c74
--- /dev/null
@@ -0,0 +1,772 @@
+<HTML
+><HEAD
+><TITLE
+>The Filter File</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Actions Files"
+HREF="actions-file.html"><LINK
+REL="NEXT"
+TITLE="Templates"
+HREF="templates.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="actions-file.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="templates.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="FILTER-FILE"
+>9. The Filter File</A
+></H1
+><P
+> All text substitutions that can be invoked through the
+ <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+></TT
+> action
+ must first be defined in the filter file, which is typically
+ called <TT
+CLASS="FILENAME"
+>default.filter</TT
+> and which can be
+ selected through the <TT
+CLASS="LITERAL"
+> <A
+HREF="config.html#FILTERFILE"
+>filterfile</A
+></TT
+> config
+ option.</P
+><P
+> Typical reasons for doing such substitutions are to eliminate
+ common annoyances in HTML and JavaScript, such as pop-up windows,
+ exit consoles, crippled windows without navigation tools, the
+ infamous &#60;BLINK&#62; tag etc, to suppress images with certain
+ width and height attributes (standard banner sizes or web-bugs),
+ or just to have fun. The possibilities are endless.</P
+><P
+> Filtering works on any text-based document type, including plain
+ text, HTML, JavaScript, CSS etc. (all <TT
+CLASS="LITERAL"
+>text/*</TT
+>
+ MIME types). Substitutions are made at the source level, so if
+ you want to <SPAN
+CLASS="QUOTE"
+>"roll your own"</SPAN
+> filters, you should be
+ familiar with HTML syntax.</P
+><P
+> Just like the <A
+HREF="actions-file.html"
+>actions files</A
+>, the
+ filter file is organized in sections, which are called <I
+CLASS="EMPHASIS"
+>filters</I
+>
+ here. Each filter consists of a heading line, that starts with the
+ <I
+CLASS="EMPHASIS"
+>keyword</I
+> <TT
+CLASS="LITERAL"
+>FILTER:</TT
+>, followed by
+ the filter's <I
+CLASS="EMPHASIS"
+>name</I
+>, and a short (one line) 
+ <I
+CLASS="EMPHASIS"
+>description</I
+> of what it does. Below that line
+ come the <I
+CLASS="EMPHASIS"
+>jobs</I
+>, i.e. lines that define the actual
+ text substitutions. By convention, the name of a filter
+ should describe what the filter <I
+CLASS="EMPHASIS"
+>eliminates</I
+>. The
+ comment is used in the <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>web-based
+ user interface</A
+>.</P
+><P
+> Once a filter called <TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+> has been defined
+ in the filter file, it can be invoked by using an action of the form
+ +<TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#FILTER"
+>filter</A
+>{<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>}</TT
+>
+ in any <A
+HREF="actions-file.html"
+>actions file</A
+>.</P
+><P
+> A filter header line for a filter called <SPAN
+CLASS="QUOTE"
+>"foo"</SPAN
+> could look
+ like this:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>FILTER: foo Replace all "foo" with "bar"</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Below that line, and up to the next header line, come the jobs that
+ define what text replacements the filter executes. They are specified
+ in a syntax that imitates <A
+HREF="http://www.perl.org/"
+TARGET="_top"
+>Perl</A
+>'s
+ <TT
+CLASS="LITERAL"
+>s///</TT
+> operator. If you are familiar with Perl, you
+ will find this to be quite intuitive, and may want to look at the
+ <A
+HREF="http://www.oesterhelt.org/pcrs/pcrs.1.html"
+TARGET="_top"
+>PCRS man page</A
+>
+ for the subtle differences to Perl behaviour. Most notably, the non-standard
+ option letter <TT
+CLASS="LITERAL"
+>U</TT
+> is supported, which turns the default
+ to ungreedy matching.</P
+><P
+> If you are new to regular expressions, you might want to take a look at
+ the <A
+HREF="appendix.html#REGEX"
+>Appendix on regular expressions</A
+>, and
+ see the <A
+HREF="http://perldoc.com/perl5.6.1/pod/perl.html"
+TARGET="_top"
+>Perl
+ manual</A
+> for
+ <A
+HREF="http://perldoc.com/perl5.6.1/pod/perlop.html#s-PATTERN-REPLACEMENT-egimosx"
+TARGET="_top"
+>the 
+ <TT
+CLASS="LITERAL"
+>s///</TT
+> operator's syntax</A
+> and <A
+HREF="http://perldoc.com/perl5.6.1/pod/perlre.html"
+TARGET="_top"
+>Perl-style regular
+ expressions</A
+> in general.
+ The below examples might also help to get you started.</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN2909"
+>9.1. Filter File Tutorial</A
+></H2
+><P
+> Now, let's complete our <SPAN
+CLASS="QUOTE"
+>"foo"</SPAN
+> filter. We have already defined
+ the heading, but the jobs are still missing. Since all it does is to replace
+ <SPAN
+CLASS="QUOTE"
+>"foo"</SPAN
+> with <SPAN
+CLASS="QUOTE"
+>"bar"</SPAN
+>, there is only one (trivial) job
+ needed:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>s/foo/bar/</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> But wait! Didn't the comment say that <I
+CLASS="EMPHASIS"
+>all</I
+> occurrences
+ of <SPAN
+CLASS="QUOTE"
+>"foo"</SPAN
+> should be replaced? Our current job will only take
+ care of the first <SPAN
+CLASS="QUOTE"
+>"foo"</SPAN
+> on each page. For global substitution,
+ we'll need to add the <TT
+CLASS="LITERAL"
+>g</TT
+> option:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>s/foo/bar/g</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Our complete filter now looks like this:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>FILTER: foo Replace all "foo" with "bar"
+s/foo/bar/g</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Let's look at some real filters for more interesting examples. Here you see
+ a filter that protects against some common annoyances that arise from JavaScript
+ abuse. Let's look at its jobs one after the other:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>FILTER: js-annoyances Get rid of particularly annoying JavaScript abuse
+
+# Get rid of JavaScript referrer tracking. Test page: http://www.randomoddness.com/untitled.htm
+#
+s|(&#60;script.*)document\.referrer(.*&#60;/script&#62;)|$1"Not Your Business!"$2|Usg</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Following the header line and a comment, you see the job. Note that it uses
+ <TT
+CLASS="LITERAL"
+>|</TT
+> as the delimiter instead of <TT
+CLASS="LITERAL"
+>/</TT
+>, because
+ the pattern contains a forward slash, which would otherwise have to be escaped
+ by a backslash (<TT
+CLASS="LITERAL"
+>\</TT
+>).</P
+><P
+> Now, let's examine the pattern: it starts with the text <TT
+CLASS="LITERAL"
+>&#60;script.*</TT
+>
+ enclosed in parentheses. Since the dot matches any character, and <TT
+CLASS="LITERAL"
+>*</TT
+>
+ means: <SPAN
+CLASS="QUOTE"
+>"Match an arbitrary number of the element left of myself"</SPAN
+>, this
+ matches <SPAN
+CLASS="QUOTE"
+>"&#60;script"</SPAN
+>, followed by <I
+CLASS="EMPHASIS"
+>any</I
+> text, i.e.
+ it matches the whole page, from the start of the first &#60;script&#62; tag.</P
+><P
+> That's more than we want, but the pattern continues: <TT
+CLASS="LITERAL"
+>document\.referrer</TT
+>
+ matches only the exact string <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+>. The dot needed to
+ be <I
+CLASS="EMPHASIS"
+>escaped</I
+>, i.e. preceded by a backslash, to take away its
+ special meaning as a joker, and make it just a regular dot. So far, the meaning is:
+ Match from the start of the first &#60;script&#62; tag in a the page, up to, and including,
+ the text <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+>, if <I
+CLASS="EMPHASIS"
+>both</I
+> are present
+ in the page (and appear in that order).</P
+><P
+> But there's still more pattern to go. The next element, again enclosed in parentheses,
+ is <TT
+CLASS="LITERAL"
+>.*&#60;/script&#62;</TT
+>. You already know what <TT
+CLASS="LITERAL"
+>.*</TT
+>
+ means, so the whole pattern translates to: Match from the start of the first  &#60;script&#62;
+ tag in a page to the end of the last &#60;script&#62; tag, provided that the text
+ <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+> appears somewhere in between.</P
+><P
+> This is still not the whole story, since we have ignored the options and the parentheses:
+ The portions of the page matched by sub-patterns that are enclosed in parentheses, will be
+ remembered and be available through the variables <TT
+CLASS="LITERAL"
+>$1, $2, ...</TT
+> in
+ the substitute. The <TT
+CLASS="LITERAL"
+>U</TT
+> option switches to ungreedy matching, which means
+ that the first <TT
+CLASS="LITERAL"
+>.*</TT
+> in the pattern will only <SPAN
+CLASS="QUOTE"
+>"eat up"</SPAN
+> all
+ text in between <SPAN
+CLASS="QUOTE"
+>"&#60;script"</SPAN
+> and the <I
+CLASS="EMPHASIS"
+>first</I
+> occurrence
+ of <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+>, and that the second <TT
+CLASS="LITERAL"
+>.*</TT
+> will
+ only span the text up to the <I
+CLASS="EMPHASIS"
+>first</I
+> <SPAN
+CLASS="QUOTE"
+>"&#60;/script&#62;"</SPAN
+>
+ tag. Furthermore, the <TT
+CLASS="LITERAL"
+>s</TT
+> option says that the match may span
+ multiple lines in the page, and the <TT
+CLASS="LITERAL"
+>g</TT
+> option again means that the
+ substitution is global.</P
+><P
+> So, to summarize, the pattern means: Match all scripts that contain the text
+ <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+>. Remember the parts of the script from
+ (and including) the start tag up to (and excluding) the string
+ <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+> as <TT
+CLASS="LITERAL"
+>$1</TT
+>, and the part following
+ that string, up to and including the closing tag, as <TT
+CLASS="LITERAL"
+>$2</TT
+>.</P
+><P
+> Now the pattern is deciphered, but wasn't this about substituting things? So
+ lets look at the substitute: <TT
+CLASS="LITERAL"
+>$1"Not Your Business!"$2</TT
+> is
+ easy to read: The text remembered as <TT
+CLASS="LITERAL"
+>$1</TT
+>, followed by 
+ <TT
+CLASS="LITERAL"
+>"Not Your Business!"</TT
+> (<I
+CLASS="EMPHASIS"
+>including</I
+>
+ the quotation marks!), followed by the text remembered as <TT
+CLASS="LITERAL"
+>$2</TT
+>.
+ This produces an exact copy of the original string, with the middle part
+ (the <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+>) replaced by <TT
+CLASS="LITERAL"
+>"Not Your
+ Business!"</TT
+>.</P
+><P
+> The whole job now reads: Replace <SPAN
+CLASS="QUOTE"
+>"document.referrer"</SPAN
+> by
+ <TT
+CLASS="LITERAL"
+>"Not Your Business!"</TT
+> wherever it appears inside a
+ &#60;script&#62; tag. Note that this job won't break JavaScript syntax,
+ since both the original and the replacement are syntactically valid
+ string objects. The script just won't have access to the referrer
+ information anymore.</P
+><P
+> We'll show you two other jobs from the JavaScript taming department, but
+ this time only point out the constructs of special interest:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># The status bar is for displaying link targets, not pointless blahblah
+#
+s/window\.status\s*=\s*['"].*?['"]/dUmMy=1/ig</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> <TT
+CLASS="LITERAL"
+>\s</TT
+> stands for whitespace characters (space, tab, newline,
+ carriage return, form feed), so that <TT
+CLASS="LITERAL"
+>\s*</TT
+> means: <SPAN
+CLASS="QUOTE"
+>"zero
+ or more whitespace"</SPAN
+>. The <TT
+CLASS="LITERAL"
+>?</TT
+> in <TT
+CLASS="LITERAL"
+>.*?</TT
+>
+ makes this matching of arbitrary text ungreedy. (Note that the <TT
+CLASS="LITERAL"
+>U</TT
+>
+ option is not set). The <TT
+CLASS="LITERAL"
+>['"]</TT
+> construct means: <SPAN
+CLASS="QUOTE"
+>"a single
+ <I
+CLASS="EMPHASIS"
+>or</I
+> a double quote"</SPAN
+>.</P
+><P
+> So what does this job do? It replaces assignments of single- or double-quoted
+ strings to the <SPAN
+CLASS="QUOTE"
+>"window.status"</SPAN
+> object with a dummy assignment
+ (using a variable name that is hopefully odd enough not to conflict with
+ real variables in scripts). Thus, it catches many cases where e.g. pointless
+ descriptions are displayed in the status bar instead of the link target when
+ you move your mouse over links.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Kill OnUnload popups. Yummy. Test: http://www.zdnet.com/zdsubs/yahoo/tree/yfs.html
+#
+s/(&#60;body .*)onunload(.*&#62;)/$1never$2/iU</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Including the
+ <A
+HREF="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-eventgroupings-htmlevents"
+TARGET="_top"
+>OnUnload
+ event binding</A
+> in the HTML DOM was a <I
+CLASS="EMPHASIS"
+>CRIME</I
+>.
+ When I close a browser window, I want it to close and die. Basta.
+ This job replaces the <SPAN
+CLASS="QUOTE"
+>"onunload"</SPAN
+> attribute in
+ <SPAN
+CLASS="QUOTE"
+>"&#60;body&#62;"</SPAN
+> tags with the dummy word <TT
+CLASS="LITERAL"
+>never</TT
+>.
+ Note that the <TT
+CLASS="LITERAL"
+>i</TT
+> option makes the pattern matching
+ case-insensitive.</P
+><P
+> The last example is from the fun department:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>FILTER: fun Fun text replacements
+
+# Spice the daily news:
+#
+s/microsoft(?!\.com)/MicroSuck/ig</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> Note the <TT
+CLASS="LITERAL"
+>(?!\.com)</TT
+> part (a so-called negative lookahead)
+ in the job's pattern, which means: Don't match, if the string 
+ <SPAN
+CLASS="QUOTE"
+>".com"</SPAN
+> appears directly following <SPAN
+CLASS="QUOTE"
+>"microsoft"</SPAN
+>
+ in the page. This prevents links to microsoft.com from being messed, while
+ still replacing the word everywhere else.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+># Buzzword Bingo (example for extended regex syntax)
+#
+s* industry[ -]leading \
+|  cutting[ -]edge \
+|  award[ -]winning # Comments are OK, too! \
+|  high[ -]performance \
+|  solutions[ -]based \
+|  unmatched \
+|  unparalleled \
+|  unrivalled \
+*&#60;font color="red"&#62;&#60;b&#62;BINGO!&#60;/b&#62;&#60;/font&#62; \
+*igx</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> The <TT
+CLASS="LITERAL"
+>x</TT
+> option in this job turns on extended syntax, and allows for
+ e.g. the liberal use of (non-interpreted!) whitespace for nicer formatting.</P
+><P
+> You get the idea?</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="actions-file.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="templates.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Actions Files</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Templates</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/index.html b/doc/webserver/user-manual/index.html
new file mode 100644 (file)
index 0000000..ef8d46d
--- /dev/null
@@ -0,0 +1,832 @@
+<HTML
+><HEAD
+><TITLE
+>Privoxy User Manual</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="NEXT"
+TITLE="Introduction"
+HREF="introduction.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="ARTICLE"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="TITLE"
+><A
+NAME="AEN2"
+>Privoxy User Manual</A
+></H1
+><P
+CLASS="PUBDATE"
+> <SUB
+> <A
+HREF="copyright.html"
+>Copyright</A
+> Â© 2001, 2002 by 
+ <A
+HREF="http://www.privoxy.org"
+TARGET="_top"
+>Privoxy Developers</A
+>
+ </SUB
+><BR></P
+><P
+CLASS="PUBDATE"
+>$Id: user-manual.sgml,v 1.121 2002/05/23 23:20:17 oes Exp $<BR></P
+><DIV
+><DIV
+CLASS="ABSTRACT"
+><A
+NAME="AEN9"
+></A
+><P
+></P
+><P
+>  The user manual gives users information on how to install, configure and use
+  <A
+HREF="http://www.privoxy.org/"
+TARGET="_top"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></A
+>.
+ </P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is a web proxy with advanced filtering
+ capabilities for protecting privacy, filtering web page content, managing
+ cookies, controlling access, and removing ads, banners, pop-ups and other
+ obnoxious Internet junk. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has a very
+ flexible configuration and can be customized to suit individual needs and
+ tastes. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> has application for both
+ stand-alone systems and multi-user networks.</P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is based on <SPAN
+CLASS="APPLICATION"
+>Internet
+ Junkbuster</SPAN
+> (tm).</P
+><P
+>  You can find the latest version of the user manual at  <A
+HREF="http://www.privoxy.org/user-manual/"
+TARGET="_top"
+>http://www.privoxy.org/user-manual/</A
+>.
+  Please see the <A
+HREF="contact.html"
+TARGET="_top"
+>Contact section</A
+> on how to
+  contact the developers.
+ </P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="introduction.html"
+>Introduction</A
+></DT
+><DD
+><DL
+><DT
+>1.1. <A
+HREF="introduction.html#FEATURES"
+>Features</A
+></DT
+></DL
+></DD
+><DT
+>2. <A
+HREF="installation.html"
+>Installation</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="installation.html#INSTALLATION-PACKAGES"
+>Binary Packages</A
+></DT
+><DD
+><DL
+><DT
+>2.1.1. <A
+HREF="installation.html#INSTALLATION-PACK-RPM"
+>Red Hat, SuSE RPMs and Conectiva</A
+></DT
+><DT
+>2.1.2. <A
+HREF="installation.html#INSTALLATION-DEB"
+>Debian</A
+></DT
+><DT
+>2.1.3. <A
+HREF="installation.html#INSTALLATION-PACK-WIN"
+>Windows</A
+></DT
+><DT
+>2.1.4. <A
+HREF="installation.html#INSTALLATION-PACK-BINTGZ"
+>Solaris, NetBSD, FreeBSD, HP-UX</A
+></DT
+><DT
+>2.1.5. <A
+HREF="installation.html#INSTALLATION-OS2"
+>OS/2</A
+></DT
+><DT
+>2.1.6. <A
+HREF="installation.html#INSTALLATION-MAC"
+>Max OSX</A
+></DT
+><DT
+>2.1.7. <A
+HREF="installation.html#INSTALLATION-AMIGA"
+>AmigaOS</A
+></DT
+></DL
+></DD
+><DT
+>2.2. <A
+HREF="installation.html#INSTALLATION-SOURCE"
+>Building from Source</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="upgradersnote.html"
+>Note to Upgraders</A
+></DT
+><DT
+>4. <A
+HREF="quickstart.html"
+>Quickstart to Using <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></A
+></DT
+><DD
+><DL
+><DT
+>4.1. <A
+HREF="quickstart.html#QUICKSTART-AD-BLOCKING"
+>Quickstart to Ad Blocking</A
+></DT
+></DL
+></DD
+><DT
+>5. <A
+HREF="startup.html"
+>Starting <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></A
+></DT
+><DD
+><DL
+><DT
+>5.1. <A
+HREF="startup.html#START-REDHAT"
+>RedHat and Conectiva</A
+></DT
+><DT
+>5.2. <A
+HREF="startup.html#START-DEBIAN"
+>Debian</A
+></DT
+><DT
+>5.3. <A
+HREF="startup.html#START-SUSE"
+>SuSE</A
+></DT
+><DT
+>5.4. <A
+HREF="startup.html#START-WINDOWS"
+>Windows</A
+></DT
+><DT
+>5.5. <A
+HREF="startup.html#START-UNICES"
+>Solaris, NetBSD, FreeBSD, HP-UX and others</A
+></DT
+><DT
+>5.6. <A
+HREF="startup.html#START-OS2"
+>OS/2</A
+></DT
+><DT
+>5.7. <A
+HREF="startup.html#START-MACOSX"
+>MAX OSX</A
+></DT
+><DT
+>5.8. <A
+HREF="startup.html#START-AMIGAOS"
+>AmigaOS</A
+></DT
+><DT
+>5.9. <A
+HREF="startup.html#CMDOPTIONS"
+>Command Line Options</A
+></DT
+></DL
+></DD
+><DT
+>6. <A
+HREF="configuration.html"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Configuration</A
+></DT
+><DD
+><DL
+><DT
+>6.1. <A
+HREF="configuration.html#AEN501"
+>Controlling <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> with Your Web Browser</A
+></DT
+><DT
+>6.2. <A
+HREF="configuration.html#CONFOVERVIEW"
+>Configuration Files Overview</A
+></DT
+></DL
+></DD
+><DT
+>7. <A
+HREF="config.html"
+>The Main Configuration File</A
+></DT
+><DD
+><DL
+><DT
+>7.1. <A
+HREF="config.html#CONF-LOG-LOC"
+>Configuration and Log File Locations</A
+></DT
+><DD
+><DL
+><DT
+>7.1.1. <A
+HREF="config.html#CONFDIR"
+>confdir</A
+></DT
+><DT
+>7.1.2. <A
+HREF="config.html#LOGDIR"
+>logdir</A
+></DT
+><DT
+>7.1.3. <A
+HREF="config.html#ACTIONSFILE"
+>actionsfile</A
+></DT
+><DT
+>7.1.4. <A
+HREF="config.html#FILTERFILE"
+>filterfile</A
+></DT
+><DT
+>7.1.5. <A
+HREF="config.html#LOGFILE"
+>logfile</A
+></DT
+><DT
+>7.1.6. <A
+HREF="config.html#JARFILE"
+>jarfile</A
+></DT
+><DT
+>7.1.7. <A
+HREF="config.html#TRUSTFILE"
+>trustfile</A
+></DT
+></DL
+></DD
+><DT
+>7.2. <A
+HREF="config.html#LOCAL-SET-UP"
+>Local Set-up Documentation</A
+></DT
+><DD
+><DL
+><DT
+>7.2.1. <A
+HREF="config.html#USER-MANUAL"
+>user-manual</A
+></DT
+><DT
+>7.2.2. <A
+HREF="config.html#TRUST-INFO-URL"
+>trust-info-url</A
+></DT
+><DT
+>7.2.3. <A
+HREF="config.html#ADMIN-ADDRESS"
+>admin-address</A
+></DT
+><DT
+>7.2.4. <A
+HREF="config.html#PROXY-INFO-URL"
+>proxy-info-url</A
+></DT
+></DL
+></DD
+><DT
+>7.3. <A
+HREF="config.html#DEBUGGING"
+>Debugging</A
+></DT
+><DD
+><DL
+><DT
+>7.3.1. <A
+HREF="config.html#DEBUG"
+>debug</A
+></DT
+><DT
+>7.3.2. <A
+HREF="config.html#SINGLE-THREADED"
+>single-threaded</A
+></DT
+></DL
+></DD
+><DT
+>7.4. <A
+HREF="config.html#ACCESS-CONTROL"
+>Access Control and Security</A
+></DT
+><DD
+><DL
+><DT
+>7.4.1. <A
+HREF="config.html#LISTEN-ADDRESS"
+>listen-address</A
+></DT
+><DT
+>7.4.2. <A
+HREF="config.html#TOGGLE"
+>toggle</A
+></DT
+><DT
+>7.4.3. <A
+HREF="config.html#ENABLE-REMOTE-TOGGLE"
+>enable-remote-toggle</A
+></DT
+><DT
+>7.4.4. <A
+HREF="config.html#ENABLE-EDIT-ACTIONS"
+>enable-edit-actions</A
+></DT
+><DT
+>7.4.5. <A
+HREF="config.html#ACLS"
+>ACLs: permit-access and deny-access</A
+></DT
+><DT
+>7.4.6. <A
+HREF="config.html#BUFFER-LIMIT"
+>buffer-limit</A
+></DT
+></DL
+></DD
+><DT
+>7.5. <A
+HREF="config.html#FORWARDING"
+>Forwarding</A
+></DT
+><DD
+><DL
+><DT
+>7.5.1. <A
+HREF="config.html#FORWARD"
+>forward</A
+></DT
+><DT
+>7.5.2. <A
+HREF="config.html#SOCKS"
+>forward-socks4 and forward-socks4a</A
+></DT
+><DT
+>7.5.3. <A
+HREF="config.html#ADVANCED-FORWARDING-EXAMPLES"
+>Advanced Forwarding Examples</A
+></DT
+></DL
+></DD
+><DT
+>7.6. <A
+HREF="config.html#WINDOWS-GUI"
+>Windows GUI Options</A
+></DT
+></DL
+></DD
+><DT
+>8. <A
+HREF="actions-file.html"
+>Actions Files</A
+></DT
+><DD
+><DL
+><DT
+>8.1. <A
+HREF="actions-file.html#AEN1553"
+>Finding the Right Mix</A
+></DT
+><DT
+>8.2. <A
+HREF="actions-file.html#AEN1560"
+>How to Edit</A
+></DT
+><DT
+>8.3. <A
+HREF="actions-file.html#ACTIONS-APPLY"
+>How Actions are Applied to URLs</A
+></DT
+><DT
+>8.4. <A
+HREF="actions-file.html#AF-PATTERNS"
+>Patterns</A
+></DT
+><DD
+><DL
+><DT
+>22<A
+HREF="actions-file.html#AEN1591"
+></A
+></DT
+><DT
+>8.4.1. <A
+HREF="actions-file.html#AEN1624"
+>The Domain Pattern</A
+></DT
+><DT
+>8.4.2. <A
+HREF="actions-file.html#AEN1686"
+>The Path Pattern</A
+></DT
+></DL
+></DD
+><DT
+>8.5. <A
+HREF="actions-file.html#ACTIONS"
+>Actions</A
+></DT
+><DD
+><DL
+><DT
+>8.5.1. <A
+HREF="actions-file.html#ADD-HEADER"
+>add-header</A
+></DT
+><DT
+>8.5.2. <A
+HREF="actions-file.html#BLOCK"
+>block</A
+></DT
+><DT
+>8.5.3. <A
+HREF="actions-file.html#CRUNCH-INCOMING-COOKIES"
+>crunch-incoming-cookies</A
+></DT
+><DT
+>8.5.4. <A
+HREF="actions-file.html#CRUNCH-OUTGOING-COOKIES"
+>crunch-outgoing-cookies</A
+></DT
+><DT
+>8.5.5. <A
+HREF="actions-file.html#DEANIMATE-GIFS"
+>deanimate-gifs</A
+></DT
+><DT
+>8.5.6. <A
+HREF="actions-file.html#DOWNGRADE-HTTP-VERSION"
+>downgrade-http-version</A
+></DT
+><DT
+>8.5.7. <A
+HREF="actions-file.html#FAST-REDIRECTS"
+>fast-redirects</A
+></DT
+><DT
+>8.5.8. <A
+HREF="actions-file.html#FILTER"
+>filter</A
+></DT
+><DT
+>8.5.9. <A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></DT
+><DT
+>8.5.10. <A
+HREF="actions-file.html#HIDE-FORWARDED-FOR-HEADERS"
+>hide-forwarded-for-headers</A
+></DT
+><DT
+>8.5.11. <A
+HREF="actions-file.html#HIDE-FROM-HEADER"
+>hide-from-header</A
+></DT
+><DT
+>8.5.12. <A
+HREF="actions-file.html#HIDE-REFERRER"
+>hide-referrer</A
+></DT
+><DT
+>8.5.13. <A
+HREF="actions-file.html#HIDE-USER-AGENT"
+>hide-user-agent</A
+></DT
+><DT
+>8.5.14. <A
+HREF="actions-file.html#KILL-POPUPS"
+>kill-popups<A
+NAME="KILL-POPUP"
+></A
+></A
+></DT
+><DT
+>8.5.15. <A
+HREF="actions-file.html#LIMIT-CONNECT"
+>limit-connect</A
+></DT
+><DT
+>8.5.16. <A
+HREF="actions-file.html#PREVENT-COMPRESSION"
+>prevent-compression</A
+></DT
+><DT
+>8.5.17. <A
+HREF="actions-file.html#SEND-VANILLA-WAFER"
+>send-vanilla-wafer</A
+></DT
+><DT
+>8.5.18. <A
+HREF="actions-file.html#SEND-WAFER"
+>send-wafer</A
+></DT
+><DT
+>8.5.19. <A
+HREF="actions-file.html#SESSION-COOKIES-ONLY"
+>session-cookies-only</A
+></DT
+><DT
+>8.5.20. <A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+></DT
+><DT
+>8.5.21. <A
+HREF="actions-file.html#AEN2600"
+>Summary</A
+></DT
+></DL
+></DD
+><DT
+>8.6. <A
+HREF="actions-file.html#ALIASES"
+>Aliases</A
+></DT
+><DT
+>8.7. <A
+HREF="actions-file.html#ACT-EXAMPLES"
+>Actions Files Tutorial</A
+></DT
+><DD
+><DL
+><DT
+>8.7.1. <A
+HREF="actions-file.html#AEN2652"
+>default.action</A
+></DT
+><DT
+>8.7.2. <A
+HREF="actions-file.html#AEN2806"
+>user.action</A
+></DT
+></DL
+></DD
+></DL
+></DD
+><DT
+>9. <A
+HREF="filter-file.html"
+>The Filter File</A
+></DT
+><DD
+><DL
+><DT
+>9.1. <A
+HREF="filter-file.html#AEN2909"
+>Filter File Tutorial</A
+></DT
+></DL
+></DD
+><DT
+>10. <A
+HREF="templates.html"
+>Templates</A
+></DT
+><DT
+>11. <A
+HREF="contact.html"
+>Contacting the Developers, Bug Reporting and Feature
+Requests</A
+></DT
+><DD
+><DL
+><DT
+>11.1. <A
+HREF="contact.html#CONTACT-SUPPORT"
+>Get Support</A
+></DT
+><DT
+>11.2. <A
+HREF="contact.html#CONTACT-BUGS"
+>Report Bugs</A
+></DT
+><DT
+>11.3. <A
+HREF="contact.html#CONTACT-FEATURE"
+>Request New Features</A
+></DT
+><DT
+>11.4. <A
+HREF="contact.html#CONTACT-ADS"
+>Report Ads or Other Actions-Related Problems</A
+></DT
+><DT
+>11.5. <A
+HREF="contact.html#CONTACT-OTHER"
+>Other</A
+></DT
+></DL
+></DD
+><DT
+>12. <A
+HREF="copyright.html"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Copyright, License and History</A
+></DT
+><DD
+><DL
+><DT
+>12.1. <A
+HREF="copyright.html#AEN3103"
+>License</A
+></DT
+><DT
+>12.2. <A
+HREF="copyright.html#HISTORY"
+>History</A
+></DT
+><DT
+>12.3. <A
+HREF="copyright.html#AUTHORS"
+>Authors</A
+></DT
+></DL
+></DD
+><DT
+>13. <A
+HREF="seealso.html"
+>See Also</A
+></DT
+><DT
+>14. <A
+HREF="appendix.html"
+>Appendix</A
+></DT
+><DD
+><DL
+><DT
+>14.1. <A
+HREF="appendix.html#REGEX"
+>Regular Expressions</A
+></DT
+><DT
+>14.2. <A
+HREF="appendix.html#AEN3353"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s Internal Pages</A
+></DT
+><DD
+><DL
+><DT
+>14.2.1. <A
+HREF="appendix.html#BOOKMARKLETS"
+>Bookmarklets</A
+></DT
+></DL
+></DD
+><DT
+>14.3. <A
+HREF="appendix.html#CHAIN"
+>Chain of Events</A
+></DT
+><DT
+>14.4. <A
+HREF="appendix.html#ACTIONSANAT"
+>Anatomy of an Action</A
+></DT
+></DL
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="introduction.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Introduction</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/installation.html b/doc/webserver/user-manual/installation.html
new file mode 100644 (file)
index 0000000..12397cf
--- /dev/null
@@ -0,0 +1,544 @@
+<HTML
+><HEAD
+><TITLE
+>Installation</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Introduction"
+HREF="introduction.html"><LINK
+REL="NEXT"
+TITLE="Note to Upgraders"
+HREF="upgradersnote.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="introduction.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="upgradersnote.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="INSTALLATION"
+>2. Installation</A
+></H1
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is available both in convenient pre-compiled
+ packages for a wide range of operating systems, and as raw source code.
+ For most users, we recommend using the packages, which can be downloaded from our
+ <A
+HREF="http://sourceforge.net/projects/ijbswa/"
+TARGET="_top"
+>Privoxy Project
+ Page</A
+>.</P
+><P
+> Note: If you have a previous <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> or
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> installation on your system, you
+ will need to remove it.  On some platforms, this may be done for you as part
+ of their installation procedure. (See below for your platform). In any case
+ <I
+CLASS="EMPHASIS"
+>be sure to backup your old configuration if it is valuable to
+ you.</I
+> See the <A
+HREF="upgradersnote.html"
+>note to
+ upgraders</A
+> section below.</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="INSTALLATION-PACKAGES"
+>2.1. Binary Packages</A
+></H2
+><P
+>How to install the binary packages depends on your operating system:</P
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="INSTALLATION-PACK-RPM"
+>2.1.1. Red Hat, SuSE RPMs and Conectiva</A
+></H3
+><P
+> RPMs can be installed with <TT
+CLASS="LITERAL"
+>rpm -Uvh privoxy-2.9.15-1.rpm</TT
+>,
+ and will use <TT
+CLASS="FILENAME"
+>/etc/privoxy</TT
+> for the location 
+ of configuration files.</P
+><P
+> Note that on Red Hat, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will
+ <I
+CLASS="EMPHASIS"
+>not</I
+> be automatically started on system boot. You will
+ need to enable that using <B
+CLASS="COMMAND"
+>chkconfig</B
+>,
+ <B
+CLASS="COMMAND"
+>ntsysv</B
+>, or similar methods. Note that SuSE will 
+automatically start Privoxy in the boot process.</P
+><P
+> If you have problems with failed dependencies, try rebuilding the SRC RPM: 
+ <TT
+CLASS="LITERAL"
+>rpm --rebuild privoxy-2.9.15-1.src.rpm;</TT
+>. This 
+ will use your locally installed libraries and RPM version. </P
+><P
+> Also note that if you have a <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> RPM installed
+ on your system, you need to remove it first, because the packages conflict.
+ Otherwise, RPM will try to remove <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+>
+ automatically, before installing <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="INSTALLATION-DEB"
+>2.1.2. Debian</A
+></H3
+><P
+> DEBs can be installed with <TT
+CLASS="LITERAL"
+>dpkg -i
+ privoxy_2.9.15-1.deb</TT
+>, and will use
+ <TT
+CLASS="FILENAME"
+>/etc/privoxy</TT
+> for the location of configuration
+ files.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="INSTALLATION-PACK-WIN"
+>2.1.3. Windows</A
+></H3
+><P
+> Just double-click the installer, which will guide you through
+ the installation process. You will find the configuration files
+ in the same directory as you installed Privoxy in. We do not
+ use the registry of Windows. </P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="INSTALLATION-PACK-BINTGZ"
+>2.1.4. Solaris, NetBSD, FreeBSD, HP-UX</A
+></H3
+><P
+> Create a new directory, <TT
+CLASS="LITERAL"
+>cd</TT
+> to it, then unzip and
+ untar the archive. For the most part, you'll have to figure out where
+ things go. FIXME.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="INSTALLATION-OS2"
+>2.1.5. OS/2</A
+></H3
+><P
+> First, make sure that no previous installations of
+ <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> and / or 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> are left on your
+ system. You can do this by </P
+><P
+> Then, just double-click the WarpIN self-installing archive, which will
+ guide you through the installation process. A shadow of the
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> executable will be placed in your
+ startup folder so it will start automatically whenever OS/2 starts.</P
+><P
+> The directory you choose to install <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ into will contain all of the configuration files.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="INSTALLATION-MAC"
+>2.1.6. Max OSX</A
+></H3
+><P
+> Unzip the downloaded package (you can either double-click on the file
+ in the finder, or on the desktop if you downloaded it there).  Then,
+ double-click on the package installer icon and follow the installation
+ process.
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will be installed in the subdirectory
+ <TT
+CLASS="LITERAL"
+>/Applications/Privoxy.app</TT
+>.
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will set itself up to start 
+ automatically on system bring-up via
+ <TT
+CLASS="LITERAL"
+>/System/Library/StartupItems/Privoxy</TT
+>.</P
+></DIV
+><DIV
+CLASS="SECT3"
+><H3
+CLASS="SECT3"
+><A
+NAME="INSTALLATION-AMIGA"
+>2.1.7. AmigaOS</A
+></H3
+><P
+> Copy and then unpack the <TT
+CLASS="FILENAME"
+>lha</TT
+> archive to a suitable location. 
+ All necessary files will be installed into <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ directory, including all configuration and log files. To uninstall, just 
+ remove this directory.</P
+><P
+> Start <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> (with RUN &#60;&#62;NIL:) in your
+ <TT
+CLASS="FILENAME"
+>startnet</TT
+> script (AmiTCP), in
+ <TT
+CLASS="FILENAME"
+>s:user-startup</TT
+> (RoadShow), as startup program in your
+ startup script (Genesis), or as startup action (Miami and MiamiDx). 
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will automatically quit when you quit your
+ TCP/IP stack (just ignore the harmless warning your TCP/IP stack may display that
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is still running).</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="INSTALLATION-SOURCE"
+>2.2. Building from Source</A
+></H2
+><P
+> The most convenient way to obtain the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> sources
+ is to download the source tarball from our <A
+HREF="http://sf.net/projects/ijbswa/"
+TARGET="_top"
+>project
+ page</A
+>.</P
+><P
+> If you like to live on the bleeding edge and are not afraid of using
+ possibly unstable development versions, you can check out the up-to-the-minute
+ version directly from <A
+HREF="http://sourceforge.net/cvs/?group_id=11118"
+TARGET="_top"
+>the
+ CVS repository</A
+> or simply download <A
+HREF="http://cvs.sourceforge.net/cvstarballs/ijbswa-cvsroot.tar.gz"
+TARGET="_top"
+>the nightly CVS
+ tarball.</A
+></P
+><P
+> To build <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> from source, 
+ <A
+HREF="http://www.gnu.org/software/autoconf/autoconf.html"
+TARGET="_top"
+>autoconf</A
+>,
+ <A
+HREF="http://www.gnu.org/software/make/make.html"
+TARGET="_top"
+>GNU make
+ (gmake)</A
+>, and, of course, a C compiler like <A
+HREF="http://www.gnu.org/software/gcc/gcc.html"
+TARGET="_top"
+>gcc</A
+> are required.</P
+><P
+> When building from a source tarball (either release version or
+ <A
+HREF="http://cvs.sourceforge.net/cvstarballs/ijbswa-cvsroot.tar.gz"
+TARGET="_top"
+>nightly CVS
+ tarball</A
+>), first unpack the source: </P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> tar xzvf privoxy-2.9.15-beta-src* [.tgz or .tar.gz]
+ cd privoxy-2.9.15-beta</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> For retrieving the current CVS sources, you'll need CVS installed.
+ Note that sources from CVS are development quality, and may not be
+ stable, or well tested. To download CVS source:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  cvs -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa login
+  cvs -z3 -d:pserver:anonymous@cvs.ijbswa.sourceforge.net:/cvsroot/ijbswa co current
+  cd current</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> This will create a directory named <TT
+CLASS="FILENAME"
+>current/</TT
+>, which will 
+ contain the source tree.</P
+><P
+> Then, in either case, to build from unpacked tarball or CVS source:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> autoheader
+ autoconf
+ ./configure      # (--help to see options)
+ make             # (the make from gnu, gmake for *BSD) 
+ su 
+ make -n install  # (to see where all the files will go)
+ make install     # (to really install)</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>  If you have gnu make, you can have the first four steps 
+  automatically done for you by just typing:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>  make</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+>  in the freshly downloaded or unpacked source directory.</P
+><P
+> For more detailed instructions on how to build Redhat and SuSE RPMs,
+ Windows self-extracting installers, building on platforms with
+ special requirements etc, please consult the <A
+HREF="../developer-manual/newrelease.html"
+TARGET="_top"
+>developer manual</A
+>.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="introduction.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="upgradersnote.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Introduction</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Note to Upgraders</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/introduction.html b/doc/webserver/user-manual/introduction.html
new file mode 100644 (file)
index 0000000..536b4f4
--- /dev/null
@@ -0,0 +1,270 @@
+<HTML
+><HEAD
+><TITLE
+>Introduction</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="NEXT"
+TITLE="Installation"
+HREF="installation.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="index.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="installation.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="INTRODUCTION"
+>1. Introduction</A
+></H1
+><P
+> This documentation is included with the current beta version of
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, v.2.9.15, 
+ and is mostly complete at this point. The most up to date reference for the
+ time being is still the comments in the source files and in the individual
+ configuration files. Development of version 3.0 is currently nearing
+ completion, and includes many significant changes and enhancements over
+ earlier versions. The target release date for
+ stable v3.0 is <SPAN
+CLASS="QUOTE"
+>"soon"</SPAN
+> ;-).</P
+><P
+> Since this is a beta version, not all new features are well tested. This
+ documentation may be slightly out of sync as a result (especially with 
+ CVS sources). And there <I
+CLASS="EMPHASIS"
+>may be</I
+> bugs, though hopefully
+ not many! </P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="FEATURES"
+>1.1. Features</A
+></H2
+><P
+> In addition to <SPAN
+CLASS="APPLICATION"
+>Internet Junkbuster's</SPAN
+> traditional
+ features of ad and banner blocking and cookie management,
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> provides new features,
+ some of them currently under development:</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>   Integrated browser based configuration and control utility at <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>
+   (shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>). Browser-based
+   tracing of rule and filter effects. Remote toggling.
+  </P
+></LI
+><LI
+><P
+>   Web page content filtering (removes banners based on size,
+   invisible <SPAN
+CLASS="QUOTE"
+>"web-bugs"</SPAN
+>, JavaScript and HTML annoyances, pop-up windows, etc.)
+  </P
+></LI
+><LI
+><P
+>   Modularized configuration that allows for standard settings and
+   user settings to reside in separate files, so that installing updated
+   actions files won't overwrite individual user settings.
+  </P
+></LI
+><LI
+><P
+>   HTTP/1.1 compliant (but not all optional 1.1 features are supported).
+  </P
+></LI
+><LI
+><P
+>   Support for Perl Compatible Regular Expressions in the configuration files, and 
+   generally a more sophisticated and flexible configuration syntax over
+   previous versions.
+  </P
+></LI
+><LI
+><P
+>   Improved cookie management features (e.g. session based cookies).
+  </P
+></LI
+><LI
+><P
+>   GIF de-animation. 
+  </P
+></LI
+><LI
+><P
+>   Bypass many click-tracking scripts (avoids script redirection).
+  </P
+></LI
+><LI
+><P
+>   Multi-threaded (POSIX and native threads).
+  </P
+></LI
+><LI
+><P
+>   User-customizable HTML templates for all proxy-generated pages (e.g. "blocked" page).
+  </P
+></LI
+><LI
+><P
+>   Auto-detection and re-reading of config file changes.
+  </P
+></LI
+><LI
+><P
+>   Improved signal handling, and a true daemon mode (Unix).
+  </P
+></LI
+><LI
+><P
+>   Every feature now controllable on a per-site or per-location basis, configuration
+   more powerful and versatile over-all.
+  </P
+></LI
+><LI
+><P
+>   Many smaller new features added, limitations and bugs removed, and security holes fixed.
+  </P
+></LI
+></UL
+></P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="index.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="installation.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Privoxy User Manual</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Installation</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/quickstart.html b/doc/webserver/user-manual/quickstart.html
new file mode 100644 (file)
index 0000000..cf3eebe
--- /dev/null
@@ -0,0 +1,807 @@
+<HTML
+><HEAD
+><TITLE
+>Quickstart to Using Privoxy</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Note to Upgraders"
+HREF="upgradersnote.html"><LINK
+REL="NEXT"
+TITLE="Starting Privoxy"
+HREF="startup.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="upgradersnote.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="startup.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="QUICKSTART"
+>4. Quickstart to Using <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></A
+></H1
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>   If upgrading, from versions before 2.9.16, please back up any configuration
+   files. See the <A
+HREF="upgradersnote.html"
+>Note to Upgraders</A
+> Section.
+ </P
+></LI
+><LI
+><P
+>  Install <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. See the <A
+HREF="installation.html"
+>Installation Section</A
+> below for platform specific
+  information. 
+ </P
+></LI
+><LI
+><P
+>   Advanced users and those who want to offer <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+   service to more than just their local machine should check the <A
+HREF="config.html"
+>main config file</A
+>, especially the <A
+HREF="config.html#ACCESS-CONTROL"
+>security-relevant</A
+> options. These are 
+   off by default.
+  </P
+></LI
+><LI
+><P
+>  Start <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>, if the installation program has
+  not done this already (may vary according to platform). See the section
+  <A
+HREF="startup.html"
+>Starting <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></A
+>.
+  </P
+></LI
+><LI
+><P
+>   Set your browser to use <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> as HTTP and
+   HTTPS proxy by setting the proxy configuration for address of
+   <TT
+CLASS="LITERAL"
+>127.0.0.1</TT
+> and port <TT
+CLASS="LITERAL"
+>8118</TT
+>.
+   (<SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> and earlier versions of
+   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> used port 8000.) See the section <A
+HREF="startup.html"
+>Starting <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></A
+> below
+   for more details on this.
+  </P
+></LI
+><LI
+><P
+>    Flush your browser's disk and memory caches, to remove any cached ad images.
+  </P
+></LI
+><LI
+><P
+>   A default installation should provide a reasonable starting point for 
+   most. There will undoubtedly be occasions where you will want to adjust the
+   configuration, but that can be dealt with as the need arises. Little 
+   to no initial configuration is required in most cases.
+  </P
+><P
+>   See the <A
+HREF="configuration.html"
+>Configuration section</A
+> for more
+   configuration options, and how to customize your installation.
+  </P
+></LI
+><LI
+><P
+>    If you experience ads that slipped through, innocent images that are
+    blocked, or otherwise feel the need to fine-tune
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> behaviour, take a look at the <A
+HREF="actions-file.html"
+>actions files</A
+>. As a quick start, you might
+    find the <A
+HREF="actions-file.html#ACT-EXAMPLES"
+>richly commented examples</A
+>
+    helpful. You can also view and edit the actions files through the <A
+HREF="http://config.privoxy.org"
+TARGET="_top"
+>web-based user interface</A
+>. The
+    Appendix <SPAN
+CLASS="QUOTE"
+>"<A
+HREF="appendix.html#ACTIONSANAT"
+>Anatomy of an
+    Action</A
+>"</SPAN
+> has hints how to debug actions that
+    <SPAN
+CLASS="QUOTE"
+>"misbehave"</SPAN
+>.
+  </P
+></LI
+><LI
+><P
+>   Please see the section <A
+HREF="contact.html"
+>Contacting the
+   Developers</A
+> on how to report bugs or problems with websites or to get
+   help. 
+  </P
+></LI
+><LI
+><P
+>   Now enjoy surfing with enhanced comfort and privacy!
+  </P
+></LI
+></UL
+></P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="QUICKSTART-AD-BLOCKING"
+>4.1. Quickstart to Ad Blocking</A
+></H2
+><P
+> Ad blocking is but one of <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+>
+ array of features. Many of these features are for the technically minded advanced 
+ user. But, ad and banner blocking is surely common ground for everybody.</P
+><P
+> 
+ This section will provide a quick summary of ad blocking so 
+ you can get up to speed quickly without having to read the more extensive
+ information provided below, though this is highly recommeneded.</P
+><P
+> First a bit of a warning ... blocking ads is much like blocking SPAM: the
+ more aggressive you are about it, the more likely you are to block 
+ things that were not intended. So there is a trade off here. If you want
+ extreme ad free browsing, be prepared to deal with more
+ <SPAN
+CLASS="QUOTE"
+>"problem"</SPAN
+> sites, and to spend more time adjusting the
+ configuration to solve these unintended consequences. In short, there is 
+ not an easy way to eliminate <I
+CLASS="EMPHASIS"
+>all</I
+> ads. Either take 
+ the easy way and settle for <I
+CLASS="EMPHASIS"
+>most</I
+> ads blocked with the
+ default configuration, or jump in and tweak it for your personal surfing
+ habits and preferences.</P
+><P
+> Secondly, a brief explanation of <SPAN
+CLASS="APPLICATION"
+>Privoxy's </SPAN
+>
+ <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+>. <SPAN
+CLASS="QUOTE"
+>"Actions"</SPAN
+> in this context, are 
+ the directives we use to tell <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to perform
+ some task relating to HTTP transactions (i.e. web browsing). We tell
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to take some <SPAN
+CLASS="QUOTE"
+>"action"</SPAN
+>. Each
+ action has a unique name and function. While there are many potential
+ <SPAN
+CLASS="APPLICATION"
+>actions</SPAN
+> in <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+>
+ arsenal, only a few are used for ad blocking. <A
+HREF="actions-file.html#ACTIONS"
+>Actions</A
+>, and <A
+HREF="actions-file.html"
+>action
+ configuration files</A
+>, are explained in depth below.</P
+><P
+> Actions are specified in <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> configuration,
+ followed by one or more URLs to which the action should apply. URLs 
+ can actually be URL type <A
+HREF="actions-file.html#AF-PATTERNS"
+>patterns</A
+> that use
+ wildcards so they can apply potentially to a range of similar URLs. The
+ actions, together with the URL patterns are called a section.</P
+><P
+> When you connect to a website, the full URL will either match one or more
+ of the sections as defined in <SPAN
+CLASS="APPLICATION"
+>Privoxy's</SPAN
+> configuration,
+ or not. If so, then <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will perform the
+ respective actions. If not, then nothing special happens. Futhermore, web
+ pages may contain embedded, secondary URLs that your web browser will
+ use to load additional components of the page, as it parses the
+ original page's HTML content. An ad image for instance, is just a URL
+ embedded in the page somewhere. The image itself may be on the same server,
+ or a server somewhere else on the Internet. Complex web pages will have many
+ such embedded URLs.</P
+><P
+> The actions we need to know about for ad blocking are:  <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+>, <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+>, and
+ <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+></TT
+>:</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>   <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> - this action stops
+   any contact between your browser and any URL patterns that match this
+   action's configuration. It can be used for blocking ads, but also anything
+   that is determined to be unwanted. By itself, it simply stops any
+   communication with the remote server and sends <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s
+   own built-in BLOCKED page instead to let you now what has happened.
+  </P
+></LI
+><LI
+><P
+>   <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+> - 
+   tells <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> to treat this URL as an image.
+   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>'s default configuration already does this
+   for all common image types (e.g. GIF), but there are many situations where this
+   is not as easy to determine. So we'll force it in these cases. This is particularly
+   important for ad blocking, since  only if we know that it's an image, we can replace
+   it by an image instead of the BLOCKED page, which would only result in a
+   <SPAN
+CLASS="QUOTE"
+>"broken image"</SPAN
+> icon. There are some limitations to this though. For
+   instance, you can't just brute-force an image substituion for an entire HTML page
+   in most situations.
+  </P
+></LI
+><LI
+><P
+>   <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#SET-IMAGE-BLOCKER"
+>set-image-blocker</A
+></TT
+> - tells
+   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> what to display in place of an ad image that
+   has hit a block rule. For this to come into play, the URL must match a
+   <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> action somewhere in the
+   configuration, <I
+CLASS="EMPHASIS"
+>and</I
+>, it must also match an
+   <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#HANDLE-AS-IMAGE"
+>handle-as-image</A
+></TT
+> action.
+  </P
+><P
+>   The configuration options on what to display instead of the ad are:
+  </P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>    Â Â Â <I
+CLASS="EMPHASIS"
+>pattern</I
+> - a checkboard pattern, so that an ad 
+    replacement is obvious. This is the default.
+   </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>    Â Â Â <I
+CLASS="EMPHASIS"
+>blank</I
+> - A very small empty GIF image is displayed.
+    This is the so-called <SPAN
+CLASS="QUOTE"
+>"invisible"</SPAN
+> configuration option.
+   </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+><P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>    Â Â Â <I
+CLASS="EMPHASIS"
+>http://&#60;URL&#62;</I
+> - A redirect to any image anywhere
+    of the user's choosing (advanced usage).
+   </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></LI
+></UL
+></P
+><P
+> The quickest way to adjust any of these settings is with your browser through
+ the special <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> editor at <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>http://config.privoxy.org/show-status</A
+>
+ (shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/show-status</A
+>). This 
+ is an internal page, and does not require Internet access. Select the
+ appropriate <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+> file, and click
+ <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIBUTTON"
+>Edit</SPAN
+>"</SPAN
+>. It is best to put personal or
+ local preferences in <TT
+CLASS="FILENAME"
+>user.action</TT
+> since this is not
+ meant to be overwritten during upgrades, and will over-ride the settings in
+ other files. Here you can insert new <SPAN
+CLASS="QUOTE"
+>"actions"</SPAN
+>, and URLs for ad
+ blocking or other purposes, and make other adjustments to the configuration.
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will detect these changes automatically.</P
+><P
+> A quick and simple step by step example:</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>     Right click on the ad image to be blocked, then select 
+     <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIMENUITEM"
+>Copy Link Location</SPAN
+>"</SPAN
+> from the
+     pop-up menu. 
+   </P
+></LI
+><LI
+><P
+>    Set your browser to 
+    <A
+HREF="http://config.privoxy.org/show-status"
+TARGET="_top"
+>http://config.privoxy.org/show-status</A
+>
+   </P
+></LI
+><LI
+><P
+>    Find <TT
+CLASS="FILENAME"
+>user.action</TT
+> in the top section, and click 
+    on <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIBUTTON"
+>Edit</SPAN
+>"</SPAN
+>:
+   </P
+><P
+>  <DIV
+CLASS="FIGURE"
+><A
+NAME="AEN356"
+></A
+><P
+><B
+>Figure 1. Actions Files in Use</B
+></P
+><DIV
+CLASS="MEDIAOBJECT"
+><P
+><IMG
+SRC="../images/files-in-use.jpg"
+ALT="Screenshot of Files in Use"
+></IMG
+></P
+></DIV
+></DIV
+>
+ </P
+></LI
+><LI
+><P
+>   You should have a section with only
+   <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> listed under 
+   <SPAN
+CLASS="QUOTE"
+>"Actions:"</SPAN
+>.
+   If not, click a <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIBUTTON"
+>Insert new section below</SPAN
+>"</SPAN
+>
+   button, and in the new section that just appeared, click the 
+   <SPAN
+CLASS="GUIBUTTON"
+>Edit</SPAN
+> button right under the word <SPAN
+CLASS="QUOTE"
+>"Actions:"</SPAN
+>.
+   This will bring up a list of all actions. Find
+   <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> near the top, and click
+   in the <SPAN
+CLASS="QUOTE"
+>"Enabled"</SPAN
+> column, then <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIBUTTON"
+>Submit</SPAN
+>"</SPAN
+>
+   just below the list.
+  </P
+></LI
+><LI
+><P
+>   Now, in the <TT
+CLASS="LITERAL"
+><A
+HREF="actions-file.html#BLOCK"
+>block</A
+></TT
+> actions section,
+   click the <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIBUTTON"
+>Add</SPAN
+>"</SPAN
+> button, and paste the URL the
+   browser got from <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIMENUITEM"
+>Copy Link Location</SPAN
+>"</SPAN
+>.
+   Remove the <TT
+CLASS="LITERAL"
+>http://</TT
+> at the beginning of the URL. Then, click
+   <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIBUTTON"
+>Submit</SPAN
+>"</SPAN
+> (or
+   <SPAN
+CLASS="QUOTE"
+>"<SPAN
+CLASS="GUIBUTTON"
+>OK</SPAN
+>"</SPAN
+> if in a pop-up window).
+  </P
+></LI
+><LI
+><P
+>   Now go back to the original page, and press <B
+CLASS="KEYCAP"
+>SHIFT-Reload</B
+>
+   (or flush all browser caches). The image should be gone now.
+  </P
+></LI
+></UL
+></P
+><P
+> This is a very crude and simple example. There might be good reasons to use a 
+ wildcard pattern match to include potentially similar images from the same
+ site. For a more extensive explanation of <SPAN
+CLASS="QUOTE"
+>"patterns"</SPAN
+>, and 
+ the entire actions concept, see <A
+HREF="actions-file.html"
+>the Actions
+ section</A
+>.</P
+><P
+> For advanced users who want to hand edit their config files, you might want
+ to now go to the <A
+HREF="actions-file.html#ACT-EXAMPLES"
+>Actions Files Tutorial</A
+>.
+ The ideas explained thererin also apply to the web-based editor.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="upgradersnote.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="startup.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Note to Upgraders</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Starting <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/seealso.html b/doc/webserver/user-manual/seealso.html
new file mode 100644 (file)
index 0000000..a1fe352
--- /dev/null
@@ -0,0 +1,396 @@
+<HTML
+><HEAD
+><TITLE
+>See Also</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Privoxy Copyright, License and History"
+HREF="copyright.html"><LINK
+REL="NEXT"
+TITLE="Appendix"
+HREF="appendix.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="copyright.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="appendix.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="SEEALSO"
+>13. See Also</A
+></H1
+><P
+> Other references and sites of interest to <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ users:</P
+><P
+> <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/"
+TARGET="_top"
+>http://www.privoxy.org/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Home page. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/faq/"
+TARGET="_top"
+>http://www.privoxy.org/faq/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> FAQ. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://sourceforge.net/projects/ijbswa/"
+TARGET="_top"
+>http://sourceforge.net/projects/ijbswa/</A
+>, 
+   the Project Page for <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> on 
+   <A
+HREF="http://sourceforge.net"
+TARGET="_top"
+>SourceForge</A
+>.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>,
+   the web-based user interface. <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> must be
+   running for this to work. Shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());"
+TARGET="_top"
+>http://www.privoxy.org/actions/</A
+>, to submit <SPAN
+CLASS="QUOTE"
+>"misses"</SPAN
+> to the developers. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.junkbusters.com/ht/en/cookies.html"
+TARGET="_top"
+>http://www.junkbusters.com/ht/en/cookies.html</A
+>,
+   an explanation how cookies are used to track web users.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.junkbusters.com/ijb.html"
+TARGET="_top"
+>http://www.junkbusters.com/ijb.html</A
+>,
+   the original Internet Junkbuster.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.waldherr.org/junkbuster/"
+TARGET="_top"
+>http://www.waldherr.org/junkbuster/</A
+>,
+   Stefan Waldherr's version of Junkbuster, from which <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> was
+   derived.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://privacy.net/analyze/"
+TARGET="_top"
+>http://privacy.net/analyze/</A
+>, a useful site
+   to check what information about you is leaked while you browse the web.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.squid-cache.org/"
+TARGET="_top"
+>http://www.squid-cache.org/</A
+>, a very popular
+   caching proxy, which is often used together with <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+>
+ <P
+></P
+><TABLE
+BORDER="0"
+><TBODY
+><TR
+><TD
+>   <A
+HREF="http://www.privoxy.org/developer-manual/"
+TARGET="_top"
+>http://www.privoxy.org/developer-manual/</A
+>, 
+   the <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> developer manual. 
+  </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="copyright.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="appendix.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Copyright, License and History</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Appendix</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/startup.html b/doc/webserver/user-manual/startup.html
new file mode 100644 (file)
index 0000000..d7fcaef
--- /dev/null
@@ -0,0 +1,505 @@
+<HTML
+><HEAD
+><TITLE
+>Starting Privoxy</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Quickstart to Using Privoxy"
+HREF="quickstart.html"><LINK
+REL="NEXT"
+TITLE="Privoxy Configuration"
+HREF="configuration.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="quickstart.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="configuration.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="STARTUP"
+>5. Starting <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></A
+></H1
+><P
+> Before launching <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> for the first time, you
+ will want to configure your browser(s) to use
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> as a HTTP and HTTPS proxy. The default is
+ 127.0.0.1 (or localhost) for the proxy address, and port 8118 (earlier versions
+ used port 8000). This is the one configuration step that must be done!</P
+><P
+> 
+ With <SPAN
+CLASS="APPLICATION"
+>Netscape</SPAN
+> (and
+ <SPAN
+CLASS="APPLICATION"
+>Mozilla</SPAN
+>), this can be set under <TT
+CLASS="LITERAL"
+>Edit
+ -&#62; Preferences -&#62; Advanced -&#62; Proxies -&#62; HTTP Proxy</TT
+>.
+ For <SPAN
+CLASS="APPLICATION"
+>Internet Explorer</SPAN
+>: <TT
+CLASS="LITERAL"
+>Tools -&#62;
+ Internet Properties -&#62; Connections -&#62; LAN Setting</TT
+>. Then,
+ check <SPAN
+CLASS="QUOTE"
+>"Use Proxy"</SPAN
+> and fill in the appropriate info (Address:
+ 127.0.0.1, Port: 8118). Include if HTTPS proxy support too.</P
+><P
+> After doing this, flush your browser's disk and memory caches to force a
+ re-reading of all pages and to get rid of any ads that may be cached. You 
+ are now ready to start enjoying the benefits of using
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>!</P
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is typically started by specifying the
+ main configuration file to be used on the command line. If no configuration
+ file is specified on the command line, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ will look for a file named <TT
+CLASS="FILENAME"
+>config</TT
+> in the current
+ directory. Except on Win32 where it will try <TT
+CLASS="FILENAME"
+>config.txt</TT
+>.</P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-REDHAT"
+>5.1. RedHat and Conectiva</A
+></H2
+><P
+>We use a script. Note that RedHat does not start Privoxy upon booting per
+default. It will use the file <TT
+CLASS="FILENAME"
+>/etc/privoxy/config</TT
+> as its
+main configuration file.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> # /etc/rc.d/init.d/privoxy start</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-DEBIAN"
+>5.2. Debian</A
+></H2
+><P
+> We use a script. Note that Debian starts Privoxy upon booting per
+ default.  It will use the file
+ <TT
+CLASS="FILENAME"
+>/etc/privoxy/config</TT
+> as its main configuration
+ file.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> # /etc/init.d/privoxy start</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-SUSE"
+>5.3. SuSE</A
+></H2
+><P
+>We use a script. It will use the file <TT
+CLASS="FILENAME"
+>/etc/privoxy/config</TT
+>
+as its main configuration file. Note that SuSE starts Privoxy upon booting
+your PC.</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> # rcprivoxy start</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-WINDOWS"
+>5.4. Windows</A
+></H2
+><P
+>Click on the Privoxy Icon to start Privoxy. If no configuration file is
+ specified on the command line, <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will look
+ for a file named <TT
+CLASS="FILENAME"
+>config.txt</TT
+>. Note that Windows will
+ automatically start Privoxy upon booting you PC.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-UNICES"
+>5.5. Solaris, NetBSD, FreeBSD, HP-UX and others</A
+></H2
+><P
+>Example Unix startup command:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+> # /usr/sbin/privoxy /etc/privoxy/config</PRE
+></TD
+></TR
+></TABLE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-OS2"
+>5.6. OS/2</A
+></H2
+><P
+>FIXME.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-MACOSX"
+>5.7. MAX OSX</A
+></H2
+><P
+>FIXME.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="START-AMIGAOS"
+>5.8. AmigaOS</A
+></H2
+><P
+>FIXME.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="CMDOPTIONS"
+>5.9. Command Line Options</A
+></H2
+><P
+> <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> may be invoked with the following
+ command-line options:</P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>    <I
+CLASS="EMPHASIS"
+>--version</I
+>
+  </P
+><P
+>     Print version info and exit. Unix only.
+  </P
+></LI
+><LI
+><P
+>    <I
+CLASS="EMPHASIS"
+>--help</I
+>
+  </P
+><P
+>   Print short usage info and exit. Unix only.
+  </P
+></LI
+><LI
+><P
+>   <I
+CLASS="EMPHASIS"
+>--no-daemon</I
+>
+  </P
+><P
+>   Don't become a daemon, i.e. don't fork and become process group
+   leader, and don't detach from controlling tty. Unix only.
+  </P
+></LI
+><LI
+><P
+>   <I
+CLASS="EMPHASIS"
+>--pidfile FILE</I
+>
+  
+  </P
+><P
+>   On startup, write the process ID to <I
+CLASS="EMPHASIS"
+>FILE</I
+>. Delete the
+   <I
+CLASS="EMPHASIS"
+>FILE</I
+> on exit. Failure to create or delete the
+   <I
+CLASS="EMPHASIS"
+>FILE</I
+> is non-fatal. If no <I
+CLASS="EMPHASIS"
+>FILE</I
+>
+   option is given, no PID file will be used. Unix only.
+  </P
+></LI
+><LI
+><P
+>   <I
+CLASS="EMPHASIS"
+>--user USER[.GROUP]</I
+>
+  
+  </P
+><P
+>   After (optionally) writing the PID file, assume the user  ID  of
+   <I
+CLASS="EMPHASIS"
+>USER</I
+>, and if included the GID of GROUP.  Exit if the
+   privileges are not sufficient to do so. Unix only.
+  </P
+></LI
+><LI
+><P
+>    <I
+CLASS="EMPHASIS"
+>configfile</I
+>
+  </P
+><P
+>    If no <I
+CLASS="EMPHASIS"
+>configfile</I
+> is included on the command line, 
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will look for a file named 
+    <SPAN
+CLASS="QUOTE"
+>"config"</SPAN
+> in the current directory (except on Win32 
+    where it will look for <SPAN
+CLASS="QUOTE"
+>"config.txt"</SPAN
+> instead). Specify 
+    full path to avoid confusion. If no config file is found, 
+    <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> will fail to start.
+  </P
+></LI
+></UL
+></P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="quickstart.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="configuration.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Quickstart to Using <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> Configuration</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/templates.html b/doc/webserver/user-manual/templates.html
new file mode 100644 (file)
index 0000000..dbd8a60
--- /dev/null
@@ -0,0 +1,290 @@
+<HTML
+><HEAD
+><TITLE
+>Templates</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="The Filter File"
+HREF="filter-file.html"><LINK
+REL="NEXT"
+TITLE="Contacting the Developers, Bug Reporting and Feature
+Requests"
+HREF="contact.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="filter-file.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="contact.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="TEMPLATES"
+>10. Templates</A
+></H1
+><P
+> All <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> built-in pages, i.e. error pages such as the 
+ <A
+HREF="http://show-the-404-error.page"
+TARGET="_top"
+><SPAN
+CLASS="QUOTE"
+>"404 - No Such Domain"</SPAN
+>
+ error page</A
+>, the <A
+HREF="http://ads.bannerserver.example.com/nasty-ads/sponsor.html"
+TARGET="_top"
+><SPAN
+CLASS="QUOTE"
+>"BLOCKED"</SPAN
+>
+ page</A
+>
+ and all pages of its <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>web-based
+ user interface</A
+>, are generated from <I
+CLASS="EMPHASIS"
+>templates</I
+>. 
+ (<SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> must be running for the above links to work as
+ intended)</P
+><P
+> These templates are stored in a subdirectory of the <A
+HREF="config.html#CONFDIR"
+>configuration
+ directory</A
+> called <TT
+CLASS="FILENAME"
+>templates</TT
+>. On unixish platforms,
+ this is typically
+ <A
+HREF="file:///etc/privoxy/templates/"
+TARGET="_top"
+><TT
+CLASS="FILENAME"
+>/etc/privoxy/templates/</TT
+></A
+>.</P
+><P
+> The templates are basically normal HTML files, but with place-holders (called symbols
+ or exports), which <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> fills at run time. You can
+ edit the templates with a normal text editor, should you want to customize them.
+ (<I
+CLASS="EMPHASIS"
+>Not recommended for the casual user</I
+>). Note that
+ just like in configuration files, lines starting with <TT
+CLASS="LITERAL"
+>#</TT
+> are
+ ignored when the templates are filled in.</P
+><P
+> The place-holders are of the form <TT
+CLASS="LITERAL"
+>@name@</TT
+>, and you will
+ find a list of available symbols, which vary from template to template,
+ in the comments at the start of each file. Note that these comments are not
+ always accurate, and that it's probably best to look at the existing HTML
+ code to find out which symbols are supported and what they are filled in with.</P
+><P
+> A special application of this substitution mechanism is to make whole
+ blocks of HTML code disappear when a specific symbol is set. We use this
+ for many purposes, one of them being to include the beta warning in all
+ our user interface (CGI) pages when <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ in in an alpha or beta development stage:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#60;!-- @if-unstable-start --&#62;
+
+  ... beta warning HTML code goes here ...
+
+&#60;!-- if-unstable-end@ --&#62;</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> If the "unstable" symbol is set, everything in between and including
+ <TT
+CLASS="LITERAL"
+>@if-unstable-start</TT
+> and <TT
+CLASS="LITERAL"
+>if-unstable-end@</TT
+>
+ will disappear, leaving nothing but an empty comment:</P
+><P
+> <TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>&#60;!--  --&#62;</PRE
+></TD
+></TR
+></TABLE
+></P
+><P
+> There's also an if-then-else construct and an <TT
+CLASS="LITERAL"
+>#include</TT
+>
+ mechanism, but you'll sure find out if you are inclined to edit the
+ templates ;-)</P
+><P
+> All templates refer to a style located at
+ <A
+HREF="http://config.privoxy.org/send-stylesheet"
+TARGET="_top"
+><TT
+CLASS="LITERAL"
+>http://config.privoxy.org/send-stylesheet</TT
+></A
+>.
+ This is, of course, locally served by <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+ and the source for it can be found and edited in the
+ <TT
+CLASS="FILENAME"
+>cgi-style.css</TT
+> template.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="filter-file.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="contact.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>The Filter File</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Contacting the Developers, Bug Reporting and Feature
+Requests</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
diff --git a/doc/webserver/user-manual/upgradersnote.html b/doc/webserver/user-manual/upgradersnote.html
new file mode 100644 (file)
index 0000000..6e8ea17
--- /dev/null
@@ -0,0 +1,288 @@
+<HTML
+><HEAD
+><TITLE
+>Note to Upgraders</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.60"><LINK
+REL="HOME"
+TITLE="Privoxy User Manual"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Installation"
+HREF="installation.html"><LINK
+REL="NEXT"
+TITLE="Quickstart to Using Privoxy"
+HREF="quickstart.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="../p_doc.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#EEEEEE"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>Privoxy User Manual</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="installation.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="quickstart.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="UPGRADERSNOTE"
+>3. Note to Upgraders</A
+></H1
+><P
+> There are very significant changes from earlier 
+ <SPAN
+CLASS="APPLICATION"
+>Junkbuster</SPAN
+> versions to the current
+ <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>. The number, names, syntax, and
+ purposes of configuration files have substantially  changed.
+ <SPAN
+CLASS="APPLICATION"
+>Junkbuster 2.0.x</SPAN
+> configuration
+ files will not migrate, <SPAN
+CLASS="APPLICATION"
+>Junkbuster 2.9.x</SPAN
+>
+ and <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> configurations will need to be
+ ported. The functionalities of the old <TT
+CLASS="FILENAME"
+>blockfile</TT
+>,
+ <TT
+CLASS="FILENAME"
+>cookiefile</TT
+> and <TT
+CLASS="FILENAME"
+>imagelist</TT
+> 
+ are now combined into the <A
+HREF="actions-file.html"
+><SPAN
+CLASS="QUOTE"
+>"actions
+ files"</SPAN
+></A
+>.  
+ <TT
+CLASS="FILENAME"
+>default.action</TT
+>, is the main actions file. Local
+ exceptions should best be put into <TT
+CLASS="FILENAME"
+>user.action</TT
+>.</P
+><P
+> A <A
+HREF="filter-file.html"
+><SPAN
+CLASS="QUOTE"
+>"filter file"</SPAN
+></A
+> (typically
+ <TT
+CLASS="FILENAME"
+>default.filter</TT
+>) is new as of <SPAN
+CLASS="APPLICATION"
+>Privoxy
+ 2.9.x</SPAN
+>, and provides some of the new sophistication (explained
+ below). <TT
+CLASS="FILENAME"
+>config</TT
+> is much the same as before.</P
+><P
+> If upgrading from a 2.0.x version, you will have to use the new config 
+ files, and possibly adapt any personal rules from your older files.
+ When porting personal rules over from the old <TT
+CLASS="FILENAME"
+>blockfile</TT
+>
+ to the new actions files, please note that even the pattern syntax has
+ changed. If upgrading from 2.9.x development versions, it is still
+ recommended to use the new configuration files.</P
+><P
+> A quick list of things to be aware of before upgrading: </P
+><P
+> <P
+></P
+><UL
+><LI
+><P
+>   The default listening port is now 8118 due to a conflict with another 
+   service (NAS).
+  </P
+></LI
+><LI
+><P
+>  
+    Some installers may remove earlier versions completely. Save any 
+    important configuration files!
+  </P
+></LI
+><LI
+><P
+>   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> is controllable with a web browser 
+   at the special URL: <A
+HREF="http://config.privoxy.org/"
+TARGET="_top"
+>http://config.privoxy.org/</A
+>
+   (Shortcut: <A
+HREF="http://p.p/"
+TARGET="_top"
+>http://p.p/</A
+>). Many
+   aspects of configuration can be done here, including temporarily disabling
+   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>.
+  </P
+></LI
+><LI
+><P
+>   The primary configuration files for cookie management, ad and banner 
+   blocking, and many other aspects of <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+>
+   configuration are the <A
+HREF="actions-file.html"
+>actions
+   files</A
+>. It is strongly recommended to become familiar with the new
+   actions concept below, before modifying these files. Locally defined rules 
+   should go into <TT
+CLASS="FILENAME"
+>user.action</TT
+>.
+  </P
+></LI
+><LI
+><P
+>   
+   Some installers may not automatically start
+   <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+> after installation.
+  </P
+></LI
+></UL
+></P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="installation.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="quickstart.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Installation</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Quickstart to Using <SPAN
+CLASS="APPLICATION"
+>Privoxy</SPAN
+></TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
index 42d0744..09c7b5f 100644 (file)
--- a/encode.c
+++ b/encode.c
@@ -1,13 +1,13 @@
-const char encode_rcs[] = "$Id: encode.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char encode_rcs[] = "$Id: encode.c,v 1.7 2002/03/24 13:25:43 swa Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/encode.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/encode.c,v $
  *
  * Purpose     :  Functions to encode and decode URLs, and also to
  *                encode cookies and HTML text.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
@@ -33,6 +33,30 @@ const char encode_rcs[] = "$Id: encode.c,v 1.1 2001/05/13 21:57:06 administrator
  *
  * Revisions   :
  *    $Log: encode.c,v $
+ *    Revision 1.7  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.6  2002/03/13 00:27:04  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.5  2002/03/07 03:46:53  oes
+ *    Fixed compiler warnings etc
+ *
+ *    Revision 1.4  2002/01/22 23:28:07  jongfoster
+ *    Adding convenience function html_encode_and_free_original()
+ *    Making all functions accept NULL paramaters - in this case, they
+ *    simply return NULL.  This allows error-checking to be deferred.
+ *
+ *    Revision 1.3  2001/11/13 00:16:40  jongfoster
+ *    Replacing references to malloc.h with the standard stdlib.h
+ *    (See ANSI or K&R 2nd Ed)
+ *
+ *    Revision 1.2  2001/05/17 22:52:35  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:51  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -40,9 +64,9 @@ const char encode_rcs[] = "$Id: encode.c,v 1.1 2001/05/13 21:57:06 administrator
 #include "config.h"
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <malloc.h>
-\r
+
 #include "encode.h"
 
 const char encode_h_rcs[] = ENCODE_H_VERSION;
@@ -152,12 +176,20 @@ static const char * const cookie_code_map[256] = {
  *
  * Returns     :  Encoded string, newly allocated on the heap. 
  *                Caller is responsible for freeing it with free().
+ *                If s is NULL, or on out-of memory, returns NULL.
  *
  *********************************************************************/
 char * html_encode(const char *s)
 {
+   char * buf;
+   
+   if (s == NULL)
+   {
+      return NULL;
+   }
+
    /* each input char can expand to at most 6 chars */
-   char * buf = (char *) malloc((strlen(s) * 6) + 1);
+   buf = (char *) malloc((strlen(s) * 6) + 1);
 
    if (buf)
    {
@@ -183,6 +215,41 @@ char * html_encode(const char *s)
    return(buf);
 }
 
+
+/*********************************************************************
+ *
+ * Function    :  html_encode_and_free_original
+ *
+ * Description :  Encodes a string so it's not interpreted as
+ *                containing HTML tags or entities.
+ *                Replaces <, >, &, and " with the appropriate HTML
+ *                entities.  Free()s original string.
+ *                If original string is NULL, simply returns NULL.
+ *
+ * Parameters  :
+ *          1  :  s = String to encode.  Null-terminated.
+ *
+ * Returns     :  Encoded string, newly allocated on the heap. 
+ *                Caller is responsible for freeing it with free().
+ *                If s is NULL, or on out-of memory, returns NULL.
+ *
+ *********************************************************************/
+char * html_encode_and_free_original(char *s)
+{
+   char * result;
+   
+   if (s == NULL)
+   {
+      return NULL;
+   }
+
+   result = html_encode(s);
+   free(s);
+
+   return result;
+}
+
+
 /*********************************************************************
  *
  * Function    :  cookie_encode
@@ -196,12 +263,20 @@ char * html_encode(const char *s)
  *
  * Returns     :  Encoded string, newly allocated on the heap. 
  *                Caller is responsible for freeing it with free().
+ *                If s is NULL, or on out-of memory, returns NULL.
  *
  *********************************************************************/
 char * cookie_encode(const char *s)
 {
+   char * buf;
+
+   if (s == NULL)
+   {
+      return NULL;
+   }
+
    /* each input char can expand to at most 3 chars */
-   char * buf = (char *) malloc((strlen(s) * 3) + 1);
+   buf = (char *) malloc((strlen(s) * 3) + 1);
 
    if (buf)
    {
@@ -232,7 +307,7 @@ char * cookie_encode(const char *s)
  * Function    :  url_encode
  *
  * Description :  Encodes a string so it can be used in a URL
- *                query string.  Replaces special characters with\r
+ *                query string.  Replaces special characters with
  *                the appropriate %xx codes.
  *
  * Parameters  :
@@ -240,15 +315,23 @@ char * cookie_encode(const char *s)
  *
  * Returns     :  Encoded string, newly allocated on the heap. 
  *                Caller is responsible for freeing it with free().
+ *                If s is NULL, or on out-of memory, returns NULL.
  *
  *********************************************************************/
 char * url_encode(const char *s)
-{\r
-   /* each input char can expand to at most 3 chars */\r
-   char * buf = (char *) malloc((strlen(s) * 3) + 1);
-\r
+{
+   char * buf;
+
+   if (s == NULL)
+   {
+      return NULL;
+   }
+
+   /* each input char can expand to at most 3 chars */
+   buf = (char *) malloc((strlen(s) * 3) + 1);
+
    if (buf)
-   {\r
+   {
       char c;
       char * p = buf;
       while( (c = *s++) != '\0')
@@ -266,9 +349,9 @@ char * url_encode(const char *s)
       }
 
       *p = '\0';
-\r
+
    }
-\r
+
    return(buf);
 }
 
@@ -285,7 +368,7 @@ char * url_encode(const char *s)
  * Returns     :  The integer value, or -1 for non-hex characters.
  *
  *********************************************************************/
-static int xdtoi(char d)
+static int xdtoi(const int d)
 {
    if ((d >= '0') && (d <= '9'))
    {
@@ -323,10 +406,10 @@ static int xtoi(const char *s)
 {
    int d1, d2;
 
-   d1 = xdtoi(*s++);
+   d1 = xdtoi(*s);
    if(d1 >= 0)
    {
-      d2 = xdtoi(*s);
+      d2 = xdtoi(*(s+1));
       if(d2 >= 0)
       {
          return (d1 << 4) + d2;
@@ -355,9 +438,9 @@ char *url_decode(const char * s)
 {
    char *buf = malloc(strlen(s) + 1);
    char *q = buf;
-\r
-   if (buf)\r
-   {\r
+
+   if (buf)
+   {
       while (*s)
       {
          switch (*s)
@@ -368,7 +451,7 @@ char *url_decode(const char * s)
                break;
 
             case '%':
-               if ((*q = xtoi(s + 1)))
+               if ((*q = xtoi(s + 1)) != '\0')
                {
                   s += 3;
                   q++;
@@ -385,9 +468,9 @@ char *url_decode(const char * s)
                break;
          }
       }
-      *q = '\0';\r
+      *q = '\0';
    }
-\r
+
    return(buf);
 
 }
index ba0b6cf..875b966 100644 (file)
--- a/encode.h
+++ b/encode.h
@@ -1,15 +1,15 @@
-#ifndef _ENCODE_H
-#define _ENCODE_H
-#define ENCODE_H_VERSION "$Id: encode.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef ENCODE_H_INCLUDED
+#define ENCODE_H_INCLUDED
+#define ENCODE_H_VERSION "$Id: encode.h,v 1.4 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/encode.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/encode.h,v $
  *
  * Purpose     :  Functions to encode and decode URLs, and also to
  *                encode cookies and HTML text.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: encode.h,v $
+ *    Revision 1.4  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.3  2002/01/22 23:28:07  jongfoster
+ *    Adding convenience function html_encode_and_free_original()
+ *    Making all functions accept NULL paramaters - in this case, they
+ *    simply return NULL.  This allows error-checking to be deferred.
+ *
+ *    Revision 1.2  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:51  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -48,6 +63,8 @@ extern char * cookie_encode(const char *s);
 extern char * url_encode(const char *s);
 extern char * url_decode(const char *str);
 
+extern char * html_encode_and_free_original(char *s);
+
 /* Revision control strings from this header and associated .c file */
 extern const char encode_rcs[];
 extern const char encode_h_rcs[];
@@ -56,7 +73,7 @@ extern const char encode_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _ENCODE_H */
+#endif /* ndef ENCODE_H_INCLUDED */
 
 /*
   Local Variables:
index 54b2687..4a3cfe7 100644 (file)
--- a/errlog.c
+++ b/errlog.c
@@ -1,13 +1,13 @@
-const char errlog_rcs[] = "$Id: errlog.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char errlog_rcs[] = "$Id: errlog.c,v 1.39 2002/04/03 17:15:27 gliptak Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/errlog.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/errlog.c,v $
  *
  * Purpose     :  Log errors to a designated destination in an elegant,
  *                printf-like fashion.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
@@ -33,50 +33,288 @@ const char errlog_rcs[] = "$Id: errlog.c,v 1.1 2001/05/13 21:57:06 administrator
  *
  * Revisions   :
  *    $Log: errlog.c,v $
+ *    Revision 1.39  2002/04/03 17:15:27  gliptak
+ *    zero padding thread ids in log
+ *
+ *    Revision 1.38  2002/03/31 17:18:59  jongfoster
+ *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
+ *
+ *    Revision 1.37  2002/03/27 14:32:43  david__schmidt
+ *    More compiler warning message maintenance
+ *
+ *    Revision 1.36  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.35  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.34  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.33  2002/03/13 00:27:04  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.32  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.31  2002/03/06 23:02:57  jongfoster
+ *    Removing tabs
+ *
+ *    Revision 1.30  2002/03/05 22:43:45  david__schmidt
+ *    - Better error reporting on OS/2
+ *    - Fix double-slash comment (oops)
+ *
+ *    Revision 1.29  2002/03/04 23:45:13  jongfoster
+ *    Printing thread ID if using Win32 native threads
+ *
+ *    Revision 1.28  2002/03/04 17:59:59  oes
+ *    Deleted deletePidFile(), cosmetics
+ *
+ *    Revision 1.27  2002/03/04 02:08:01  david__schmidt
+ *    Enable web editing of actions file on OS/2 (it had been broken all this time!)
+ *
+ *    Revision 1.26  2002/01/09 19:05:45  steudten
+ *    Fix big memory leak.
+ *
+ *    Revision 1.25  2002/01/09 14:32:08  oes
+ *    Added support for gmtime_r and localtime_r.
+ *
+ *    Revision 1.24  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.23  2001/11/07 00:02:13  steudten
+ *    Add line number in error output for lineparsing for
+ *    actionsfile and configfile.
+ *    Special handling for CLF added.
+ *
+ *    Revision 1.22  2001/11/05 23:43:05  steudten
+ *    Add time+date to log files.
+ *
+ *    Revision 1.21  2001/10/25 03:40:47  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.20  2001/09/16 23:04:34  jongfoster
+ *    Fixing a warning
+ *
+ *    Revision 1.19  2001/09/13 20:08:06  jongfoster
+ *    Adding support for LOG_LEVEL_CGI
+ *
+ *    Revision 1.18  2001/09/10 11:27:24  oes
+ *    Declaration of w32_socket_strerr now conditional
+ *
+ *    Revision 1.17  2001/09/10 10:17:13  oes
+ *    Removed unused variable; Fixed sprintf format
+ *
+ *    Revision 1.16  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.15  2001/07/29 17:41:10  jongfoster
+ *    Now prints thread ID for each message (pthreads only)
+ *
+ *    Revision 1.14  2001/07/19 19:03:48  haroon
+ *    - Added case for LOG_LEVEL_POPUPS
+ *
+ *    Revision 1.13  2001/07/13 13:58:58  oes
+ *     - Added case for LOG_LEVEL_DEANIMATE
+ *     - Removed all #ifdef PCRS
+ *
+ *    Revision 1.12  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.11  2001/06/01 18:14:49  jongfoster
+ *    Changing the calls to strerr() to check HAVE_STRERR (which is defined
+ *    in config.h if appropriate) rather than the NO_STRERR macro.
+ *
+ *    Revision 1.10  2001/05/29 11:52:21  oes
+ *    Conditional compilation of w32_socket_error
+ *
+ *    Revision 1.9  2001/05/28 16:15:17  jongfoster
+ *    Improved reporting of errors under Win32.
+ *
+ *    Revision 1.8  2001/05/26 17:25:14  jongfoster
+ *    Added support for CLF (Common Log Format) and fixed LOG_LEVEL_LOG
+ *
+ *    Revision 1.7  2001/05/26 15:21:28  jongfoster
+ *    Activity animation in Win32 GUI now works even if debug==0
+ *
+ *    Revision 1.6  2001/05/25 21:55:08  jongfoster
+ *    Now cleans up properly on FATAL (removes taskbar icon etc)
+ *
+ *    Revision 1.5  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.4  2001/05/21 19:32:54  jongfoster
+ *    Added another #ifdef _WIN_CONSOLE
+ *
+ *    Revision 1.3  2001/05/20 01:11:40  jongfoster
+ *    Added support for LOG_LEVEL_FATAL
+ *    Renamed LOG_LEVEL_FRC to LOG_LEVEL_FORCE,
+ *    and LOG_LEVEL_REF to LOG_LEVEL_RE_FILTER
+ *
+ *    Revision 1.2  2001/05/17 22:42:01  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *     - Repaired logging for REF and FRC
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:51  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
 #include "config.h"
+#include "miscutil.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__OS2__)
 #include <unistd.h>
-#endif /* ndef _WIN32 */
+#endif /* !defined(_WIN32) && !defined(__OS2__) */
 
 #include <errno.h>
-/* #include <pthread.h> */
+#include <assert.h>
+#ifdef FEATURE_PTHREAD
+#include <pthread.h>
+#endif /* def FEATURE_PTHREAD */
 
 #ifdef _WIN32
+#ifndef STRICT
+#define STRICT
+#endif
 #include <windows.h>
+#ifndef _WIN_CONSOLE
 #include "w32log.h"
+#endif /* ndef _WIN_CONSOLE */
 #endif /* def _WIN32 */
 
+#ifdef __OS2__
+#include <sys/socket.h> /* For sock_errno */
+#define INCL_DOS
+#include <os2.h>
+#endif
+
 #include "errlog.h"
 #include "project.h"
+#include "jcc.h"
 
 const char errlog_h_rcs[] = ERRLOG_H_VERSION;
 
-/* LOG_LEVEL_ERROR and LOG_LEVEL_INFO cannot be turned off */
-#define LOG_LEVEL_MINIMUM  (LOG_LEVEL_ERROR | LOG_LEVEL_INFO)
+
+/*
+ * LOG_LEVEL_FATAL cannot be turned off.  (There are
+ * some exceptional situations where we need to get a
+ * message to the user).
+ */
+#define LOG_LEVEL_MINIMUM  LOG_LEVEL_FATAL
 
 /* where to log (default: stderr) */
 static FILE *logfp = NULL;
 
-/* where to log (NULL == stderr) */
-static char * logfilename = NULL;
-
 /* logging detail level.  */
-static int debug = LOG_LEVEL_MINIMUM;  
+static int debug = (LOG_LEVEL_FATAL | LOG_LEVEL_ERROR | LOG_LEVEL_INFO);  
+
+/* static functions */
+static void fatal_error(const char * error_message);
+#ifdef _WIN32
+static char *w32_socket_strerr(int errcode, char *tmp_buf);
+#endif
+#ifdef __OS2__
+static char *os2_socket_strerr(int errcode, char *tmp_buf);
+#endif
+
+/*********************************************************************
+ *
+ * Function    :  fatal_error
+ *
+ * Description :  Displays a fatal error to standard error (or, on 
+ *                a WIN32 GUI, to a dialog box), and exits
+ *                JunkBuster with status code 1.
+ *
+ * Parameters  :
+ *          1  :  error_message = The error message to display.
+ *
+ * Returns     :  Does not return.
+ *
+ *********************************************************************/
+static void fatal_error(const char * error_message)
+{
+#if defined(_WIN32) && !defined(_WIN_CONSOLE)
+   MessageBox(g_hwndLogFrame, error_message, "Privoxy Error", 
+      MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);  
+
+   /* Cleanup - remove taskbar icon etc. */
+   TermLogWindow();
+
+#else /* if !defined(_WIN32) || defined(_WIN_CONSOLE) */
+   fputs(error_message, stderr);
+#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
+
+#if defined(unix)
+   unlink(pidfile);
+#endif /* unix */
+
+   exit(1);
+}
 
 
 /*********************************************************************
  *
- * Function    :  init_errlog
+ * Function    :  init_error_log
  *
  * Description :  Initializes the logging module.  Must call before
  *                calling log_error.
@@ -100,6 +338,7 @@ void init_error_log(const char *prog_name, const char *logfname, int debuglevel)
 
    if ((logfp != NULL) && (logfp != stderr))
    {
+      log_error(LOG_LEVEL_INFO, "(Re-)Open logfile %s", logfname ? logfname : "none");
       fclose(logfp);
    }
    logfp = stderr;
@@ -107,14 +346,9 @@ void init_error_log(const char *prog_name, const char *logfname, int debuglevel)
    /* set the designated log file */
    if( logfname )
    {
-      if( !(fp = fopen(logfname, "a")) )
+      if( NULL == (fp = fopen(logfname, "a")) )
       {
-         log_error(LOG_LEVEL_ERROR, "init_errlog(): can't open logfile: %s", logfname);
-#if defined(_WIN32) && ! defined (_WIN_CONSOLE)
-            MessageBox(NULL, "init_errlog(): can't open logfile", "Internet JunkBuster Error", 
-               MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);  
-#endif /* defined(_WIN32) && ! defined (_WIN_CONSOLE) */
-         exit(1);
+         log_error(LOG_LEVEL_FATAL, "init_error_log(): can't open logfile: %s", logfname);
       }
 
       /* set logging to be completely unbuffered */
@@ -123,7 +357,7 @@ void init_error_log(const char *prog_name, const char *logfname, int debuglevel)
       logfp = fp;
    }
 
-   log_error(LOG_LEVEL_INFO, "Internet JunkBuster version " VERSION);
+   log_error(LOG_LEVEL_INFO, "Privoxy version " VERSION);
    if (prog_name != NULL)
    {
       log_error(LOG_LEVEL_INFO, "Program name: %s", prog_name);
@@ -151,39 +385,124 @@ void init_error_log(const char *prog_name, const char *logfname, int debuglevel)
 void log_error(int loglevel, char *fmt, ...)
 {
    va_list ap;
-   char outbuf[BUFSIZ];
+   char *outbuf= NULL;
+   static char *outbuf_save = NULL;
    char * src = fmt;
    int outc = 0;
    long this_thread = 1;  /* was: pthread_t this_thread;*/
+#ifdef __OS2__
+   PTIB     ptib;
+   APIRET   ulrc;
+#endif /* __OS2__ */
+
+#if defined(_WIN32) && !defined(_WIN_CONSOLE)
+   /*
+    * Irrespective of debug setting, a GET/POST/CONNECT makes
+    * the taskbar icon animate.  (There is an option to disable
+    * this but checking that is handled inside LogShowActivity()).
+    */
+   if (loglevel == LOG_LEVEL_GPC)
+   {
+      LogShowActivity();
+   }
+#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
 
    /* verify if loglevel applies to current settings and bail out if negative */
-   if(!(loglevel & debug))
+   if ((loglevel & debug) == 0)
    {
       return;
    }
 
    /* FIXME get current thread id */
-   /* this_thread = (long)pthread_self(); */
-
+#ifdef FEATURE_PTHREAD
+   this_thread = (long)pthread_self();
+#elif defined(_WIN32)
+   this_thread = GetCurrentThreadId();
+#elif defined(__OS2__)
+   ulrc = DosGetInfoBlocks(&ptib, NULL);
+   if (ulrc == 0)
+     this_thread = ptib -> tib_ptib2 -> tib2_ultid;
+#endif /* def FEATURE_PTHREAD */
+
+   if ( !outbuf_save ) 
+   {
+      outbuf_save = outbuf = (char*)malloc(BUFFER_SIZE);
+      assert(outbuf);
+   }
+   outbuf = outbuf_save;
+
+    {
+       /*
+        * Write timestamp into tempbuf.
+        *
+        * Complex because not all OSs have tm_gmtoff or
+        * the %z field in strftime()
+        */
+       time_t now; 
+       struct tm tm_now; 
+       time (&now);
+#ifdef HAVE_LOCALTIME_R
+       tm_now = *localtime_r(&now, &tm_now);
+#else
+       tm_now = *localtime (&now); 
+#endif
+       strftime(outbuf, BUFFER_SIZE-6, "%b %d %H:%M:%S ", &tm_now); 
+       outbuf += strlen( outbuf );
+    }
    switch (loglevel)
    {
       case LOG_LEVEL_ERROR:
-         outc = sprintf(outbuf, "IJB(%d) Error: ", this_thread);
+         outc = sprintf(outbuf, "Privoxy(%05ld) Error: ", this_thread);
+         break;
+      case LOG_LEVEL_FATAL:
+         outc = sprintf(outbuf, "Privoxy(%05ld) Fatal error: ", this_thread);
          break;
       case LOG_LEVEL_GPC:
-         outc = sprintf(outbuf, "IJB(%d) Request: ", this_thread);
+         outc = sprintf(outbuf, "Privoxy(%05ld) Request: ", this_thread);
          break;
       case LOG_LEVEL_CONNECT:
-         outc = sprintf(outbuf, "IJB(%d) Connect: ", this_thread);
+         outc = sprintf(outbuf, "Privoxy(%05ld) Connect: ", this_thread);
+         break;
+      case LOG_LEVEL_LOG:
+         outc = sprintf(outbuf, "Privoxy(%05ld) Writing: ", this_thread);
          break;
       case LOG_LEVEL_HEADER:
-         outc = sprintf(outbuf, "IJB(%d) Header: ", this_thread);
+         outc = sprintf(outbuf, "Privoxy(%05ld) Header: ", this_thread);
          break;
       case LOG_LEVEL_INFO:
-         outc = sprintf(outbuf, "IJB(%d) Info: ", this_thread);
+         outc = sprintf(outbuf, "Privoxy(%05ld) Info: ", this_thread);
+         break;
+      case LOG_LEVEL_RE_FILTER:
+         outc = sprintf(outbuf, "Privoxy(%05ld) Re-Filter: ", this_thread);
+         break;
+#ifdef FEATURE_FORCE_LOAD
+      case LOG_LEVEL_FORCE:
+         outc = sprintf(outbuf, "Privoxy(%05ld) Force: ", this_thread);
+         break;
+#endif /* def FEATURE_FORCE_LOAD */
+#ifdef FEATURE_FAST_REDIRECTS
+      case LOG_LEVEL_REDIRECTS:
+         outc = sprintf(outbuf, "Privoxy(%05ld) Redirect: ", this_thread);
+         break;
+#endif /* def FEATURE_FAST_REDIRECTS */
+      case LOG_LEVEL_DEANIMATE:
+         outc = sprintf(outbuf, "Privoxy(%05ld) Gif-Deanimate: ", this_thread);
+         break;
+      case LOG_LEVEL_CLF:
+         outbuf = outbuf_save;
+         outc = 0;
+         outbuf[0] = '\0';
+         break;
+#ifdef FEATURE_KILL_POPUPS
+      case LOG_LEVEL_POPUPS:
+         outc = sprintf(outbuf, "Privoxy(%05ld) Kill-Popups: ", this_thread);
+         break;
+#endif /* def FEATURE_KILL_POPUPS */
+      case LOG_LEVEL_CGI:
+         outc = sprintf(outbuf, "Privoxy(%05ld) CGI: ", this_thread);
          break;
       default:
-         outc = sprintf(outbuf, "IJB(%d) UNKNOWN LOG TYPE(%d): ", this_thread, loglevel);
+         outc = sprintf(outbuf, "Privoxy(%05ld) UNKNOWN LOG TYPE(%d): ", this_thread, loglevel);
          break;
    }
    
@@ -191,10 +510,10 @@ void log_error(int loglevel, char *fmt, ...)
    va_start( ap, fmt );
 
    /* build formatted message from fmt and var-args */
-   while ((*src) && (outc < BUFSIZ-2))
+   while ((*src) && (outc < BUFFER_SIZE-2))
    {
-      char tempbuf[BUFSIZ];
-      char *sval;
+      char tempbuf[BUFFER_SIZE];
+      char *sval = NULL;
       int ival;
       unsigned uval;
       long lval;
@@ -218,7 +537,7 @@ void log_error(int loglevel, char *fmt, ...)
             ival = va_arg( ap, int );
             oldoutc = outc;
             outc += sprintf(tempbuf, "%d", ival);
-            if (outc < BUFSIZ-1) 
+            if (outc < BUFFER_SIZE-1) 
             {
                strcpy(outbuf + oldoutc, tempbuf);
             }
@@ -231,7 +550,7 @@ void log_error(int loglevel, char *fmt, ...)
             uval = va_arg( ap, unsigned );
             oldoutc = outc;
             outc += sprintf(tempbuf, "%u", uval);
-            if (outc < BUFSIZ-1) 
+            if (outc < BUFFER_SIZE-1) 
             {
                strcpy(outbuf + oldoutc, tempbuf);
             }
@@ -258,7 +577,7 @@ void log_error(int loglevel, char *fmt, ...)
             else
             {
                /* Error */
-               sprintf(outbuf, "IJB(%d) Error: log_error(): Bad format string:\n"
+               sprintf(outbuf, "Privoxy(%ld) Error: log_error(): Bad format string:\n"
                                "Format = \"%s\"\n"
                                "Exiting.", this_thread, fmt);
                /* FIXME RACE HAZARD: should start critical section error_log_use here */
@@ -268,14 +587,11 @@ void log_error(int loglevel, char *fmt, ...)
                }
                fputs(outbuf, logfp);
                /* FIXME RACE HAZARD: should end critical section error_log_use here */
-#if defined(_WIN32) && ! defined (_WIN_CONSOLE)
-               MessageBox(NULL, outbuf, "Internet JunkBuster Error", 
-                  MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);  
-#endif /* defined(_WIN32) && ! defined (_WIN_CONSOLE) */
-               exit(1);
+               fatal_error(outbuf);
+               /* Never get here */
                break;
             }
-            if (outc < BUFSIZ-1) 
+            if (outc < BUFFER_SIZE-1) 
             {
                strcpy(outbuf + oldoutc, tempbuf);
             }
@@ -295,7 +611,7 @@ void log_error(int loglevel, char *fmt, ...)
             sval = va_arg( ap, char * );
             oldoutc = outc;
             outc += strlen(sval);
-            if (outc < BUFSIZ-1) 
+            if (outc < BUFFER_SIZE-1) 
             {
                strcpy(outbuf + oldoutc, sval);
             }
@@ -304,22 +620,57 @@ void log_error(int loglevel, char *fmt, ...)
                outbuf[oldoutc] = '\0';
             }
             break;
+         case 'N':
+            /* Non-standard: Print a counted string.  Takes 2 parameters:
+             * int length, const char * string
+             */
+            ival = va_arg( ap, int );
+            sval = va_arg( ap, char * );
+            if (ival < 0)
+            {
+               ival = 0;
+            }
+            oldoutc = outc;
+            outc += ival;
+            if (outc < BUFFER_SIZE-1)
+            {
+               memcpy(outbuf + oldoutc, sval, (size_t) ival);
+            }
+            else
+            {
+               outbuf[oldoutc] = '\0';
+            }
+            break;
          case 'E':
             /* Non-standard: Print error code from errno */
-            ival = errno;
-#ifndef NOSTRERROR
+#ifdef _WIN32
+            ival = WSAGetLastError();
+            sval = w32_socket_strerr(ival, tempbuf);
+#elif __OS2__
+            ival = sock_errno();
+            if (ival != 0)
+              sval = os2_socket_strerr(ival, tempbuf);
+            else
+            {
+              ival = errno;
+              sval = strerror(ival);
+            }
+#else /* ifndef _WIN32 */
+            ival = errno; 
+#ifdef HAVE_STRERROR
             sval = strerror(ival);
-#else /* def NOSTRERROR */
-            sval = NULL
-#endif /* def NOSTRERROR */
+#else /* ifndef HAVE_STRERROR */
+            sval = NULL;
+#endif /* ndef HAVE_STRERROR */
             if (sval == NULL)
             {
                sprintf(tempbuf, "(errno = %d)", ival);
                sval = tempbuf;
             }
+#endif /* ndef _WIN32 */
             oldoutc = outc;
             outc += strlen(sval);
-            if (outc < BUFSIZ-1) 
+            if (outc < BUFFER_SIZE-1) 
             {
                strcpy(outbuf + oldoutc, sval);
             }
@@ -328,8 +679,52 @@ void log_error(int loglevel, char *fmt, ...)
                outbuf[oldoutc] = '\0';
             }
             break;
+         case 'T':
+            /* Non-standard: Print a Common Log File timestamp */
+            {
+               /*
+                * Write timestamp into tempbuf.
+                *
+                * Complex because not all OSs have tm_gmtoff or
+                * the %z field in strftime()
+                */
+               time_t now; 
+               struct tm *tm_now; 
+               struct tm gmt;
+#ifdef HAVE_LOCALTIME_R
+               struct tm dummy;
+#endif
+               int days, hrs, mins; 
+               time (&now); 
+#ifdef HAVE_GMTIME_R
+               gmt = *gmtime_r(&now, &gmt);
+#else
+               gmt = *gmtime(&now);
+#endif
+#ifdef HAVE_LOCALTIME_R
+               tm_now = localtime_r(&now, &dummy);
+#else
+               tm_now = localtime (&now); 
+#endif
+               days = tm_now->tm_yday - gmt.tm_yday; 
+               hrs = ((days < -1 ? 24 : 1 < days ? -24 : days * 24) + tm_now->tm_hour - gmt.tm_hour); 
+               mins = hrs * 60 + tm_now->tm_min - gmt.tm_min; 
+               strftime (tempbuf, BUFFER_SIZE-6, "%d/%b/%Y:%H:%M:%S ", tm_now); 
+               sprintf (tempbuf + strlen(tempbuf), "%+03d%02d", mins / 60, abs(mins) % 60); 
+            }
+            oldoutc = outc;
+            outc += strlen(tempbuf);
+            if (outc < BUFFER_SIZE-1) 
+            {
+               strcpy(outbuf + oldoutc, tempbuf);
+            }
+            else
+            {
+               outbuf[oldoutc] = '\0';
+            }
+            break;
          default:
-            sprintf(outbuf, "IJB(%d) Error: log_error(): Bad format string:\n"
+            sprintf(outbuf, "Privoxy(%ld) Error: log_error(): Bad format string:\n"
                             "Format = \"%s\"\n"
                             "Exiting.", this_thread, fmt);
             /* FIXME RACE HAZARD: should start critical section error_log_use here */
@@ -337,13 +732,10 @@ void log_error(int loglevel, char *fmt, ...)
             {
                logfp = stderr;
             }
-            fputs(outbuf, logfp);
+            fputs(outbuf_save, logfp);
             /* FIXME RACE HAZARD: should end critical section error_log_use here */
-#if defined(_WIN32) && ! defined (_WIN_CONSOLE)
-            MessageBox(NULL, outbuf, "Internet JunkBuster Error", 
-               MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);  
-#endif /* defined(_WIN32) && ! defined (_WIN_CONSOLE) */
-            exit(1);
+            fatal_error(outbuf_save);
+            /* Never get here */
             break;
 
       } /* switch( p ) */
@@ -353,20 +745,20 @@ void log_error(int loglevel, char *fmt, ...)
    /* done with var. args */
    va_end( ap );
    
-   if (outc >= BUFSIZ-2)
+   if (outc >= BUFFER_SIZE-2)
    {
       /* insufficient room for newline and trailing null. */
 
       static const char warning[] = "... [too long, truncated]\n";
 
-      if (outc < BUFSIZ)
+      if (outc < BUFFER_SIZE)
       {
          /* Need to add terminating null in this case. */
          outbuf[outc] = '\0';
       }
 
       /* Truncate output */
-      outbuf[BUFSIZ - sizeof(warning)] = '\0';
+      outbuf[BUFFER_SIZE - sizeof(warning)] = '\0';
 
       /* Append warning */
       strcat(outbuf, warning);
@@ -386,22 +778,192 @@ void log_error(int loglevel, char *fmt, ...)
       logfp = stderr;
    }
 
-   fputs(outbuf, logfp);
+   fputs(outbuf_save, logfp);
+
+   if (loglevel == LOG_LEVEL_FATAL)
+   {
+      fatal_error(outbuf_save);
+      /* Never get here */
+   }
 
    /* FIXME RACE HAZARD: should end critical section error_log_use here */
 
 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
    /* Write to display */
-   LogPutString(outbuf);
-   LogShowActivity();
+   LogPutString(outbuf_save);
 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
 
 }
 
 
+#ifdef _WIN32
+/*********************************************************************
+ *
+ * Function    :  w32_socket_strerr
+ *
+ * Description :  Translate the return value from WSAGetLastError()
+ *                into a string.
+ *
+ * Parameters  :
+ *          1  :  errcode = The return value from WSAGetLastError().
+ *          2  :  tmp_buf = A temporary buffer that might be used to
+ *                          store the string.
+ *
+ * Returns     :  String representing the error code.  This may be
+ *                a global string constant or a string stored in
+ *                tmp_buf.
+ *
+ *********************************************************************/
+static char *w32_socket_strerr(int errcode, char *tmp_buf)
+{
+#define TEXT_FOR_ERROR(code,text) \
+   if (errcode == code)           \
+   {                              \
+      return #code " - " text;    \
+   }
+
+   TEXT_FOR_ERROR(WSAEACCES, "Permission denied")
+   TEXT_FOR_ERROR(WSAEADDRINUSE, "Address already in use.")
+   TEXT_FOR_ERROR(WSAEADDRNOTAVAIL, "Cannot assign requested address.");
+   TEXT_FOR_ERROR(WSAEAFNOSUPPORT, "Address family not supported by protocol family.");
+   TEXT_FOR_ERROR(WSAEALREADY, "Operation already in progress.");
+   TEXT_FOR_ERROR(WSAECONNABORTED, "Software caused connection abort.");
+   TEXT_FOR_ERROR(WSAECONNREFUSED, "Connection refused.");
+   TEXT_FOR_ERROR(WSAECONNRESET, "Connection reset by peer.");
+   TEXT_FOR_ERROR(WSAEDESTADDRREQ, "Destination address required.");
+   TEXT_FOR_ERROR(WSAEFAULT, "Bad address.");
+   TEXT_FOR_ERROR(WSAEHOSTDOWN, "Host is down.");
+   TEXT_FOR_ERROR(WSAEHOSTUNREACH, "No route to host.");
+   TEXT_FOR_ERROR(WSAEINPROGRESS, "Operation now in progress.");
+   TEXT_FOR_ERROR(WSAEINTR, "Interrupted function call.");
+   TEXT_FOR_ERROR(WSAEINVAL, "Invalid argument.");
+   TEXT_FOR_ERROR(WSAEISCONN, "Socket is already connected.");
+   TEXT_FOR_ERROR(WSAEMFILE, "Too many open sockets.");
+   TEXT_FOR_ERROR(WSAEMSGSIZE, "Message too long.");
+   TEXT_FOR_ERROR(WSAENETDOWN, "Network is down.");
+   TEXT_FOR_ERROR(WSAENETRESET, "Network dropped connection on reset.");
+   TEXT_FOR_ERROR(WSAENETUNREACH, "Network is unreachable.");
+   TEXT_FOR_ERROR(WSAENOBUFS, "No buffer space available.");
+   TEXT_FOR_ERROR(WSAENOPROTOOPT, "Bad protocol option.");
+   TEXT_FOR_ERROR(WSAENOTCONN, "Socket is not connected.");
+   TEXT_FOR_ERROR(WSAENOTSOCK, "Socket operation on non-socket.");
+   TEXT_FOR_ERROR(WSAEOPNOTSUPP, "Operation not supported.");
+   TEXT_FOR_ERROR(WSAEPFNOSUPPORT, "Protocol family not supported.");
+   TEXT_FOR_ERROR(WSAEPROCLIM, "Too many processes.");
+   TEXT_FOR_ERROR(WSAEPROTONOSUPPORT, "Protocol not supported.");
+   TEXT_FOR_ERROR(WSAEPROTOTYPE, "Protocol wrong type for socket.");
+   TEXT_FOR_ERROR(WSAESHUTDOWN, "Cannot send after socket shutdown.");
+   TEXT_FOR_ERROR(WSAESOCKTNOSUPPORT, "Socket type not supported.");
+   TEXT_FOR_ERROR(WSAETIMEDOUT, "Connection timed out.");
+   TEXT_FOR_ERROR(WSAEWOULDBLOCK, "Resource temporarily unavailable.");
+   TEXT_FOR_ERROR(WSAHOST_NOT_FOUND, "Host not found.");
+   TEXT_FOR_ERROR(WSANOTINITIALISED, "Successful WSAStartup not yet performed.");
+   TEXT_FOR_ERROR(WSANO_DATA, "Valid name, no data record of requested type.");
+   TEXT_FOR_ERROR(WSANO_RECOVERY, "This is a non-recoverable error.");
+   TEXT_FOR_ERROR(WSASYSNOTREADY, "Network subsystem is unavailable.");
+   TEXT_FOR_ERROR(WSATRY_AGAIN, "Non-authoritative host not found.");
+   TEXT_FOR_ERROR(WSAVERNOTSUPPORTED, "WINSOCK.DLL version out of range.");
+   TEXT_FOR_ERROR(WSAEDISCON, "Graceful shutdown in progress.");
+   /*
+    * The following error codes are documented in the Microsoft WinSock
+    * reference guide, but don't actually exist.
+    *
+    * TEXT_FOR_ERROR(WSA_INVALID_HANDLE, "Specified event object handle is invalid.");
+    * TEXT_FOR_ERROR(WSA_INVALID_PARAMETER, "One or more parameters are invalid.");
+    * TEXT_FOR_ERROR(WSAINVALIDPROCTABLE, "Invalid procedure table from service provider.");
+    * TEXT_FOR_ERROR(WSAINVALIDPROVIDER, "Invalid service provider version number.");
+    * TEXT_FOR_ERROR(WSA_IO_PENDING, "Overlapped operations will complete later.");
+    * TEXT_FOR_ERROR(WSA_IO_INCOMPLETE, "Overlapped I/O event object not in signaled state.");
+    * TEXT_FOR_ERROR(WSA_NOT_ENOUGH_MEMORY, "Insufficient memory available.");
+    * TEXT_FOR_ERROR(WSAPROVIDERFAILEDINIT, "Unable to initialize a service provider.");
+    * TEXT_FOR_ERROR(WSASYSCALLFAILURE, "System call failure.");
+    * TEXT_FOR_ERROR(WSA_OPERATION_ABORTED, "Overlapped operation aborted.");
+    */
+
+   sprintf(tmp_buf, "(error number %d)", errcode);
+   return tmp_buf;
+}
+#endif /* def _WIN32 */
+
+
+#ifdef __OS2__
+/*********************************************************************
+ *
+ * Function    :  os2_socket_strerr
+ *
+ * Description :  Translate the return value from sock_errno()
+ *                into a string.
+ *
+ * Parameters  :
+ *          1  :  errcode = The return value from sock_errno().
+ *          2  :  tmp_buf = A temporary buffer that might be used to
+ *                          store the string.
+ *
+ * Returns     :  String representing the error code.  This may be
+ *                a global string constant or a string stored in
+ *                tmp_buf.
+ *
+ *********************************************************************/
+static char *os2_socket_strerr(int errcode, char *tmp_buf)
+{
+#define TEXT_FOR_ERROR(code,text) \
+   if (errcode == code)           \
+   {                              \
+      return #code " - " text;    \
+   }
+
+   TEXT_FOR_ERROR(SOCEPERM          , "Not owner.")
+   TEXT_FOR_ERROR(SOCESRCH          , "No such process.")
+   TEXT_FOR_ERROR(SOCEINTR          , "Interrupted system call.")
+   TEXT_FOR_ERROR(SOCENXIO          , "No such device or address.")
+   TEXT_FOR_ERROR(SOCEBADF          , "Bad file number.")
+   TEXT_FOR_ERROR(SOCEACCES         , "Permission denied.")
+   TEXT_FOR_ERROR(SOCEFAULT         , "Bad address.")
+   TEXT_FOR_ERROR(SOCEINVAL         , "Invalid argument.")
+   TEXT_FOR_ERROR(SOCEMFILE         , "Too many open files.")
+   TEXT_FOR_ERROR(SOCEPIPE          , "Broken pipe.")
+   TEXT_FOR_ERROR(SOCEWOULDBLOCK    , "Operation would block.")
+   TEXT_FOR_ERROR(SOCEINPROGRESS    , "Operation now in progress.")
+   TEXT_FOR_ERROR(SOCEALREADY       , "Operation already in progress.")
+   TEXT_FOR_ERROR(SOCENOTSOCK       , "Socket operation on non-socket.")
+   TEXT_FOR_ERROR(SOCEDESTADDRREQ   , "Destination address required.")
+   TEXT_FOR_ERROR(SOCEMSGSIZE       , "Message too long.")
+   TEXT_FOR_ERROR(SOCEPROTOTYPE     , "Protocol wrong type for socket.")
+   TEXT_FOR_ERROR(SOCENOPROTOOPT    , "Protocol not available.")
+   TEXT_FOR_ERROR(SOCEPROTONOSUPPORT, "Protocol not supported.")
+   TEXT_FOR_ERROR(SOCESOCKTNOSUPPORT, "Socket type not supported.")
+   TEXT_FOR_ERROR(SOCEOPNOTSUPP     , "Operation not supported.")
+   TEXT_FOR_ERROR(SOCEPFNOSUPPORT   , "Protocol family not supported.")
+   TEXT_FOR_ERROR(SOCEAFNOSUPPORT   , "Address family not supported by protocol family.")
+   TEXT_FOR_ERROR(SOCEADDRINUSE     , "Address already in use.")
+   TEXT_FOR_ERROR(SOCEADDRNOTAVAIL  , "Can't assign requested address.")
+   TEXT_FOR_ERROR(SOCENETDOWN       , "Network is down.")
+   TEXT_FOR_ERROR(SOCENETUNREACH    , "Network is unreachable.")
+   TEXT_FOR_ERROR(SOCENETRESET      , "Network dropped connection on reset.")
+   TEXT_FOR_ERROR(SOCECONNABORTED   , "Software caused connection abort.")
+   TEXT_FOR_ERROR(SOCECONNRESET     , "Connection reset by peer.")
+   TEXT_FOR_ERROR(SOCENOBUFS        , "No buffer space available.")
+   TEXT_FOR_ERROR(SOCEISCONN        , "Socket is already connected.")
+   TEXT_FOR_ERROR(SOCENOTCONN       , "Socket is not connected.")
+   TEXT_FOR_ERROR(SOCESHUTDOWN      , "Can't send after socket shutdown.")
+   TEXT_FOR_ERROR(SOCETOOMANYREFS   , "Too many references: can't splice.")
+   TEXT_FOR_ERROR(SOCETIMEDOUT      , "Operation timed out.")
+   TEXT_FOR_ERROR(SOCECONNREFUSED   , "Connection refused.")
+   TEXT_FOR_ERROR(SOCELOOP          , "Too many levels of symbolic links.")
+   TEXT_FOR_ERROR(SOCENAMETOOLONG   , "File name too long.")
+   TEXT_FOR_ERROR(SOCEHOSTDOWN      , "Host is down.")
+   TEXT_FOR_ERROR(SOCEHOSTUNREACH   , "No route to host.")
+   TEXT_FOR_ERROR(SOCENOTEMPTY      , "Directory not empty.")
+   TEXT_FOR_ERROR(SOCEOS2ERR        , "OS/2 Error.")
+
+   sprintf(tmp_buf, "(error number %d)", errcode);
+   return tmp_buf;
+}
+#endif /* def __OS2__ */
+
+
 /*
   Local Variables:
   tab-width: 3
   end:
 */
-
index 24ce285..c3424dd 100644 (file)
--- a/errlog.h
+++ b/errlog.h
@@ -1,15 +1,15 @@
-#ifndef _ERRLOG_H
-#define _ERRLOG_H
-#define ERRLOG_H_VERSION "$Id: errlog.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef ERRLOG_H_INCLUDED
+#define ERRLOG_H_INCLUDED
+#define ERRLOG_H_VERSION "$Id: errlog.h,v 1.12 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/errlog.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/errlog.h,v $
  *
  * Purpose     :  Log errors to a designated destination in an elegant,
  *                printf-like fashion.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: errlog.h,v $
+ *    Revision 1.12  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.11  2002/03/06 23:02:57  jongfoster
+ *    Removing tabs
+ *
+ *    Revision 1.10  2001/09/13 20:08:06  jongfoster
+ *    Adding support for LOG_LEVEL_CGI
+ *
+ *    Revision 1.9  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.8  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.7  2001/07/19 19:02:53  haroon
+ *    Added define for LOG_LEVEL_POPUPS
+ *
+ *    Revision 1.6  2001/07/13 13:59:22  oes
+ *     - Added LOG_LEVEL_DEANIMATE
+ *     - Changed LOG_LEVEL_CLF
+ *     - Removed all #ifdef PCRS
+ *
+ *    Revision 1.5  2001/05/26 17:25:14  jongfoster
+ *    Added support for CLF (Common Log Format) and fixed LOG_LEVEL_LOG
+ *
+ *    Revision 1.4  2001/05/25 21:56:06  jongfoster
+ *    Added FIXME comment to (broken) LOG_LEVEL_LOG
+ *
+ *    Revision 1.3  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.2  2001/05/20 01:11:40  jongfoster
+ *    Added support for LOG_LEVEL_FATAL
+ *    Renamed LOG_LEVEL_FRC to LOG_LEVEL_FORCE,
+ *    and LOG_LEVEL_REF to LOG_LEVEL_RE_FILTER
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:51  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -45,19 +130,31 @@ extern "C" {
 
 /* Debug level for errors */
 
-#define LOG_LEVEL_GPC     0x0001
-#define LOG_LEVEL_CONNECT 0x0002
-#define LOG_LEVEL_IO      0x0004
-#define LOG_LEVEL_HEADER  0x0008
-#define LOG_LEVEL_LOG     0x0010
-#ifdef PCRS
-#define LOG_LEVEL_FRC     0x0020
-#define LOG_LEVEL_REF     0x0040
-#endif /* def PCRS */
+#define LOG_LEVEL_GPC        0x0001
+#define LOG_LEVEL_CONNECT    0x0002
+#define LOG_LEVEL_IO         0x0004
+#define LOG_LEVEL_HEADER     0x0008
+#define LOG_LEVEL_LOG        0x0010
+#ifdef FEATURE_FORCE_LOAD
+#define LOG_LEVEL_FORCE      0x0020
+#endif /* def FEATURE_FORCE_LOAD */
+#define LOG_LEVEL_RE_FILTER  0x0040
+#ifdef FEATURE_FAST_REDIRECTS
+#define LOG_LEVEL_REDIRECTS  0x0080
+#endif /* def FEATURE_FAST_REDIRECTS */
+#define LOG_LEVEL_DEANIMATE  0x0100
+
+#define LOG_LEVEL_CLF        0x0200 /* Common Log File format */
+#ifdef FEATURE_KILL_POPUPS
+#define LOG_LEVEL_POPUPS     0x0400 /* Kill Popups */
+#endif /* def FEATURE_KILL_POPUPS */
+
+#define LOG_LEVEL_CGI   0x0800 /* CGI / templates */
 
 /* Following are always on: */
-#define LOG_LEVEL_ERROR   0x1000
-#define LOG_LEVEL_INFO    0x2000
+#define LOG_LEVEL_INFO    0x1000
+#define LOG_LEVEL_ERROR   0x2000
+#define LOG_LEVEL_FATAL   0x4000 /* Exits after writing log */
 
 extern void init_error_log(const char *prog_name, const char *logfname, int debuglevel);
 extern void log_error(int loglevel, char *fmt, ...);
@@ -70,7 +167,7 @@ extern const char errlog_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _ERRLOG_H */
+#endif /* ndef ERRLOG_H_INCLUDED */
 
 /*
   Local Variables:
index 29cee47..ff70ac5 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1,24 +1,24 @@
-const char filters_rcs[] = "$Id: filters.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 1.57 2002/04/08 20:38:34 swa Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/filters.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/filters.c,v $
  *
  * Purpose     :  Declares functions to parse/crunch headers and pages.
  *                Functions declared include:
  *                   `acl_addr', `add_stats', `block_acl', `block_imageurl',
- *                   `block_url', `cookie_url', `domaincmp', `dsplit',
- *                   `filter_popups', `forward_url',
- *                   `ij_untrusted_url', `intercept_url', `re_process_buffer',
- *                   `show_proxy_args', and `trust_url'
+ *                   `block_url', `url_actions', `domain_split',
+ *                   `filter_popups', `forward_url', 'redirect_url',
+ *                   `ij_untrusted_url', `intercept_url', `pcrs_filter_respose',
+ *                   'ijb_send_banner', and `trust_url'
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -38,6 +38,359 @@ const char filters_rcs[] = "$Id: filters.c,v 1.1 2001/05/13 21:57:06 administrat
  *
  * Revisions   :
  *    $Log: filters.c,v $
+ *    Revision 1.57  2002/04/08 20:38:34  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.56  2002/04/05 15:51:24  oes
+ *     - bugfix: error-pages now get correct request protocol
+ *     - fix for invalid HTML in trust info
+ *
+ *    Revision 1.55  2002/04/02 16:13:51  oes
+ *    Fix: No "Go there anyway" for SSL
+ *
+ *    Revision 1.54  2002/04/02 14:55:56  oes
+ *    Bugfix: is_untrusted_url() now depends on FEATURE_TRUST, not FEATURE_COOKIE_JAR
+ *
+ *    Revision 1.53  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.52  2002/03/24 16:35:57  jongfoster
+ *    Removing logo
+ *
+ *    Revision 1.51  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.50  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.49  2002/03/16 20:29:14  oes
+ *    Cosmetics
+ *
+ *    Revision 1.48  2002/03/13 20:25:34  oes
+ *    Better logging for content filters
+ *
+ *    Revision 1.47  2002/03/13 00:30:52  jongfoster
+ *    Killing warnings
+ *    Added option of always sending redirect for imageblock,
+ *    currently disabled with #if 0.
+ *
+ *    Revision 1.46  2002/03/12 01:42:49  oes
+ *    Introduced modular filters
+ *
+ *    Revision 1.45  2002/03/08 16:47:50  oes
+ *    Added choice beween GIF and PNG built-in images
+ *
+ *    Revision 1.44  2002/03/07 03:49:31  oes
+ *     - Fixed compiler warnings etc
+ *     - Changed built-in images from GIF to PNG
+ *       (with regard to Unisys patent issue)
+ *     - Added a 4x4 pattern PNG which is less intrusive
+ *       than the logo but also clearly marks the deleted banners
+ *
+ *    Revision 1.43  2002/01/22 23:51:59  jongfoster
+ *    Replacing strsav() with the safer string_append().
+ *
+ *    Adding missing html_encode() to error message generators.  Where encoded
+ *    and unencoded versions of a string were provided, removing the unencoded
+ *    one.
+ *
+ *    Revision 1.42  2002/01/17 21:00:32  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Using a single, simple url_match(pattern,url) function - rather than
+ *    the 3-line match routine which was repeated all over the place.
+ *
+ *    Renaming free_url to free_url_spec, since it frees a struct url_spec.
+ *
+ *    Using parse_http_url() to parse URLs without faking a HTTP
+ *    request line for parse_http_request().
+ *
+ *    Revision 1.41  2001/11/13 00:14:07  jongfoster
+ *    Fixing stupid bug now I've figured out what || means.
+ *    (It always returns 0 or 1, not one of it's paramaters.)
+ *
+ *    Revision 1.40  2001/10/26 17:37:55  oes
+ *    - Re-enabled Netscape 200/404 bug workaround in block_url():
+ *      - Removed OS/2 special case
+ *      - Made block_url() independant from sed() having been run
+ *    - Made trust_url independant from sed() having been run
+ *    - Made is_imageurl independant from sed() having been run.
+ *      It now checks User-Agent: and Accept: by itself.
+ *
+ *
+ *    Revision 1.39  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.38  2001/10/23 21:32:33  jongfoster
+ *    Adding error-checking to selected functions
+ *
+ *    Revision 1.37  2001/10/22 15:33:56  david__schmidt
+ *    Special-cased OS/2 out of the Netscape-abort-on-404-in-js problem in
+ *    filters.c.  Added a FIXME in front of the offending code.  I'll gladly
+ *    put in a better/more robust fix for all parties if one is presented...
+ *    It seems that just returning 200 instead of 404 would pretty much fix
+ *    it for everyone, but I don't know all the history of the problem.
+ *
+ *    Revision 1.36  2001/10/10 16:44:16  oes
+ *    Added match_portlist function
+ *
+ *    Revision 1.35  2001/10/07 15:41:23  oes
+ *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
+ *
+ *    New function remove_chunked_transfer_coding that strips chunked
+ *      transfer coding to plain and is called by pcrs_filter_response
+ *      and gif_deanimate_response if neccessary
+ *
+ *    Improved handling of zero-change re_filter runs
+ *
+ *    pcrs_filter_response and gif_deanimate_response now remove
+ *      chunked transfer codeing before processing the body.
+ *
+ *    Revision 1.34  2001/09/20 15:49:36  steudten
+ *
+ *    Fix BUG: Change int size to size_t size in pcrs_filter_response().
+ *    See cgi.c fill_template().
+ *
+ *    Revision 1.33  2001/09/16 17:05:14  jongfoster
+ *    Removing unused #include showarg.h
+ *
+ *    Revision 1.32  2001/09/16 13:21:27  jongfoster
+ *    Changes to use new list functions.
+ *
+ *    Revision 1.31  2001/09/16 11:38:02  jongfoster
+ *    Splitting fill_template() into 2 functions:
+ *    template_load() loads the file
+ *    template_fill() performs the PCRS regexps.
+ *    This is because the CGI edit interface has a "table row"
+ *    template which is used many times in the page - this
+ *    change means it's only loaded from disk once.
+ *
+ *    Revision 1.30  2001/09/16 11:00:10  jongfoster
+ *    New function alloc_http_response, for symmetry with free_http_response
+ *
+ *    Revision 1.29  2001/09/13 23:32:40  jongfoster
+ *    Moving image data to cgi.c rather than cgi.h
+ *    Fixing a GPF under Win32 (and any other OS that protects global
+ *    constants from being written to).
+ *
+ *    Revision 1.28  2001/09/10 10:18:51  oes
+ *    Silenced compiler warnings
+ *
+ *    Revision 1.27  2001/08/05 16:06:20  jongfoster
+ *    Modifiying "struct map" so that there are now separate header and
+ *    "map_entry" structures.  This means that functions which modify a
+ *    map no longer need to return a pointer to the modified map.
+ *    Also, it no longer reverses the order of the entries (which may be
+ *    important with some advanced template substitutions).
+ *
+ *    Revision 1.26  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.25  2001/07/26 10:09:46  oes
+ *    Made browser detection a little less naive
+ *
+ *    Revision 1.24  2001/07/25 17:22:51  oes
+ *    Added workaround for Netscape bug that prevents display of page when loading a component fails.
+ *
+ *    Revision 1.23  2001/07/23 13:40:12  oes
+ *    Fixed bug that caused document body to be dropped when pcrs joblist was empty.
+ *
+ *    Revision 1.22  2001/07/18 12:29:34  oes
+ *    - Made gif_deanimate_response respect
+ *      csp->action->string[ACTION_STRING_DEANIMATE]
+ *    - Logging cosmetics
+ *
+ *    Revision 1.21  2001/07/13 13:59:53  oes
+ *     - Introduced gif_deanimate_response which shares the
+ *       generic content modification interface of pcrs_filter_response
+ *       and acts as a wrapper to deanimate.c:gif_deanimate()
+ *     - Renamed re_process_buffer to pcrs_filter_response
+ *     - pcrs_filter_response now returns NULL on failiure
+ *     - Removed all #ifdef PCRS
+ *
+ *    Revision 1.20  2001/07/01 17:01:04  oes
+ *    Added comments and missing return statement in is_untrusted_url()
+ *
+ *    Revision 1.19  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.18  2001/06/29 13:27:38  oes
+ *    - Cleaned up, renamed and reorderd functions
+ *      and improved comments
+ *
+ *    - block_url:
+ *      - Ported to CGI platform. Now delivers
+ *        http_response or NULL
+ *      - Unified HTML and GIF generation (moved image detection
+ *        and GIF generation here from jcc.c:chat())
+ *      - Fixed HTTP status to:
+ *       -  403 (Forbidden) for the "blocked" HTML message
+ *       -  200 (OK) for GIF answers
+ *       -  302 (Redirect) for redirect to GIF
+ *
+ *    - trust_url:
+ *      - Ported to CGI platform. Now delivers
+ *        http_response or NULL
+ *      - Separated detection of untrusted URL into
+ *        (bool)is_untrusted_url
+ *      - Added enforcement of untrusted requests
+ *
+ *    - Moved redirect_url() from cgi.c to here
+ *      and ported it to the CGI platform
+ *
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.17  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.16  2001/06/07 23:10:26  jongfoster
+ *    Allowing unanchored domain patterns to back off and retry
+ *    if they partially match.  Optimized right-anchored patterns.
+ *    Moving ACL and forward files into config file.
+ *    Replacing struct gateway with struct forward_spec
+ *
+ *    Revision 1.15  2001/06/03 19:12:00  oes
+ *    extracted-CGI relevant stuff
+ *
+ *    Revision 1.14  2001/06/01 10:30:55  oes
+ *    Added optional left-anchoring to domaincmp
+ *
+ *    Revision 1.13  2001/05/31 21:21:30  jongfoster
+ *    Permissionsfile / actions file changes:
+ *    - Changed "permission" to "action" throughout
+ *    - changes to file format to allow string parameters
+ *    - Moved helper functions to actions.c
+ *
+ *    Revision 1.12  2001/05/31 17:35:20  oes
+ *
+ *     - Enhanced domain part globbing with infix and prefix asterisk
+ *       matching and optional unanchored operation
+ *
+ *    Revision 1.11  2001/05/29 11:53:23  oes
+ *    "See why" link added to "blocked" page
+ *
+ *    Revision 1.10  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.9  2001/05/27 22:17:04  oes
+ *
+ *    - re_process_buffer no longer writes the modified buffer
+ *      to the client, which was very ugly. It now returns the
+ *      buffer, which it is then written by chat.
+ *
+ *    - content_length now adjusts the Content-Length: header
+ *      for modified documents rather than crunch()ing it.
+ *      (Length info in csp->content_length, which is 0 for
+ *      unmodified documents)
+ *
+ *    - For this to work, sed() is called twice when filtering.
+ *
+ *    Revision 1.8  2001/05/26 17:13:28  jongfoster
+ *    Filled in a function comment.
+ *
+ *    Revision 1.7  2001/05/26 15:26:15  jongfoster
+ *    ACL feature now provides more security by immediately dropping
+ *    connections from untrusted hosts.
+ *
+ *    Revision 1.6  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.5  2001/05/25 22:34:30  jongfoster
+ *    Hard tabs->Spaces
+ *
+ *    Revision 1.4  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.3  2001/05/20 16:44:47  jongfoster
+ *    Removing last hardcoded Junkbusters.com URLs.
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:52  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -49,25 +402,34 @@ const char filters_rcs[] = "$Id: filters.c,v 1.1 2001/05/13 21:57:06 administrat
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
+#include <assert.h>
 
 #ifndef _WIN32
+#ifndef __OS2__
 #include <unistd.h>
+#endif /* ndef __OS2__ */
 #include <netinet/in.h>
 #else
 #include <winsock2.h>
-#endif
+#endif /* ndef _WIN32 */
+
+#ifdef __OS2__
+#include <utils.h>
+#endif /* def __OS2__ */
 
 #include "project.h"
 #include "filters.h"
 #include "encode.h"
-#include "jcc.h"
-#include "showargs.h"
 #include "parsers.h"
 #include "ssplit.h"
-#include "gateway.h"
-#include "jbsockets.h"
 #include "errlog.h"
 #include "jbsockets.h"
+#include "miscutil.h"
+#include "actions.h"
+#include "cgi.h"
+#include "list.h"
+#include "deanimate.h"
+#include "urlmatch.h"
 
 #ifdef _WIN32
 #include "win32.h"
@@ -85,61 +447,7 @@ const char filters_h_rcs[] = FILTERS_H_VERSION;
 #define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
 
 
-static const char CBLOCK[] = 
-#ifdef AMIGA 
-       "HTTP/1.0 403 Request for blocked URL\n" 
-#else /* ifndef AMIGA */
-       "HTTP/1.0 202 Request for blocked URL\n"
-#endif /* ndef AMIGA */
-       "Pragma: no-cache\n"
-       "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
-       "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
-       "Content-Type: text/html\n\n"
-       "<html>\n"
-       "<head>\n"
-       "<title>Internet Junkbuster: Request for blocked URL</title>\n"
-       "</head>\n"
-       WHITEBG
-       "<center><h1>"
-       BANNER
-       "</h1></center>\n"
-      "<p align=center>Your request for <b>%s%s</b><br>\n"
-      "was blocked because it matches the following pattern "
-      "in the blockfile: <b>%s</b>\n</p>"
-#ifdef FORCE_LOAD
-       "<p align=center><a href=\"http://" FORCE_PREFIX
-        "%s%s\">Go there anyway.</a></p>"
-#endif /* def FORCE_LOAD */
-      "</body>\n"
-      "</html>\n";
-
-#ifdef TRUST_FILES
-static const char CTRUST[] =
-#ifdef AMIGA 
-       "HTTP/1.0 403 Request for untrusted URL\n"
-#else /* ifndef AMIGA */
-       "HTTP/1.0 202 Request for untrusted URL\n"
-#endif /* ndef AMIGA */
-       "Pragma: no-cache\n"
-       "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
-       "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
-       "Content-Type: text/html\n\n"
-       "<html>\n"
-       "<head>\n"
-       "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
-       "</head>\n"
-       WHITEBG
-       "<center>"
-       "<a href=http://internet.junkbuster.com/ij-untrusted-url?%s+%s+%s>"
-       BANNER
-       "</a>"
-       "</center>"
-       "</body>\n"
-       "</html>\n";
-#endif /* def TRUST_FILES */
-
-
-#ifdef ACL_FILES
+#ifdef FEATURE_ACL
 /*********************************************************************
  *
  * Function    :  block_acl
@@ -148,52 +456,51 @@ static const char CTRUST[] =
  *                Decide yes or no based on ACL file.
  *
  * Parameters  :
- *          1  :  src = Address the browser/user agent is requesting.
- *          2  :  dst = The proxy or gateway address this is going to.
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  dst = The proxy or gateway address this is going to.
+ *                      Or NULL to check all possible targets.
+ *          2  :  csp = Current client state (buffers, headers, etc...)
+ *                      Also includes the client IP address.
  *
  * Returns     : 0 = FALSE (don't block) and 1 = TRUE (do block)
  *
  *********************************************************************/
-int block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp)
+int block_acl(struct access_control_addr *dst, struct client_state *csp)
 {
-   struct file_list *fl;
-   struct access_control_list *a, *acl;
-   struct access_control_addr s[1], d[1];
+   struct access_control_list *acl = csp->config->acl;
 
    /* if not using an access control list, then permit the connection */
-   if (((fl = csp->alist) == NULL) || ((acl = fl->f) == NULL))
+   if (acl == NULL)
    {
       return(0);
    }
 
    /* search the list */
-   for (a = acl->next ; a ; a = a->next)
+   while (acl != NULL)
    {
-      *s = *src;
-      *d = *dst;
-
-      s->addr &= a->src->mask;
-      d->addr &= a->dst->mask;
-
-      if ((s->addr  == a->src->addr)
-      && (d->addr  == a->dst->addr)
-      && ((s->port == a->src->port)
-       || (s->port == 0)
-       || (a->src->port == 0))
-      && ((d->port == a->dst->port)
-       || (d->port == 0)
-       || (a->dst->port == 0)))
+      if ((csp->ip_addr_long & acl->src->mask) == acl->src->addr)
       {
-         if (a->action == ACL_PERMIT)
+         if (dst == NULL)
          {
-            return(0);
+            /* Just want to check if they have any access */
+            if (acl->action == ACL_PERMIT)
+            {
+               return(0);
+            }
          }
-         else
+         else if ( ((dst->addr & acl->dst->mask) == acl->dst->addr)
+           && ((dst->port == acl->dst->port) || (acl->dst->port == 0)))
          {
-            return(1);
+            if (acl->action == ACL_PERMIT)
+            {
+               return(0);
+            }
+            else
+            {
+               return(1);
+            }
          }
       }
+      acl = acl->next;
    }
 
    return(1);
@@ -205,11 +512,11 @@ int block_acl(struct access_control_addr *src, struct access_control_addr *dst,
  *
  * Function    :  acl_addr
  *
- * Description :  Called from `load_aclfile'.  FIXME: I can't say more.
+ * Description :  Called from `load_config' to parse an ACL address.
  *
  * Parameters  :
- *          1  :  aspec = (what?)
- *          2  :  aca = (what?)
+ *          1  :  aspec = String specifying ACL address.
+ *          2  :  aca = struct access_control_addr to fill in.
  *
  * Returns     :  0 => Ok, everything else is an error.
  *
@@ -222,7 +529,7 @@ int acl_addr(char *aspec, struct access_control_addr *aca)
    masklength = 32;
    port       =  0;
 
-   if ((p = strchr(aspec, '/')))
+   if ((p = strchr(aspec, '/')) != NULL)
    {
       *p++ = '\0';
 
@@ -238,7 +545,7 @@ int acl_addr(char *aspec, struct access_control_addr *aca)
       return(-1);
    }
 
-   if ((p = strchr(aspec, ':')))
+   if ((p = strchr(aspec, ':')) != NULL)
    {
       *p++ = '\0';
 
@@ -253,9 +560,8 @@ int acl_addr(char *aspec, struct access_control_addr *aca)
 
    aca->addr = ntohl(resolve_hostname_to_ip(aspec));
 
-   if (aca->addr == -1)
+   if (aca->addr == INADDR_NONE)
    {
-      log_error(LOG_LEVEL_ERROR, "can't resolve address for %s", aspec);
       return(-1);
    }
 
@@ -274,1252 +580,1014 @@ int acl_addr(char *aspec, struct access_control_addr *aca)
    return(0);
 
 }
-#endif /* def ACL_FILES */
+#endif /* def FEATURE_ACL */
 
 
 /*********************************************************************
  *
- * Function    :  block_url
+ * Function    :  match_portlist
  *
- * Description :  Called from `chat'.  Check to see if we need to block this.
+ * Description :  Check if a given number is covered by a comma
+ *                separated list of numbers and ranges (a,b-c,d,..)
  *
  * Parameters  :
- *          1  :  http = http_request request to "check" for blocked
- *          2  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  portlist = String with list
+ *          2  :  port = port to check
  *
- * Returns     :  NULL => unblocked, else string to HTML block description.
+ * Returns     :  0 => no match
+ *                1 => match
  *
  *********************************************************************/
-char *block_url(struct http_request *http, struct client_state *csp)
+int match_portlist(const char *portlist, int port)
 {
-   struct file_list *fl;
-   struct block_spec *b;
-   struct url_spec url[1];
-   char *p;
-   int n;
+   char *min, *max, *next, *portlist_copy;
 
-   if (((fl = csp->blist) == NULL) || ((b = fl->f) == NULL))
+   min = next = portlist_copy = strdup(portlist);
+
+   /*
+    * Zero-terminate first item and remember offset for next
+    */
+   if (NULL != (next = strchr(portlist_copy, (int) ',')))
    {
-      return(NULL);
+      *next++ = '\0';
    }
 
-   *url = dsplit(http->host);
-
-   /* if splitting the domain fails, punt */
-   if (url->dbuf == NULL) return(NULL);
-
-   for (b = b->next; b ; b = b->next)
+   /*
+    * Loop through all items, checking for match
+    */
+   while(min)
    {
-      if ((b->url->port == 0) || (b->url->port == http->port))
+      if (NULL == (max = strchr(min, (int) '-')))
       {
-         if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
+         /*
+          * No dash, check for equality
+          */
+         if (port == atoi(min))
          {
-            if ((b->url->path == NULL) ||
-#ifdef REGEX
-               (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
-#else
-               (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
-#endif
-            )
-            {
-               freez(url->dbuf);
-               freez(url->dvec);
-
-               if (b->reject == 0) return(NULL);
-
-               n  = strlen(CBLOCK);
-               n += strlen(http->hostport);
-               n += strlen(http->path);
-               n += strlen(b->url->spec);
-#ifdef FORCE_LOAD
-               n += strlen(http->hostport);
-               n += strlen(http->path);
-#endif /* def FORCE_LOAD */
+            free(portlist_copy);
+            return(1);
+         }
+      }
+      else
+      {
+         /*
+          * This is a range, so check if between min and max,
+          * or, if max was omitted, between min and 65K
+          */
+         *max++ = '\0';
+         if(port >= atoi(min) && port <= (atoi(max) ? atoi(max) : 65535))
+         {
+            free(portlist_copy);
+            return(1);
+         }
 
-               p = (char *)malloc(n);
+      }
 
-#ifdef FORCE_LOAD
-               sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec, http->hostport, http->path);
-#else
-               sprintf(p, CBLOCK, http->hostport, http->path, b->url->spec);
-#endif /* def FORCE_LOAD */
+      /*
+       * Jump to next item
+       */
+      min = next;
 
-               return(p);
-            }
-         }
+      /*
+       * Zero-terminate next item and remember offset for n+1
+       */
+      if ((NULL != next) && (NULL != (next = strchr(next, (int) ','))))
+      {
+         *next++ = '\0';
       }
    }
-   freez(url->dbuf);
-   freez(url->dvec);
-   return(NULL);
+
+   free(portlist_copy);
+   return 0;
 
 }
 
 
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
 /*********************************************************************
  *
- * Function    :  block_imageurl
+ * Function    :  block_url
  *
- * Description :  Given a URL which is blocked, decide whether to 
- *                send the "blocked" image or HTML.
+ * Description :  Called from `chat'.  Check to see if we need to block this.
  *
  * Parameters  :
- *          1  :  http = URL to check.
- *          2  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  True (nonzero) if URL is in image list, false (0)
- *                otherwise
+ * Returns     :  NULL => unblocked, else HTTP block response
  *
  *********************************************************************/
-int block_imageurl(struct http_request *http, struct client_state *csp)
+struct http_response *block_url(struct client_state *csp)
 {
-#ifdef DETECT_MSIE_IMAGES
-   if ((csp->accept_types 
-       & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
-       == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE))
+#ifdef FEATURE_IMAGE_BLOCKING
+   char *p;
+#endif /* def FEATURE_IMAGE_BLOCKING */
+   struct http_response *rsp;
+
+   /*
+    * If it's not blocked, don't block it ;-)
+    */
+   if ((csp->action->flags & ACTION_BLOCK) == 0)
    {
-      return 1;
+      return NULL;
    }
-   else if ((csp->accept_types 
-       & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
-       == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_HTML))
+
+   /*
+    * Else, prepare a response
+    */
+   if (NULL == (rsp = alloc_http_response()))
    {
-      return 0;
+      return cgi_error_memory();
    }
-#endif
 
-#if defined(USE_IMAGE_LIST)
-   return block_imageurl_using_imagelist(http, csp);
-#else
-   /* Don't know - assume HTML */
-   return 0;
-#endif
-}
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
+   /*
+    * If it's an image-url, send back an image or redirect
+    * as specified by the relevant +image action
+    */
+#ifdef FEATURE_IMAGE_BLOCKING
+   if (((csp->action->flags & ACTION_IMAGE_BLOCKER) != 0)
+        && is_imageurl(csp))
+   {
+      /* determine HOW images should be blocked */
+      p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER];
 
+#if 1 /* Two alternative strategies, use this one for now: */
 
-#ifdef USE_IMAGE_LIST
-/*********************************************************************
- *
- * Function    :  block_imageurl
- *
- * Description :  Test if a URL is in the imagelist.
- *
- * Parameters  :
- *          1  :  http = URL to check.
- *          2  :  csp = Current client state (buffers, headers, etc...)
- *
- * Returns     :  True (nonzero) if URL is in image list, false (0)
- *                otherwise
- *
- *********************************************************************/
-int block_imageurl_using_imagelist(struct http_request *http, struct client_state *csp)
-{
-   struct file_list *fl;
-   struct block_spec *b;
-   struct url_spec url[1];
+      /* and handle accordingly: */
+      if ((p == NULL) || (0 == strcmpic(p, "pattern")))
+      {
+         rsp->body = bindup(image_pattern_data, image_pattern_length);
+         if (rsp->body == NULL)
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+         rsp->content_length = image_pattern_length;
 
-   if (((fl = csp->ilist) == NULL) || ((b  = fl->f) == NULL))
-   {
-      return(0);
-   }
+         if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+      }
 
-   *url = dsplit(http->host);
+      else if (0 == strcmpic(p, "blank"))
+      {
+         rsp->body = bindup(image_blank_data, image_blank_length);
+         if (rsp->body == NULL)
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+         rsp->content_length = image_blank_length;
 
-   /* if splitting the domain fails, punt */
-   if (url->dbuf == NULL) return(0);
+         if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+      }
 
-   for (b = b->next; b ; b = b->next)
+      else
+      {
+         rsp->status = strdup("302 Local Redirect from Privoxy");
+         if (rsp->status == NULL)
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+
+         if (enlist_unique_header(rsp->headers, "Location", p))
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+      }
+
+#else /* Following code is disabled for now */
+
+      /* and handle accordingly: */
+      if ((p == NULL) || (0 == strcmpic(p, "pattern")))
+      {
+         p = CGI_PREFIX "send-banner?type=pattern";
+      }
+      else if (0 == strcmpic(p, "blank"))
+      {
+         p = CGI_PREFIX "send-banner?type=blank";
+      }
+      rsp->status = strdup("302 Local Redirect from Privoxy");
+      if (rsp->status == NULL)
+      {
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
+
+      if (enlist_unique_header(rsp->headers, "Location", p))
+      {
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
+#endif /* Preceeding code is disabled for now */
+   }
+   else
+#endif /* def FEATURE_IMAGE_BLOCKING */
+
+   /*
+    * Else, generate an HTML "blocked" message:
+    */
    {
+      jb_err err;
+      struct map * exports;
+
+      /*
+       * Workaround for stupid Netscape bug which prevents
+       * pages from being displayed if loading a referenced
+       * JavaScript or style sheet fails. So make it appear
+       * as if it succeeded.
+       */
+      if ( NULL != (p = get_header_value(csp->headers, "User-Agent:"))
+           && !strncmpic(p, "mozilla", 7) /* Catch Netscape but */
+           && !strstr(p, "Gecko")         /* save Mozilla, */
+           && !strstr(p, "compatible")    /* MSIE */
+           && !strstr(p, "Opera"))        /* and Opera. */
+      {
+         rsp->status = strdup("200 Request for blocked URL");
+      }
+      else
+      {
+         rsp->status = strdup("404 Request for blocked URL");
+      }
 
-      if ((b->url->port == 0) || (b->url->port == http->port))
+      if (rsp->status == NULL)
       {
-         /* port matches, check domain */
-         if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
-         {
-            /* domain matches, check path */
-            if ((b->url->path == NULL) ||
-#ifdef REGEX
-               (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
-#else
-               (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
-#endif
-            )
-            {
-               /* Matches */
-               freez(url->dbuf);
-               freez(url->dvec);
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
 
-               if (b->reject == 0) return(0);
+      exports = default_exports(csp, NULL);
+      if (exports == NULL)
+      {
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
 
-               return(1);
-            }
-         }
+#ifdef FEATURE_FORCE_LOAD
+      err = map(exports, "force-prefix", 1, FORCE_PREFIX, 1);
+      if (csp->http->ssl != 0)
+#endif /* ndef FEATURE_FORCE_LOAD */
+      {
+         err = map_block_killer(exports, "force-support");
+      }
+
+      if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1);
+      if (!err) err = map(exports, "hostport", 1, html_encode(csp->http->hostport), 0);
+      if (!err) err = map(exports, "path", 1, html_encode(csp->http->path), 0);
+
+      if (err)
+      {
+         free_map(exports);
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
+
+      err = template_fill_for_cgi(csp, "blocked", exports, rsp);
+      if (err)
+      {
+         free_http_response(rsp);
+         return cgi_error_memory();
       }
    }
-   freez(url->dbuf);
-   freez(url->dvec);
-   return(0);
+
+   return finish_http_response(rsp);
 
 }
-#endif /* def USE_IMAGE_LIST */
 
 
-#ifdef PCRS
+#ifdef FEATURE_TRUST
 /*********************************************************************
  *
- * Function    :  re_process_buffer
+ * Function    :  trust_url FIXME: I should be called distrust_url
  *
- * Description :  Apply all jobs from the joblist (aka. Perl regexp's) to
- *                the text buffer that's been accumulated in csp->iob->buf.
- *                Then, write the modified buffer out to the client
- *                (Maybe this should happen from jcc.c via flush_socket
- *                for better readability).
+ * Description :  Calls is_untrusted_url to determine if the URL is trusted
+ *                and if not, returns a HTTP 304 response with a reject message.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  N/A
+ * Returns     :  NULL => trusted, else http_response.
  *
  *********************************************************************/
-void re_process_buffer(struct client_state *csp)
+struct http_response *trust_url(struct client_state *csp)
 {
-   int hits=0;
-   int size = csp->iob->eod - csp->iob->cur;
-   char *old=csp->iob->cur, *new = NULL;
-   pcrs_job *job, *joblist;
+   struct http_response *rsp;
+   struct map * exports;
+   char buf[BUFFER_SIZE];
+   char *p;
+   struct url_spec **tl;
+   struct url_spec *t;
+   jb_err err;
 
-   struct file_list *fl;
-   struct re_filterfile_spec *b;
+   /*
+    * Don't bother to work on trusted URLs
+    */
+   if (!is_untrusted_url(csp))
+   {
+      return NULL;
+   }
 
-   /* Sanity first ;-) */
-   if (size <= 0) return;
+   /*
+    * Else, prepare a response:
+    */
+   if (NULL == (rsp = alloc_http_response()))
+   {
+      return cgi_error_memory();
+   }
 
-   if ( ( NULL == (fl = csp->rlist) ) || ( NULL == (b = fl->f) ) )
+   exports = default_exports(csp, NULL);
+   if (exports == NULL)
    {
-      log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
-      return;
+      free_http_response(rsp);
+      return cgi_error_memory();
    }
 
-   joblist = b->joblist;
+   /*
+    * Export the protocol, host, port, and referrer information
+    */
+   err = map(exports, "hostport", 1, csp->http->hostport, 1);
+   if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); 
+   if (!err) err = map(exports, "path", 1, csp->http->path, 1);
+
+   if (NULL != (p = get_header_value(csp->headers, "Referer:")))
+   {
+      if (!err) err = map(exports, "referrer", 1, html_encode(p), 0);
+   }
+   else
+   {
+      if (!err) err = map(exports, "referrer", 1, "unknown", 1);
+   }
 
+   if (err)
+   {
+      free_map(exports);
+      free_http_response(rsp);
+      return cgi_error_memory();
+   }
 
-   log_error(LOG_LEVEL_REF, "re_filtering %s%s (size %d) ...",
-              csp->http->hostport, csp->http->path, size);
+   /*
+    * Export the trust list
+    */
+   p = strdup("");
+   for (tl = csp->config->trust_list; (t = *tl) != NULL ; tl++)
+   {
+      sprintf(buf, "<li>%s</li>\n", t->spec);
+      string_append(&p, buf);
+   }
+   err = map(exports, "trusted-referrers", 1, p, 0);
 
-   /* Apply all jobs from the joblist */
-   for (job = joblist; NULL != job; job = job->next)
+   if (err)
    {
-      hits += pcrs_exec_substitution(job, old, size, &new, &size);
-      if (old != csp->iob->cur) free(old);
-      old=new;
+      free_map(exports);
+      free_http_response(rsp);
+      return cgi_error_memory();
    }
 
-   log_error(LOG_LEVEL_REF, " produced %d hits (new size %d).", hits, size);
+   /*
+    * Export the trust info, if available
+    */
+   if (csp->config->trust_info->first)
+   {
+      struct list_entry *l;
 
-   if (write_socket(csp->cfd, old, size) != size)
+      p = strdup("");
+      for (l = csp->config->trust_info->first; l ; l = l->next)
+      {
+         sprintf(buf, "<li> <a href=\"%s\">%s</a><br>\n",l->str, l->str);
+         string_append(&p, buf);
+      }
+      err = map(exports, "trust-info", 1, p, 0);
+   }
+   else
    {
-      log_error(LOG_LEVEL_ERROR, "write to client failed.");
+      err = map_block_killer(exports, "have-trust-info");
    }
 
-   /* fwiw, reset the iob */
-   IOB_RESET(csp);
-   freez(new);
-   return;
+   if (err)
+   {
+      free_map(exports);
+      free_http_response(rsp);
+      return cgi_error_memory();
+   }
+
+   /*
+    * Export the force prefix or the force conditional block killer
+    */
+#ifdef FEATURE_FORCE_LOAD
+   err = map(exports, "force-prefix", 1, FORCE_PREFIX, 1);
+#else /* ifndef FEATURE_FORCE_LOAD */
+   err = map_block_killer(exports, "force-support");
+#endif /* ndef FEATURE_FORCE_LOAD */
+
+   if (err)
+   {
+      free_map(exports);
+      free_http_response(rsp);
+      return cgi_error_memory();
+   }
+
+   /*
+    * Build the response
+    */
+   err = template_fill_for_cgi(csp, "untrusted", exports, rsp);
+   if (err)
+   {
+      free_http_response(rsp);
+      return cgi_error_memory();
+   }
 
+   return finish_http_response(rsp);
 }
-#endif /* def PCRS */
+#endif /* def FEATURE_TRUST */
 
 
-#ifdef TRUST_FILES
+#ifdef FEATURE_FAST_REDIRECTS
 /*********************************************************************
  *
- * Function    :  trust_url
+ * Function    :  redirect_url
  *
- * Description :  Should we "trust" this URL?  See "trustfile" line in config.
+ * Description :  Checks for redirection URLs and returns a HTTP redirect
+ *                to the destination URL, if necessary
  *
  * Parameters  :
- *          1  :  http = http_request request for requested URL
- *          2  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  NULL => trusted, else string to HTML "untrusted" description.
+ * Returns     :  NULL if URL was clean, HTTP redirect otherwise.
  *
  *********************************************************************/
-char *trust_url(struct http_request *http, struct client_state *csp)
+struct http_response *redirect_url(struct client_state *csp)
 {
-   struct file_list *fl;
-   struct block_spec *b;
-   struct url_spec url[1], **tl, *t;
-   char *p, *h;
-   char *hostport, *path, *refer;
-   struct http_request rhttp[1];
-   int n;
+   char *p, *q;
+   struct http_response *rsp;
 
-   if (((fl = csp->tlist) == NULL) || ((b  = fl->f) == NULL))
+   p = q = csp->http->path;
+   log_error(LOG_LEVEL_REDIRECTS, "checking path for redirects: %s", p);
+
+   /*
+    * find the last URL encoded in the request
+    */
+   while ((p = strstr(p, "http://")) != NULL)
    {
-      return(NULL);
+      q = p++;
    }
 
-   *url = dsplit(http->host);
-
-   /* if splitting the domain fails, punt */
-   if (url->dbuf == NULL) return(NULL);
+   /*
+    * if there was any, generate and return a HTTP redirect
+    */
+   if (q != csp->http->path)
+   {
+      log_error(LOG_LEVEL_REDIRECTS, "redirecting to: %s", q);
 
-   memset(rhttp, '\0', sizeof(*rhttp));
+      if (NULL == (rsp = alloc_http_response()))
+      {
+         return cgi_error_memory();
+      }
 
-   for (b = b->next; b ; b = b->next)
-   {
-      if ((b->url->port == 0) || (b->url->port == http->port))
+      if ( enlist_unique_header(rsp->headers, "Location", q)
+        || (NULL == (rsp->status = strdup("302 Local Redirect from Privoxy"))) )
       {
-         if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
-         {
-            if ((b->url->path == NULL) ||
-#ifdef REGEX
-               (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
-#else
-               (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
-#endif
-            )
-            {
-               freez(url->dbuf);
-               freez(url->dvec);
-
-               if (b->reject == 0) return(NULL);
-
-               hostport = url_encode(http->hostport);
-               path     = url_encode(http->path);
-
-               if (csp->referrer)
-               {
-                  refer = url_encode(csp->referrer);
-               }
-               else
-               {
-                  refer = url_encode("undefined");
-               }
-
-               n  = strlen(CTRUST);
-               n += strlen(hostport);
-               n += strlen(path);
-               n += strlen(refer);
-
-               p = (char *)malloc(n);
-
-               sprintf(p, CTRUST, hostport, path, refer);
-
-               freez(hostport);
-               freez(path);
-               freez(refer);
-
-               return(p);
-            }
-         }
+         free_http_response(rsp);
+         return cgi_error_memory();
       }
-   }
-
-   freez(url->dbuf);
-   freez(url->dvec);
-
-   if ((csp->referrer == NULL)|| (strlen(csp->referrer) <= 9))
-   {
-      /* no referrer was supplied */
-      goto trust_url_not_trusted;
-   }
-
-   /* forge a URL from the referrer so we can use
-    * convert_url() to parse it into its components.
-    */
 
-   p = NULL;
-   p = strsav(p, "GET ");
-   p = strsav(p, csp->referrer + 9);   /* skip over "Referer: " */
-   p = strsav(p, " HTTP/1.0");
-
-   parse_http_request(p, rhttp, csp);
-
-   if (rhttp->cmd == NULL)
-   {
-      freez(p);
-      goto trust_url_not_trusted;
-   }
-
-   freez(p);
-
-   *url = dsplit(rhttp->host);
-
-   /* if splitting the domain fails, punt */
-   if (url->dbuf == NULL) goto trust_url_not_trusted;
-
-   for (tl = trust_list; (t = *tl) ; tl++)
-   {
-      if ((t->port == 0) || (t->port == rhttp->port))
-      {
-         if ((t->domain[0] == '\0') || domaincmp(t, url) == 0)
-         {
-            if ((t->path == NULL) ||
-#ifdef REGEX
-               (regexec(t->preg, rhttp->path, 0, NULL, 0) == 0)
-#else
-               (strncmp(t->path, rhttp->path, t->pathlen) == 0)
-#endif
-            )
-            {
-               /* if the URL's referrer is from a trusted referrer, then
-                * add the target spec to the trustfile as an unblocked
-                * domain and return NULL (which means it's OK).
-                */
-
-               FILE *fp;
-
-               freez(url->dbuf);
-               freez(url->dvec);
-
-               if ((fp = fopen(trustfile, "a")))
-               {
-                  h = NULL;
-
-                  h = strsav(h, "~");
-                  h = strsav(h, http->hostport);
-
-                  p = http->path;
-                  if ((*p++ == '/')
-                  && (*p++ == '~'))
-                  {
-                  /* since this path points into a user's home space
-                   * be sure to include this spec in the trustfile.
-                   */
-                     if ((p = strchr(p, '/')))
-                     {
-                        *p = '\0';
-                        h = strsav(h, http->path);
-                        h = strsav(h, "/");
-                     }
-                  }
-
-                  free_http_request(rhttp);
-
-                  fprintf(fp, "%s\n", h);
-                  freez(h);
-                  fclose(fp);
-               }
-               return(NULL);
-            }
-         }
-      }
-   }
-
-trust_url_not_trusted:
-   free_http_request(rhttp);
-
-   hostport = url_encode(http->hostport);
-   path     = url_encode(http->path);
-
-   if (csp->referrer)
-   {
-      refer = url_encode(csp->referrer);
+      return finish_http_response(rsp);
    }
    else
    {
-      refer = url_encode("undefined");
+      return NULL;
    }
 
-   n  = strlen(CTRUST);
-   n += strlen(hostport);
-   n += strlen(path);
-   n += strlen(refer);
-
-   p = (char *)malloc(n);
-   sprintf(p, CTRUST, hostport, path, refer);
-
-   freez(hostport);
-   freez(path);
-   freez(refer);
-
-   return(p);
-
 }
-#endif /* def TRUST_FILES */
+#endif /* def FEATURE_FAST_REDIRECTS */
 
 
+#ifdef FEATURE_IMAGE_BLOCKING
 /*********************************************************************
  *
- * Function    :  intercept_url
+ * Function    :  is_imageurl
  *
- * Description :  checks the URL `basename' against a list of URLs to
- *                snarf. If it matches, it calls the associated function
- *                which returns an HTML page to send back to the client.
- *                Right now, we snarf:
- *                      "show-proxy-args", and
- *                      "ij-untrusted-url" (optional w/TRUST_FILES)
+ * Description :  Given a URL, decide whether it is an image or not,
+ *                using either the info from a previous +image action
+ *                or, #ifdef FEATURE_IMAGE_DETECT_MSIE, the info from
+ *                the browser's accept header.
  *
  * Parameters  :
- *          1  :  http = http_request request, check `basename's of blocklist
- *          2  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  NULL for no recognized URLs, or an HTML description page.
+ * Returns     :  True (nonzero) if URL is an image, false (0)
+ *                otherwise
  *
  *********************************************************************/
-char *intercept_url(struct http_request *http, struct client_state *csp)
+int is_imageurl(struct client_state *csp)
 {
-   char *basename;
-   const struct interceptors *v;
-
-   basename = strrchr(http->path, '/');
-
-   if (basename == NULL) return(NULL);
+#ifdef FEATURE_IMAGE_DETECT_MSIE
+   char *tmp;
 
-   basename ++; /* first char past the last slash */
-
-   if (*basename)
+   tmp = get_header_value(csp->headers, "User-Agent:");
+   if (tmp && strstr(tmp, "MSIE"))
    {
-      for (v = intercept_patterns; v->str; v++)
+      tmp = get_header_value(csp->headers, "Accept:");
+      if (tmp && strstr(tmp, "image/gif"))
       {
-         if (strncmp(basename, v->str, v->len) == 0)
-         {
-            return((v->interceptor)(http, csp));
-         }
+         /* Client will accept HTML.  If this seems counterintuitive,
+          * blame Microsoft.
+          */
+         return(0);
+      }
+      else
+      {
+         return(1);
       }
    }
+#endif /* def FEATURE_IMAGE_DETECT_MSIE */
 
-   return(NULL);
+   return ((csp->action->flags & ACTION_IMAGE) != 0);
 
 }
+#endif /* def FEATURE_IMAGE_BLOCKING */
 
 
+#ifdef FEATURE_TRUST
 /*********************************************************************
  *
- * Function    :  cookie_url
+ * Function    :  is_untrusted_url
+ *
+ * Description :  Should we "distrust" this URL (and block it)?
  *
- * Description :  Accept this cookie, or no?  See "cookiefile" setting.
+ *                Yes if it matches a line in the trustfile, or if the
+ *                    referrer matches a line starting with "+" in the
+ *                    trustfile.
+ *                No  otherwise.
  *
  * Parameters  :
- *          1  :  http = http_request request for blocked URLs
- *          2  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  NULL => accept, cookie_spec pointer to crunch.
+ * Returns     :  0 => trusted, 1 => untrusted
  *
  *********************************************************************/
-struct cookie_spec *cookie_url(struct http_request *http, struct client_state *csp)
+int is_untrusted_url(struct client_state *csp)
 {
    struct file_list *fl;
-   struct cookie_spec *b;
-   struct url_spec url[1];
+   struct block_spec *b;
+   struct url_spec **trusted_url;
+   struct http_request rhttp[1];
+   const char * referer;
+   jb_err err;
 
-   if (((fl = csp->clist) == NULL) || ((b = fl->f) == NULL))
+   /*
+    * If we don't have a trustlist, we trust everybody
+    */
+   if (((fl = csp->tlist) == NULL) || ((b  = fl->f) == NULL))
    {
-      return(NULL);
+      return 0;
    }
 
-   *url = dsplit(http->host);
+   memset(rhttp, '\0', sizeof(*rhttp));
 
-   /* if splitting the domain fails, punt */
-   if (url->dbuf == NULL) return(NULL);
+   /*
+    * Do we trust the request URL itself?
+    */
+   for (b = b->next; b ; b = b->next)
+   {
+      if (url_match(b->url, csp->http))
+      {
+         return b->reject;
+      }
+   }
 
-   for (b = b->next; NULL != b; b = b->next)
+   if (NULL == (referer = get_header_value(csp->headers, "Referer:")))
+   {
+      /* no referrer was supplied */
+      return 1;
+   }
+
+
+   /*
+    * If not, do we maybe trust its referrer?
+    */
+   err = parse_http_url(referer, rhttp, csp);
+   if (err)
+   {
+      return 1;
+   }
+
+   for (trusted_url = csp->config->trust_list; *trusted_url != NULL; trusted_url++)
    {
-      if ((b->url->port == 0) || (b->url->port == http->port))
+      if (url_match(*trusted_url, rhttp))
       {
-         if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
+         /* if the URL's referrer is from a trusted referrer, then
+          * add the target spec to the trustfile as an unblocked
+          * domain and return NULL (which means it's OK).
+          */
+
+         FILE *fp;
+
+         if (NULL != (fp = fopen(csp->config->trustfile, "a")))
          {
-            if ((b->url->path == NULL) ||
-#ifdef REGEX
-               (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
-#else
-               (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
-#endif
-            )
+            char * path;
+            char * path_end;
+            char * new_entry = strdup("~");
+
+            string_append(&new_entry, csp->http->hostport);
+
+            path = csp->http->path;
+            if ( (path[0] == '/')
+              && (path[1] == '~')
+              && ((path_end = strchr(path + 2, '/')) != NULL))
+            {
+               /* since this path points into a user's home space
+                * be sure to include this spec in the trustfile.
+                */
+               int path_len = path_end - path; /* save offset */
+               path = strdup(path); /* Copy string */
+               if (path != NULL)
+               {
+                  path_end = path + path_len; /* regenerate ptr to new buffer */
+                  *(path_end + 1) = '\0'; /* Truncate path after '/' */
+               }
+               string_join(&new_entry, path);
+            }
+
+            if (new_entry != NULL)
+            {
+               fprintf(fp, "%s\n", new_entry);
+               free(new_entry);
+            }
+            else
             {
-               freez(url->dbuf);
-               freez(url->dvec);
-               return(b);
+               /* FIXME: No way to handle out-of memory, so mostly ignoring it */
+               log_error(LOG_LEVEL_ERROR, "Out of memory adding pattern to trust file");
             }
+
+            fclose(fp);
          }
+         return 0;
       }
    }
-
-   freez(url->dbuf);
-   freez(url->dvec);
-   return(NULL);
-
+   return 1;
 }
+#endif /* def FEATURE_TRUST */
 
 
 /*********************************************************************
  *
- * Function    :  forward_url
+ * Function    :  pcrs_filter_response
  *
- * Description :  Should we forward this to another proxy?
+ * Description :  Ecexute all text substitutions from all applying
+ *                +filter actions on the text buffer that's been accumulated
+ *                in csp->iob->buf. If this changes the contents, set
+ *                csp->content_length to the modified size and raise the
+ *                CSP_FLAG_MODIFIED flag.
  *
  * Parameters  :
- *          1  :  http = http_request request for current URL
- *          2  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  Return gw_default for no forward match,
- *                else a gateway pointer to a specific forwarding proxy.
+ * Returns     :  a pointer to the (newly allocated) modified buffer.
+ *                or NULL if there were no hits or something went wrong
  *
  *********************************************************************/
-const struct gateway *forward_url(struct http_request *http, struct client_state *csp)
+char *pcrs_filter_response(struct client_state *csp)
 {
+   int hits=0;
+   size_t size;
+
+   char *old = csp->iob->cur, *new = NULL;
+   pcrs_job *job;
+
    struct file_list *fl;
-   struct forward_spec *b;
-   struct url_spec url[1];
+   struct re_filterfile_spec *b;
+   struct list_entry *filtername;
 
-   if (((fl = csp->flist) == NULL) || ((b = fl->f) == NULL))
+   /* 
+    * Sanity first
+    */
+   if (csp->iob->cur >= csp->iob->eod)
    {
-      return(gw_default);
+      return(NULL);
    }
+   size = csp->iob->eod - csp->iob->cur;
 
-   *url = dsplit(http->host);
+   if ( ( NULL == (fl = csp->rlist) ) || ( NULL == fl->f) )
+   {
+      log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
+      return(NULL);
+   }
 
-   /* if splitting the domain fails, punt */
-   if (url->dbuf == NULL) return(gw_default);
+   /*
+    * If the body has a "chunked" transfer-encoding,
+    * get rid of it first, adjusting size and iob->eod
+    */
+   if (csp->flags & CSP_FLAG_CHUNKED)
+   {
+      log_error(LOG_LEVEL_RE_FILTER, "Need to de-chunk first");
+      if (0 == (size = remove_chunked_transfer_coding(csp->iob->cur, size)))
+      {
+         return(NULL);
+      }
+      csp->iob->eod = csp->iob->cur + size;
+      csp->flags |= CSP_FLAG_MODIFIED;
+   }
 
-   for (b = b->next; b ; b = b->next)
+   /*
+    * For all applying +filter actions, look if a filter by that
+    * name exists and if yes, execute it's pcrs_joblist on the
+    * buffer.
+    */
+   for (b = fl->f; b; b = b->next)
    {
-      if ((b->url->port == 0) || (b->url->port == http->port))
+      for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first;
+           filtername ; filtername = filtername->next)
       {
-         if ((b->url->domain[0] == '\0') || (domaincmp(b->url, url) == 0))
+         if (strcmp(b->name, filtername->str) == 0)
          {
-            if ((b->url->path == NULL) ||
-#ifdef REGEX
-               (regexec(b->url->preg, http->path, 0, NULL, 0) == 0)
-#else
-               (strncmp(b->url->path, http->path, b->url->pathlen) == 0)
-#endif
-            )
+            int current_hits = 0;
+
+            if ( NULL == b->joblist )
             {
-               freez(url->dbuf);
-               freez(url->dvec);
-               return(b->gw);
+               log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name);
+               return(NULL);
             }
+
+            log_error(LOG_LEVEL_RE_FILTER, "re_filtering %s%s (size %d) with filter %s...",
+                      csp->http->hostport, csp->http->path, size, b->name);
+
+            /* Apply all jobs from the joblist */
+            for (job = b->joblist; NULL != job; job = job->next)
+            {
+               current_hits += pcrs_execute(job, old, size, &new, &size);
+               if (old != csp->iob->cur) free(old);
+               old=new;
+            }
+
+            log_error(LOG_LEVEL_RE_FILTER, " ...produced %d hits (new size %d).", current_hits, size);
+            hits += current_hits;
          }
       }
    }
 
-   freez(url->dbuf);
-   freez(url->dvec);
-   return(gw_default);
+   /*
+    * If there were no hits, destroy our copy and let
+    * chat() use the original in csp->iob
+    */
+   if (!hits)
+   {
+      free(new);
+      return(NULL);
+   }
+
+   csp->flags |= CSP_FLAG_MODIFIED;
+   csp->content_length = size;
+   IOB_RESET(csp);
+
+   return(new);
 
 }
 
 
 /*********************************************************************
  *
- * Function    :  dsplit
+ * Function    :  gif_deanimate_response
  *
- * Description :  Takes a domain and returns a pointer to a url_spec
- *                structure populated with dbuf, dcnt and dvec.  The
- *                other fields in the structure that is returned are zero.
+ * Description :  Deanimate the GIF image that has been accumulated in
+ *                csp->iob->buf, set csp->content_length to the modified
+ *                size and raise the CSP_FLAG_MODIFIED flag.
  *
  * Parameters  :
- *          1  :  domain = a URL address
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  url_spec structure populated with dbuf, dcnt and dvec.
+ * Returns     :  a pointer to the (newly allocated) modified buffer.
+ *                or NULL in case something went wrong.
  *
  *********************************************************************/
-struct url_spec dsplit(char *domain)
+char *gif_deanimate_response(struct client_state *csp)
 {
-   struct url_spec ret[1];
-   char *v[BUFSIZ];
-   int size;
+   struct binbuffer *in, *out;
    char *p;
+   size_t size = csp->iob->eod - csp->iob->cur;
 
-   memset(ret, '\0', sizeof(*ret));
-
-   if ((p = strrchr(domain, '.')))
+   /*
+    * If the body has a "chunked" transfer-encoding,
+    * get rid of it first, adjusting size and iob->eod
+    */
+   if (csp->flags & CSP_FLAG_CHUNKED)
    {
-      if (*(++p) == '\0')
+      log_error(LOG_LEVEL_DEANIMATE, "Need to de-chunk first");
+      if (0 == (size = remove_chunked_transfer_coding(csp->iob->cur, size)))
       {
-         ret->toplevel = 1;
+         return(NULL);
       }
+      csp->iob->eod = csp->iob->cur + size;
+      csp->flags |= CSP_FLAG_MODIFIED;
    }
 
-   ret->dbuf = strdup(domain);
-
-   /* map to lower case */
-   for (p = ret->dbuf; *p ; p++) *p = tolower(*p);
-
-   /* split the domain name into components */
-   ret->dcnt = ssplit(ret->dbuf, ".", v, SZ(v), 1, 1);
-
-   if (ret->dcnt <= 0)
+   if (  (NULL == (in =  (struct binbuffer *)zalloc(sizeof *in )))
+      || (NULL == (out = (struct binbuffer *)zalloc(sizeof *out))) )
    {
-      memset(ret, '\0', sizeof(ret));
-      return(*ret);
+      log_error(LOG_LEVEL_DEANIMATE, "failed! (no mem)");
+      return NULL;
    }
 
-   /* save a copy of the pointers in dvec */
-   size = ret->dcnt * sizeof(*ret->dvec);
+   in->buffer = csp->iob->cur;
+   in->size = size;
 
-   if ((ret->dvec = (char **)malloc(size)))
+   if (gif_deanimate(in, out, strncmp("last", csp->action->string[ACTION_STRING_DEANIMATE], 4)))
    {
-      memcpy(ret->dvec, v, size);
+      log_error(LOG_LEVEL_DEANIMATE, "failed! (gif parsing)");
+      free(in);
+      buf_free(out);
+      return(NULL);
+   }
+   else
+   {
+      if ((int)size == out->offset)
+      {
+         log_error(LOG_LEVEL_DEANIMATE, "GIF not changed.");
+      }
+      else
+      {
+         log_error(LOG_LEVEL_DEANIMATE, "Success! GIF shrunk from %d bytes to %d.", size, out->offset);
+      }
+      csp->content_length = out->offset;
+      csp->flags |= CSP_FLAG_MODIFIED;
+      p = out->buffer;
+      free(in);
+      free(out);
+      return(p);
    }
-
-   return(*ret);
 
 }
 
 
 /*********************************************************************
  *
- * Function    :  domaincmp
+ * Function    :  remove_chunked_transfer_coding
  *
- * Description :  Compare domain names.
- *                domaincmp("a.b.c" , "a.b.c")  => 0 (MATCH)
- *                domaincmp("a*.b.c", "a.b.c")  => 0 (MATCH)
- *                domaincmp("b.c"   , "a.b.c")  => 0 (MATCH)
- *                domaincmp(""      , "a.b.c")  => 0 (MATCH)
+ * Description :  In-situ remove the "chunked" transfer coding as defined
+ *                in rfc2616 from a buffer.
  *
  * Parameters  :
- *          1  :  pattern = a domain that may contain a '*' as a wildcard.
- *          2  :  fqdn = domain name against which the patterns are compared.
+ *          1  :  buffer = Pointer to the text buffer
+ *          2  :  size = Number of bytes to be processed
  *
- * Returns     :  0 => domains are equivalent, else no match.
+ * Returns     :  The new size, i.e. the number of bytes from buffer which
+ *                are occupied by the stripped body, or 0 in case something
+ *                went wrong
  *
  *********************************************************************/
-int domaincmp(struct url_spec *pattern, struct url_spec *fqdn)
+int remove_chunked_transfer_coding(char *buffer, const size_t size)
 {
-   char **pv, **fv;  /* vectors  */
-   int    pn,   fn;  /* counters */
-   char  *p,   *f;   /* chars    */
+   size_t newsize = 0;
+   unsigned int chunksize = 0;
+   char *from_p, *to_p;
 
-   pv = pattern->dvec;
-   pn = pattern->dcnt;
+   assert(buffer);
+   from_p = to_p = buffer;
 
-   fv = fqdn->dvec;
-   fn = fqdn->dcnt;
-
-   while ((pn > 0) && (fn > 0))
+   if (sscanf(buffer, "%x", &chunksize) != 1)
    {
-      p = pv[--pn];
-      f = fv[--fn];
+      log_error(LOG_LEVEL_ERROR, "Invalid first chunksize while stripping \"chunked\" transfer coding");
+      return(0);
+   }
 
-      while (*p && *f && (*p == tolower(*f)))
+   while (chunksize > 0)
+   {
+      if (NULL == (from_p = strstr(from_p, "\r\n")))
       {
-         p++, f++;
+         log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding");
+         return(0);
       }
+      newsize += chunksize;
+      from_p += 2;
 
-      if ((*p != tolower(*f)) && (*p != '*')) return(1);
-   }
+      memmove(to_p, from_p, (size_t) chunksize);
+      to_p = buffer + newsize;
+      from_p += chunksize + 2;
 
-   if (pn > 0) return(1);
+      if (sscanf(from_p, "%x", &chunksize) != 1)
+      {
+         log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding");
+         return(0);
+      }
+   }
 
-   return(0);
+   /* FIXME: Should this get its own loglevel? */
+   log_error(LOG_LEVEL_RE_FILTER, "De-chunking successful. Shrunk from %d to %d\n", size, newsize);
+   return(newsize);
 
 }
 
 
-/* intercept functions */
-
 /*********************************************************************
  *
- * Function    :  show_proxy_args
+ * Function    :  url_actions
  *
- * Description :  This "crunch"es "http:/any.thing/show-proxy-args" and
- *                returns a web page describing the current status of IJB.
+ * Description :  Gets the actions for this URL.
  *
  * Parameters  :
- *          1  :  http = ignored
+ *          1  :  http = http_request request for blocked URLs
  *          2  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  A string that contains the current status of IJB.
+ * Returns     :  N/A
  *
  *********************************************************************/
-char *show_proxy_args(struct http_request *http, struct client_state *csp)
+void url_actions(struct http_request *http,
+                 struct client_state *csp)
 {
-   char *s = NULL;
-
-#ifdef SPLIT_PROXY_ARGS
-   FILE * fp;
-   char buf[BUFSIZ];
-   char * p;
-   const char * filename = NULL;
-   const char * file_description = NULL;
-   char * query_string = strrchr(http->path, '?');
-   char which_file = '\0';
-
-
-   if (query_string != NULL)
-   {
-      /* first char past the last '?' (maybe '\0')*/
-      which_file = query_string[1];
-   }
-   switch (which_file)
-   {
-   case 'b':
-      if (csp->blist)
-      {
-         filename = csp->blist->filename;
-         file_description = "Block List";
-      }
-      break;
-   case 'c':
-      if (csp->clist)
-      {
-         filename = csp->clist->filename;
-         file_description = "Cookie List";
-      }
-      break;
-   case 'f':
-      if (csp->flist)
-      {
-         filename = csp->flist->filename;
-         file_description = "Forward List";
-      }
-      break;
-
-#ifdef ACL_FILES
-   case 'a':
-      if (csp->alist)
-      {
-         filename = csp->alist->filename;
-         file_description = "Access Control List";
-      }
-      break;
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-   case 'i':
-      if (csp->ilist)
-      {
-         filename = csp->ilist->filename;
-         file_description = "Image List";
-      }
-      break;
-#endif /* def USE_IMAGE_LIST */
-
-#ifdef KILLPOPUPS
-   case 'p':
-      if (csp->plist)
-      {
-         filename = csp->plist->filename;
-         file_description = "Popup list";
-      }
-      break;
-#endif /* def KILLPOPUPS */
-
-#ifdef PCRS
-   case 'r':
-      if (csp->rlist)
-      {
-         filename = csp->rlist->filename;
-         file_description = "RE Filter List";
-      }
-      break;
-#endif /* def PCRS */
+   struct file_list *fl;
+   struct url_actions *b;
+   int i;
 
-#ifdef TRUST_FILES
-   case 't':
-      if (csp->tlist)
-      {
-         filename = csp->tlist->filename;
-         file_description = "Trust List";
-      }
-      break;
-#endif /* def TRUST_FILES */
-   }
+   init_current_action(csp->action);
 
-   if (filename)
+   for (i = 0; i < MAX_ACTION_FILES; i++)
    {
-      /* Display specified file */
-      /* FIXME: Add HTTP headers so this isn't cached */
-      s = strsav(s,
-         "HTTP/1.0 200 OK\n"
-         "Server: IJ/" VERSION "\n"
-         "Content-type: text/html\n"
-         "Pragma: no-cache\n"
-         "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
-         "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
-         "\n"
-
-         "<html>"
-         "<head>"
-         "<title>Internet Junkbuster Proxy Status - ");
-      s = strsav(s, file_description);
-      s = strsav(s, 
-         "</title>"
-         "</head>\n"
-         "<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
-         "<center>\n"
-         "<h1>" BANNER "\n");
-      s = strsav(s, file_description);
-      s = strsav(s, 
-         "</h1></center>\n"
-         "<p><a href=\"show-proxy-args\">Back to proxy status</a></p>\n"
-         "<h2>");
-      s = strsav(s, file_description);
-      s = strsav(s,
-         "</h2>\n"
-         "Contents of file &quot;<code>");
-      p = html_encode(filename);
-      s = strsav(s, p);
-      freez(p);
-      s = strsav(s,
-         "</code>&quot;:<br>\n"
-         "</p>\n"
-         "<pre>");
-      
-      if ((fp = fopen(filename, "r")) == NULL)
+      if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL))
       {
-         s = strsav(s, "</pre><h1>ERROR OPENING FILE!</h1><pre>");
+         return;
       }
-      else
-      {
-         while (fgets(buf, sizeof(buf), fp))
-         {
-            p = html_encode(buf);
-            if (p)
-            {
-               s = strsav(s, p);
-               freez(p);
-               s = strsav(s, "<br>");
-            }
-         }
-         fclose(fp);
-      }
-
-      s = strsav(s,
-         "</pre>\n"
-         "<br>\n"
-         "<p><a href=\"show-proxy-args\">Back to proxy status</a></p>\n"
-         "<br>\n"
-         "<small><small><p>\n"
-         "Code and documentation of the " BANNER " Proxy"
-         "<sup><small>TM</small></sup>\n"
-         "<a href=\"http://www.junkbusters.com/ht/en/legal.html#copy\">\n" "Copyright</a>&#169; 1997 Junkbusters Corporation\n"
-         "<a href=\"http://www.junkbusters.com/ht/en/legal.html#marks\"><sup><small>TM</small></sup></a><br>\n"
-         "Copying and distribution permitted under the"
-         "<a href=\"http://www.gnu.org/copyleft/gpl.html\">\n"
-         "<small>GNU</small></a> "
-         "General Public License.\n"
-         "</small>"
-         "<address><kbd>webmaster@junkbusters.com</kbd></address>"
-         "</small>"
-         "</body></html>\n");
-      return(s);
-   }
-#endif /* def SPLIT_PROXY_ARGS */
-   
-   s = strsav(s, proxy_args->header);
-   s = strsav(s, proxy_args->invocation);
-#ifdef STATISTICS
-   s = add_stats(s);
-#endif /* def STATISTICS */
-   s = strsav(s, proxy_args->gateways);
-
-#ifdef SPLIT_PROXY_ARGS
-   s = strsav(s, 
-      "<h2>The following files are in use:</h2>\n"
-      "<p>(Click a filename to view it)</p>\n"
-      "<ul>\n");
-
-   if (csp->blist)
-   {
-      s = strsav(s, "<li>Block List: <a href=\"show-proxy-args?block\"><code>");
-      s = strsav(s, csp->blist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-
-   if (csp->clist)
-   {
-      s = strsav(s, "<li>Cookie List: <a href=\"show-proxy-args?cookie\"><code>");
-      s = strsav(s, csp->clist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-
-   if (csp->flist)
-   {
-      s = strsav(s, "<li>Forward List: <a href=\"show-proxy-args?forward\"><code>");
-      s = strsav(s, csp->flist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-
-#ifdef ACL_FILES
-   if (csp->alist)
-   {
-      s = strsav(s, "<li>Access Control List: <a href=\"show-proxy-args?acl\"><code>");
-      s = strsav(s, csp->alist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-   if (csp->ilist)
-   {
-      s = strsav(s, "<li>Image List: <a href=\"show-proxy-args?image\"><code>");
-      s = strsav(s, csp->ilist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-#endif /* def USE_IMAGE_LIST */
-
-#ifdef KILLPOPUPS
-   if (csp->plist)
-   {
-      s = strsav(s, "<li>Popup List: <a href=\"show-proxy-args?popup\"><code>");
-      s = strsav(s, csp->plist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-#endif /* def KILLPOPUPS */
-
-#ifdef PCRS
-   if (csp->rlist)
-   {
-      s = strsav(s, "<li>RE Filter List: <a href=\"show-proxy-args?re\"><code>");
-      s = strsav(s, csp->rlist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-#endif /* def PCRS */
-
-#ifdef TRUST_FILES
-   if (csp->tlist)
-   {
-      s = strsav(s, "<li>Trust List: <a href=\"show-proxy-args?trust\"><code>");
-      s = strsav(s, csp->tlist->filename);
-      s = strsav(s, "</code></a></li>\n");
-   }
-#endif /* def TRUST_FILES */
-
-   s = strsav(s, "</ul>");
-
-#else /* ifndef SPLIT_PROXY_ARGS */
-   if (csp->blist)
-   {
-      s = strsav(s, csp->blist->proxy_args);
-   }
-
-   if (csp->clist)
-   {
-      s = strsav(s, csp->clist->proxy_args);
-   }
-
-   if (csp->flist)
-   {
-      s = strsav(s, csp->flist->proxy_args);
-   }
-
-#ifdef ACL_FILES
-   if (csp->alist)
-   {
-      s = strsav(s, csp->alist->proxy_args);
-   }
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-   if (csp->ilist)
-   {
-      s = strsav(s, csp->ilist->proxy_args);
-   }
-#endif /* def USE_IMAGE_LIST */
-
-#ifdef KILLPOPUPS
-   if (csp->plist)
-   {
-      s = strsav(s, csp->plist->proxy_args);
-   }
-#endif /* def KILLPOPUPS */
 
-#ifdef PCRS
-   if (csp->rlist)
-   {
-      s = strsav(s, csp->rlist->proxy_args);
+      apply_url_actions(csp->action, http, b);
    }
-#endif /* def PCRS */
-
-#ifdef TRUST_FILES
-   if (csp->tlist)
-   {
-      s = strsav(s, csp->tlist->proxy_args);
-   }
-#endif /* def TRUST_FILES */
-
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-   s = strsav(s, proxy_args->trailer);
-
-   return(s);
 
+   return;
 }
 
 
-#ifdef TRUST_FILES
 /*********************************************************************
  *
- * Function    :  ij_untrusted_url
+ * Function    :  apply_url_actions
  *
- * Description :  This "crunch"es "http:/any.thing/ij-untrusted-url" and
- *                returns a web page describing why it was untrusted.
+ * Description :  Applies a list of URL actions.
  *
  * Parameters  :
- *          1  :  http = http_request request for crunched URL
- *          2  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  action = Destination.
+ *          2  :  http = Current URL
+ *          3  :  b = list of URL actions to apply
  *
- * Returns     :  A string that contains why this was untrusted.
+ * Returns     :  N/A
  *
  *********************************************************************/
-char *ij_untrusted_url(struct http_request *http, struct client_state *csp)
+void apply_url_actions(struct current_action_spec *action,
+                       struct http_request *http,
+                       struct url_actions *b)
 {
-   int n;
-   char *hostport, *path, *refer, *p, *v[9];
-   char buf[BUFSIZ];
-   struct url_spec **tl, *t;
-
-
-   static const char format[] =
-      "HTTP/1.0 200 OK\r\n"
-      "Pragma: no-cache\n"
-      "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\n"
-      "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\n"
-      "Content-Type: text/html\n\n"
-      "<html>\n"
-      "<head>\n"
-      "<title>Internet Junkbuster: Request for untrusted URL</title>\n"
-      "</head>\n"
-      BODY
-      "<center><h1>"
-      BANNER
-      "</h1></center>"
-      "The " BANNER " Proxy "
-      "<A href=\"" HOME_PAGE_URL "\">"
-      "(" HOME_PAGE_URL ") </A>"
-      "intercepted the request for %s%s\n"
-      "because the URL is not trusted.\n"
-      "<br><br>\n";
-
-   if ((n = ssplit(http->path, "?+", v, SZ(v), 0, 0)) == 4)
+   if (b == NULL)
    {
-      hostport = url_decode(v[1]);
-      path     = url_decode(v[2]);
-      refer    = url_decode(v[3]);
-   }
-   else
-   {
-      hostport = strdup("undefined_host");
-      path     = strdup("/undefined_path");
-      refer    = strdup("undefined");
-   }
-
-   n  = sizeof(format);
-   n += strlen(hostport);
-   n += strlen(path    );
-
-   if ((p = (char *)malloc(n)))
-   {
-      sprintf(p, format, hostport, path);
-   }
-
-   strsav(p, "The referrer in this request was <strong>");
-   strsav(p, refer);
-   strsav(p, "</strong><br>\n");
-
-   freez(hostport);
-   freez(path    );
-   freez(refer   );
-
-   p = strsav(p, "<h3>The following referrers are trusted</h3>\n");
-
-   for (tl = trust_list; (t = *tl) ; tl++)
-   {
-      sprintf(buf, "%s<br>\n", t->spec);
-      p = strsav(p, buf);
+      /* Should never happen */
+      return;
    }
 
-   if (trust_info->next)
+   for (b = b->next; NULL != b; b = b->next)
    {
-      struct list *l;
-
-      strcpy(buf,
-         "<p>"
-         "You can learn more about what this means "
-         "and what you may be able to do about it by "
-         "reading the following documents:<br>\n"
-         "<ol>\n"
-      );
-
-      p = strsav(p, buf);
-
-      for (l = trust_info->next; l ; l = l->next)
+      if (url_match(b->url, http))
       {
-         sprintf(buf,
-            "<li> <a href=%s>%s</a><br>\n",
-               l->str, l->str);
-         p = strsav(p, buf);
+         merge_current_action(action, b->action);
       }
-
-      p = strsav(p, "</ol>\n");
    }
-
-   p = strsav(p, "</body>\n" "</html>\n");
-
-   return(p);
-
 }
-#endif /* def TRUST_FILES */
 
 
-#ifdef STATISTICS
 /*********************************************************************
  *
- * Function    :  add_stats
+ * Function    :  forward_url
  *
- * Description :  Statistics function of JB.  Called by `show_proxy_args'.
+ * Description :  Should we forward this to another proxy?
  *
  * Parameters  :
- *          1  :  s = string that holds the proxy args description page
+ *          1  :  http = http_request request for current URL
+ *          2  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  A pointer to the descriptive status web page.
+ * Returns     :  Pointer to forwarding information.
  *
  *********************************************************************/
-char *add_stats(char *s)
+const struct forward_spec * forward_url(struct http_request *http,
+                                        struct client_state *csp)
 {
-   /*
-    * Output details of the number of requests rejected and
-    * accepted. This is switchable in the junkbuster config.
-    * Does nothing if this option is not enabled.
-    */
+   static const struct forward_spec fwd_default[1] = { FORWARD_SPEC_INITIALIZER };
+   struct forward_spec *fwd = csp->config->forward;
 
-   float perc_rej;   /* Percentage of http requests rejected */
-   char out_str[81];
-   int local_urls_read     = urls_read;
-   int local_urls_rejected = urls_rejected;
-
-   /*
-    * Need to alter the stats not to include the fetch of this
-    * page.
-    *
-        * Can't do following thread safely! doh!
-        *
-    * urls_read--;
-    * urls_rejected--; * This will be incremented subsequently *
-        */
-
-   s = strsav(s,"<h2>Statistics for this " BANNER ":</h2>\n");
-
-   if (local_urls_read == 0)
+   if (fwd == NULL)
    {
-
-      s = strsav(s,"No activity so far!\n");
-
+      return fwd_default;
    }
-   else
-   {
-
-      perc_rej = (float)local_urls_rejected * 100.0F /
-            (float)local_urls_read;
 
-      sprintf(out_str,
-         "%d requests received, %d filtered "
-         "(%6.2f %%).",
-         local_urls_read, 
-         local_urls_rejected, perc_rej);
-
-      s = strsav(s,out_str);
+   while (fwd != NULL)
+   {
+      if (url_match(fwd->url, http))
+      {
+         return fwd;
+      }
+      fwd = fwd->next;
    }
 
-   return(s);
+   return fwd_default;
 }
-#endif /* def STATISTICS */
 
 
 /*
index 68af519..75da5b1 100644 (file)
--- a/filters.h
+++ b/filters.h
@@ -1,20 +1,19 @@
-#ifndef _FILTERS_H
-#define _FILTERS_H
-#define FILTERS_H_VERSION "$Id: filters.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef FILTERS_H_INCLUDED
+#define FILTERS_H_INCLUDED
+#define FILTERS_H_VERSION "$Id: filters.h,v 1.19 2002/03/26 22:29:54 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/filters.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/filters.h,v $
  *
  * Purpose     :  Declares functions to parse/crunch headers and pages.
  *                Functions declared include:
  *                   `acl_addr', `add_stats', `block_acl', `block_imageurl',
- *                   `block_url', `cookie_url', `domaincmp', `dsplit',
- *                   `filter_popups', `forward_url'
+ *                   `block_url', `url_actions', `filter_popups', `forward_url'
  *                   `ij_untrusted_url', `intercept_url', `re_process_buffer',
  *                   `show_proxy_args', and `trust_url'
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: filters.h,v $
+ *    Revision 1.19  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.18  2002/03/25 22:12:45  oes
+ *    Added fix for undefined INADDR_NONE on Solaris by Bart Schelstraete
+ *
+ *    Revision 1.17  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.16  2002/01/17 21:01:02  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Revision 1.15  2001/10/10 16:44:16  oes
+ *    Added match_portlist function
+ *
+ *    Revision 1.14  2001/10/07 15:41:40  oes
+ *    Added prototype for remove_chunked_transfer_coding
+ *
+ *    Revision 1.13  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.12  2001/07/29 19:01:11  jongfoster
+ *    Changed _FILENAME_H to FILENAME_H_INCLUDED.
+ *    Added forward declarations for needed structures.
+ *
+ *    Revision 1.11  2001/07/13 14:00:18  oes
+ *     - Introduced gif_deanimate_response
+ *     - Renamed re_process_buffer to pcrs_filter_response
+ *     - Removed all #ifdef PCRS
+ *
+ *    Revision 1.10  2001/06/29 13:29:01  oes
+ *    Cleaned up and updated to reflect the changesin
+ *    filters.c
+ *
+ *    Revision 1.9  2001/06/07 23:10:53  jongfoster
+ *    Replacing struct gateway with struct forward_spec
+ *
+ *    Revision 1.8  2001/06/03 19:12:00  oes
+ *    extracted-CGI relevant stuff
+ *
+ *    Revision 1.7  2001/05/31 21:21:30  jongfoster
+ *    Permissionsfile / actions file changes:
+ *    - Changed "permission" to "action" throughout
+ *    - changes to file format to allow string parameters
+ *    - Moved helper functions to actions.c
+ *
+ *    Revision 1.6  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.5  2001/05/27 22:17:04  oes
+ *
+ *    - re_process_buffer no longer writes the modified buffer
+ *      to the client, which was very ugly. It now returns the
+ *      buffer, which it is then written by chat.
+ *
+ *    - content_length now adjusts the Content-Length: header
+ *      for modified documents rather than crunch()ing it.
+ *      (Length info in csp->content_length, which is 0 for
+ *      unmodified documents)
+ *
+ *    - For this to work, sed() is called twice when filtering.
+ *
+ *    Revision 1.4  2001/05/26 15:26:15  jongfoster
+ *    ACL feature now provides more security by immediately dropping
+ *    connections from untrusted hosts.
+ *
+ *    Revision 1.3  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:52  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
-\f\r
+\f
 
 #include "project.h"
 
 extern "C" {
 #endif
 
-#ifdef ACL_FILES
-extern int block_acl(struct access_control_addr *src, struct access_control_addr *dst, struct client_state *csp);
-extern int acl_addr(char *aspec, struct access_control_addr *aca);
-#endif /* def ACL_FILES */
-
-extern char *block_url(struct http_request *http, struct client_state *csp);
-#ifdef TRUST_FILES
-extern char *trust_url(struct http_request *http, struct client_state *csp);
-#endif /* def TRUST_FILES */
-extern char *intercept_url(struct http_request *http, struct client_state *csp);
 
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
-extern int block_imageurl(struct http_request *http, struct client_state *csp);
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
+struct access_control_addr;
+struct client_state;
+struct http_request;
+struct http_response;
+struct current_action_spec;
+struct url_actions;
+struct url_spec;
 
-#ifdef USE_IMAGE_LIST
-extern int block_imageurl_using_imagelist(struct http_request *http, struct client_state *csp);
-#endif /* def USE_IMAGE_LIST */
 
-extern struct cookie_spec *cookie_url(struct http_request *http, struct client_state *csp);
-extern const struct gateway *forward_url(struct http_request *http, struct client_state *csp);
+/*
+ * ACL checking
+ */
+#ifdef FEATURE_ACL
+extern int block_acl(struct access_control_addr *dst, struct client_state *csp);
+extern int acl_addr(char *aspec, struct access_control_addr *aca);
+#endif /* def FEATURE_ACL */
+extern int match_portlist(const char *portlist, int port);
 
-extern struct url_spec dsplit(char *domain);
-extern int domaincmp(struct url_spec *pattern, struct url_spec *fqdn);
+/*
+ * Interceptors
+ */
+extern struct http_response *block_url(struct client_state *csp);
+extern struct http_response *redirect_url(struct client_state *csp);
+#ifdef FEATURE_TRUST
+extern struct http_response *trust_url(struct client_state *csp);
+#endif /* def FEATURE_TRUST */
 
-extern char *show_proxy_args(struct http_request *http, struct client_state *csp);
+/*
+ * Request inspectors
+ */
+#ifdef FEATURE_TRUST
+extern int is_untrusted_url(struct client_state *csp);
+#endif /* def FEATURE_TRUST */
+#ifdef FEATURE_IMAGE_BLOCKING
+extern int is_imageurl(struct client_state *csp);
+#endif /* def FEATURE_IMAGE_BLOCKING */
 
-#ifdef TRUST_FILES
-extern char *ij_untrusted_url(struct http_request *http, struct client_state *csp);
-#endif /* def TRUST_FILES */
+/*
+ * Determining applicable actions
+ */
+extern void url_actions(struct http_request *http, 
+                        struct client_state *csp);
+extern void apply_url_actions(struct current_action_spec *action, 
+                              struct http_request *http, 
+                              struct url_actions *b);
+/*
+ * Determining parent proxies
+ */
+extern const struct forward_spec *forward_url(struct http_request *http, struct client_state *csp);
 
-#ifdef STATISTICS
-extern char *add_stats(char *s);
-#endif /* def STATISTICS */
+/*
+ * Content modification
+ */
+extern char *pcrs_filter_response(struct client_state *csp);
+extern char *gif_deanimate_response(struct client_state *csp);
+extern int remove_chunked_transfer_coding(char *buffer, const size_t size);
 
-#ifdef PCRS
-extern void re_process_buffer(struct client_state *csp);
-#endif /* def PCRS */
+/*
+ * Solaris fix:
+ */
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif     
 
-/* Revision control strings from this header and associated .c file */
+/* 
+ * Revision control strings from this header and associated .c file
+ */
 extern const char filters_rcs[];
 extern const char filters_h_rcs[];
 
@@ -97,7 +273,7 @@ extern const char filters_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _FILTERS_H */
+#endif /* ndef FILTERS_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/forward b/forward
deleted file mode 100644 (file)
index be4c787..0000000
--- a/forward
+++ /dev/null
@@ -1,97 +0,0 @@
-#      Forwarding specification for Internet Junkbuster 2.0
-#
-# Copyright 1997-8 Junkbusters Corp.  For distribution, modification and use
-# under the GNU General Public License. These files come with NO WARRANTY.
-# See http://www.junkbusters.com/ht/en/gpl.html or README file for details.
-
-# For this file to have any effect, the line beginning "forwardfile" must
-# be commented in, with the name of this file following the word "forwardfile"
-
-#
-# This feature allows routing of HTTP requests via multiple proxies.
-# It can be used to better protect privacy and confidentiality when
-# accessing specific domains by routing requests to those domains
-# to a special purpose filtering proxy such as lpwa.com
-#
-# It can also be used in an environment with multiple networks to route
-# requests via multiple gateways allowing transparent access to multiple
-# networks without having to modify browser configurations.
-#
-# Also specified here are special gateway protocols such as SOCKS.
-
-# The syntax of each line is
-#
-# target_domain[:port][/path]  forwarding_domain[:port]        gateway_type    gateway_domain[:port]
-#
-
-# A '.' in the forwarding domain/port means that requests made to the
-# target domain are not forwarded but are made directly by the proxy
-# (though the proxy may still use a gateway to contact the server)
-#
-# Lines are checked in turn, and the last match wins.
-#
-# There is an implicit line equivalent to the following, which specifies that
-# anything not finding a match on the list is to go out without forwarding
-# or gateway protocol; like so:
-#
-# *    .       .       .       # implicit
-
-# In the following common configuration, everything goes to Lucent's LPWA,
-# except SSL on port 443 (which it doesn't handle)
-# *            lpwa.com:8000   .       .
-# :443         .               .       .
-
-# See the FAQ for instructions on how to automate the login procedure for LPWA.
-# Some users have reported difficulties related to LPWA's use of . as the
-# last element of the domain, and have said that this can be fixed with this:
-# lpwa.   lpwa.com:8000   .       .
-
-# In this fictitious example, everything goes via an ISP's caching proxy,
-# except requests to that ISP:
-#
-# *            caching.myisp.net:8000  .       .
-# myisp.net    .                       .       .
-
-# For the @home network, we're told the forwarding configuration is this:
-# *       proxy:8080      .       .
-# Also, we're told they insist on getting cookies and Javascript, so you need
-# to add home.com to the cookie file. We consider Javascript a security risk;
-# see our page on cookies. Java need not be enabled.
-
-# In this example direct connections are made to all "internal" domains,
-# but everything else goes through Lucent's LPWA by way of the company's
-# SOCKS gateway to the Internet.
-#
-# *                    lpwa.com:8000   socks   argyle.my_company.com:1080
-# my_company.com       .               .       .
-
-# This is how you could set up a site that always uses SOCKS but no forwarders
-#
-# *                    .               socks   knee.my_company.com:1080
-
-# An advanced example for network administrators.
-#
-# If you have links to multiple ISPs that provide various special
-#content to their subscribers, you can configure forwarding to pass
-# requests to the specific host that's connected to that ISP
-# so that everybody can see
-# all of the content on all of the ISPs.
-#
-# This is tricky, but here's a sample:
-# 
-# host-a has a PPP connection to isp-a.com
-# host-b has a PPP connection to isp-b.com
-
-# host-a can run an Internet Junkbuster proxy with forwarding like this:
-#
-# /            .               .       .
-# isp-b.com    host-b:8000     .       .
-#
-# host-b can run an Internet Junkbuster proxy with forwarding like this:
-# /            .               .       .
-# isp-a.com    host-a:8000     .       .
-#
-# Now, *anyone* on the Internet (including users on host-a and host-b)
-# can set their browser's proxy to *either* host-a or host-b and
-# be able to browse the content on isp-a or isp-b.
-
index 2ccf167..7584b94 100644 (file)
--- a/gateway.c
+++ b/gateway.c
@@ -1,20 +1,20 @@
-const char gateway_rcs[] = "$Id: gateway.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char gateway_rcs[] = "$Id: gateway.c,v 1.15 2002/03/26 22:29:54 swa Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/gateway.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/gateway.c,v $
  *
  * Purpose     :  Contains functions to connect to a server, possibly
- *                using a "gateway" (i.e. HTTP proxy and/or SOCKS4
- *                proxy).  Also contains the list of gateway types.
+ *                using a "forwarder" (i.e. HTTP proxy and/or a SOCKS4
+ *                proxy).
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -34,6 +34,85 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.1 2001/05/13 21:57:06 administrat
  *
  * Revisions   :
  *    $Log: gateway.c,v $
+ *    Revision 1.15  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.14  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.13  2002/03/13 00:29:59  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.12  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.11  2002/03/08 17:46:04  jongfoster
+ *    Fixing int/size_t warnings
+ *
+ *    Revision 1.10  2002/03/07 03:50:19  oes
+ *     - Improved handling of failed DNS lookups
+ *     - Fixed compiler warnings
+ *
+ *    Revision 1.9  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.8  2001/09/13 20:10:12  jongfoster
+ *    Fixing missing #include under Windows
+ *
+ *    Revision 1.7  2001/09/12 17:58:26  steudten
+ *
+ *    add #include <string.h>
+ *
+ *    Revision 1.6  2001/09/10 10:41:16  oes
+ *    Added #include in.h
+ *
+ *    Revision 1.5  2001/07/29 18:47:57  jongfoster
+ *    Adding missing #include project.h
+ *
+ *    Revision 1.4  2001/07/24 12:47:06  oes
+ *    Applied BeOS support update by Eugenia
+ *
+ *    Revision 1.3  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.2  2001/06/07 23:11:38  jongfoster
+ *    Removing gateways[] list - no longer used.
+ *    Replacing function pointer in struct gateway with a directly
+ *    called function forwarded_connect(), which can do the common
+ *    task of deciding whether to connect to the web server or HTTP
+ *    proxy.
+ *    Replacing struct gateway with struct forward_spec
+ *    Fixing bug with SOCKS4A and HTTP proxy server in combination.
+ *    It was a bug which led to the connection being made to the web
+ *    server rather than the HTTP proxy, and also a buffer overrun.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:54  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -42,12 +121,27 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.1 2001/05/13 21:57:06 administrat
 
 #include <stdio.h>
 #include <sys/types.h>
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#endif
+
 #include <errno.h>
+#include <string.h>
 
 #ifdef _WIN32
 #include <winsock2.h>
 #endif /* def _WIN32 */
 
+#ifdef __BEOS__
+#include <netdb.h>
+#endif /* def __BEOS__ */
+
+#ifdef __OS2__
+#include <utils.h>
+#endif /* def __OS2__ */
+
+#include "project.h"
 #include "jcc.h"
 #include "errlog.h"
 #include "jbsockets.h"
@@ -55,20 +149,10 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.1 2001/05/13 21:57:06 administrat
 
 const char gateway_h_rcs[] = GATEWAY_H_VERSION;
 
-#define SOCKS_4      40    /* original SOCKS 4 protocol */
-#define SOCKS_4A     41    /* as modified for hosts w/o external DNS */
-
-const struct gateway gateways[] = {
-   /* type        function          gw type/host/port, fw host/port */
-   { "direct",    direct_connect,   0,          NULL, 0,    NULL, 0 },
-   { ".",         direct_connect,   0,          NULL, 0,    NULL, 0 },
-   { "socks",     socks4_connect,   SOCKS_4,    NULL, 1080, NULL, 0 },
-   { "socks4",    socks4_connect,   SOCKS_4,    NULL, 1080, NULL, 0 },
-   { "socks4a",   socks4_connect,   SOCKS_4A,   NULL, 1080, NULL, 0 },
-   { NULL,        NULL,             0,          NULL, 0,    NULL, 0 }
-};
-
-const struct gateway *gw_default = gateways; /* direct */
+static jb_socket socks4_connect(const struct forward_spec * fwd,
+                                const char * target_host,
+                                int target_port,
+                                struct client_state *csp);
 
 
 #define SOCKS_REQUEST_GRANTED          90
@@ -99,31 +183,56 @@ static const char socks_userid[] = "anonymous";
 
 /*********************************************************************
  *
- * Function    :  direct_connect
+ * Function    :  forwarded_connect
  *
- * Description :  Direct how we connect to the web.  This can be:
- *                directly    : no forwarding, or
- *                indirectly  : through another proxy such as squid.
+ * Description :  Connect to a specified web server, possibly via
+ *                a HTTP proxy and/or a SOCKS proxy.
  *
  * Parameters  :
- *          1  :  gw = pointer to a gateway structure (such as gw_default)
+ *          1  :  fwd = the proxies to use when connecting.
  *          2  :  http = the http request and apropos headers
  *          3  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  -1 => failure, else it is the socket file descriptor.
+ * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket file descriptor.
  *
  *********************************************************************/
-int direct_connect(const struct gateway *gw, struct http_request *http, struct client_state *csp)
+jb_socket forwarded_connect(const struct forward_spec * fwd,
+                            struct http_request *http,
+                            struct client_state *csp)
 {
-   if (gw->forward_host)
+   const char * dest_host;
+   int dest_port;
+
+   /* Figure out if we need to connect to the web server or a HTTP proxy. */
+   if (fwd->forward_host)
    {
-      return(connect_to(gw->forward_host, gw->forward_port, csp));
+      /* HTTP proxy */
+      dest_host = fwd->forward_host;
+      dest_port = fwd->forward_port;
    }
    else
    {
-      return(connect_to(http->host, http->port, csp));
+      /* Web server */
+      dest_host = http->host;
+      dest_port = http->port;
    }
 
+   /* Connect, maybe using a SOCKS proxy */
+   switch (fwd->type)
+   {
+      case SOCKS_NONE:
+         return (connect_to(dest_host, dest_port, csp));
+
+      case SOCKS_4:
+      case SOCKS_4A:
+         return (socks4_connect(fwd, dest_host, dest_port, csp));
+
+      default:
+         /* Should never get here */
+         log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type.");
+         errno = EINVAL;
+         return(JB_INVALID_SOCKET);
+   }
 }
 
 
@@ -132,37 +241,43 @@ int direct_connect(const struct gateway *gw, struct http_request *http, struct c
  * Function    :  socks4_connect
  *
  * Description :  Connect to the SOCKS server, and connect through
- *                it to the web server or web proxy.   This handles
+ *                it to the specified server.   This handles
  *                all the SOCKS negotiation, and returns a file
  *                descriptor for a socket which can be treated as a
  *                normal (non-SOCKS) socket.
  *
  * Parameters  :
- *          1  :  gw = pointer to a gateway structure (such as gw_default)
- *          2  :  http = the http request and apropos headers
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  fwd = Specifies the SOCKS proxy to use.
+ *          2  :  target_host = The final server to connect to.
+ *          3  :  target_port = The final port to connect to.
+ *          4  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  -1 => failure, else a socket file descriptor.
+ * Returns     :  JB_INVALID_SOCKET => failure, else a socket file descriptor.
  *
  *********************************************************************/
-int socks4_connect(const struct gateway *gw, struct http_request *http, struct client_state *csp)
+static jb_socket socks4_connect(const struct forward_spec * fwd,
+                                const char * target_host,
+                                int target_port,
+                                struct client_state *csp)
 {
    int web_server_addr;
-   unsigned char cbuf[BUFSIZ];
-   unsigned char sbuf[BUFSIZ];
+   char cbuf[BUFFER_SIZE];
+   char sbuf[BUFFER_SIZE];
    struct socks_op    *c = (struct socks_op    *)cbuf;
    struct socks_reply *s = (struct socks_reply *)sbuf;
-   int n, csiz, sfd, target_port;
+   size_t n;
+   size_t csiz;
+   jb_socket sfd;
    int err = 0;
-   char *errstr, *target_host;
+   char *errstr;
 
-   if ((gw->gateway_host == NULL) || (*gw->gateway_host == '\0'))
+   if ((fwd->gateway_host == NULL) || (*fwd->gateway_host == '\0'))
    {
       log_error(LOG_LEVEL_CONNECT, "socks4_connect: NULL gateway host specified");
       err = 1;
    }
 
-   if (gw->gateway_port <= 0)
+   if (fwd->gateway_port <= 0)
    {
       log_error(LOG_LEVEL_CONNECT, "socks4_connect: invalid gateway port specified");
       err = 1;
@@ -171,18 +286,7 @@ int socks4_connect(const struct gateway *gw, struct http_request *http, struct c
    if (err)
    {
       errno = EINVAL;
-      return(-1);
-   }
-
-   if (gw->forward_host)
-   {
-      target_host = gw->forward_host;
-      target_port = gw->forward_port;
-   }
-   else
-   {
-      target_host = http->host;
-      target_port = http->port;
+      return(JB_INVALID_SOCKET);
    }
 
    /* build a socks request for connection to the web server */
@@ -191,10 +295,15 @@ int socks4_connect(const struct gateway *gw, struct http_request *http, struct c
 
    csiz = sizeof(*c) + sizeof(socks_userid) - 1;
 
-   switch (gw->type)
+   switch (fwd->type)
    {
       case SOCKS_4:
          web_server_addr = htonl(resolve_hostname_to_ip(target_host));
+         if (web_server_addr == INADDR_NONE)
+         {
+            log_error(LOG_LEVEL_CONNECT, "socks4_connect: could not resolve target host %s", target_host);
+            return(JB_INVALID_SOCKET);
+         }
          break;
       case SOCKS_4A:
          web_server_addr = 0x00000001;
@@ -202,16 +311,16 @@ int socks4_connect(const struct gateway *gw, struct http_request *http, struct c
          if (n > sizeof(cbuf))
          {
             errno = EINVAL;
-            return(-1);
+            return(JB_INVALID_SOCKET);
          }
-         strcpy(((char *)cbuf) + csiz, http->host);
+         strcpy(cbuf + csiz, target_host);
          csiz = n;
          break;
       default:
          /* Should never get here */
-         log_error(LOG_LEVEL_ERROR, "SOCKS4 impossible internal error - bad SOCKS type.");
+         log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type.");
          errno = EINVAL;
-         return(-1);
+         return(JB_INVALID_SOCKET);
    }
 
    c->vn          = 4;
@@ -224,25 +333,25 @@ int socks4_connect(const struct gateway *gw, struct http_request *http, struct c
    c->dstip[3]    = (web_server_addr         ) & 0xff;
 
    /* pass the request to the socks server */
-   sfd = connect_to(gw->gateway_host, gw->gateway_port, csp);
+   sfd = connect_to(fwd->gateway_host, fwd->gateway_port, csp);
 
-   if (sfd < 0)
+   if (sfd == JB_INVALID_SOCKET)
    {
-      return(-1);
+      return(JB_INVALID_SOCKET);
    }
 
-   if ((n = write_socket(sfd, (char *)c, csiz)) != csiz)
+   if (write_socket(sfd, (char *)c, csiz))
    {
       log_error(LOG_LEVEL_CONNECT, "SOCKS4 negotiation write failed...");
       close_socket(sfd);
-      return(-1);
+      return(JB_INVALID_SOCKET);
    }
 
-   if ((n = read_socket(sfd, sbuf, sizeof(sbuf))) != sizeof(*s))
+   if (read_socket(sfd, sbuf, sizeof(sbuf)) != sizeof(*s))
    {
       log_error(LOG_LEVEL_CONNECT, "SOCKS4 negotiation read failed...");
       close_socket(sfd);
-      return(-1);
+      return(JB_INVALID_SOCKET);
    }
 
    switch (s->cd)
@@ -266,7 +375,7 @@ int socks4_connect(const struct gateway *gw, struct http_request *http, struct c
          errno = EACCES;
          break;
       default:
-         errstr = (char *) cbuf;
+         errstr = cbuf;
          errno = ENOENT;
          sprintf(errstr,
                  "SOCKS request rejected for reason code %d\n", s->cd);
@@ -275,7 +384,7 @@ int socks4_connect(const struct gateway *gw, struct http_request *http, struct c
    log_error(LOG_LEVEL_CONNECT, "socks4_connect: %s ...", errstr);
 
    close_socket(sfd);
-   return(-1);
+   return(JB_INVALID_SOCKET);
 
 }
 
index 6914555..d96bc58 100644 (file)
--- a/gateway.h
+++ b/gateway.h
@@ -1,16 +1,16 @@
-#ifndef _GATEWAY_H
-#define _GATEWAY_H
-#define GATEWAY_H_VERSION "$Id: gateway.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef GATEWAY_H_INCLUDED
+#define GATEWAY_H_INCLUDED
+#define GATEWAY_H_VERSION "$Id: gateway.h,v 1.6 2002/03/25 22:12:45 oes Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/gateway.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/gateway.h,v $
  *
  * Purpose     :  Contains functions to connect to a server, possibly
  *                using a "gateway" (i.e. HTTP proxy and/or SOCKS4
  *                proxy).  Also contains the list of gateway types.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: gateway.h,v $
+ *    Revision 1.6  2002/03/25 22:12:45  oes
+ *    Added fix for undefined INADDR_NONE on Solaris by Bart Schelstraete
+ *
+ *    Revision 1.5  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.4  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.3  2001/07/29 18:58:15  jongfoster
+ *    Removing nested #includes, adding forward declarations for needed
+ *    structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
+ *
+ *    Revision 1.2  2001/06/07 23:12:14  jongfoster
+ *    Removing gateways[] list - no longer used.
+ *    Replacing function pointer in struct gateway with a directly
+ *    called function forwarded_connect(), which can do the common
+ *    task of deciding whether to connect to the web server or HTTP
+ *    proxy.
+ *    Replacing struct gateway with struct forward_spec
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:54  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
-#include "project.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern const struct gateway gateways[];
-extern const struct gateway *gw_default;
+struct forward_spec;
+struct http_request;
+struct client_state;
 
-extern int socks4_connect(const struct gateway *gw, struct http_request *http, struct client_state *csp);
-extern int direct_connect(const struct gateway *gw, struct http_request *http, struct client_state *csp);
+extern jb_socket forwarded_connect(const struct forward_spec * fwd, 
+                                   struct http_request *http, 
+                                   struct client_state *csp);
 
-/* Revision control strings from this header and associated .c file */
+/*
+ * Solaris fix
+ */
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
+
+/*
+ * Revision control strings from this header and associated .c file
+ */
 extern const char gateway_rcs[];
 extern const char gateway_h_rcs[];
 
@@ -60,7 +114,7 @@ extern const char gateway_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _GATEWAY_H */
+#endif /* ndef GATEWAY_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/genclspec.sh b/genclspec.sh
new file mode 100755 (executable)
index 0000000..796d05f
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# $Id: genclspec,v 1.30 2002/04/26 15:51:05 morcego Exp $
+#
+# Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# This program is free software; you can redistribute it 
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.  See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file.  If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# $Log: genclspec.spec,v $
+#
+
+VERSION=`cat privoxy-rh.spec | sed -n -e 's/^Version:[ ]*//p'`
+RELEASE=`cat privoxy-rh.spec | sed -n -e 's/^Release:[ ]*//p'`
+CLTAG=${VERSION}-${RELEASE}cl
+
+PACKAGER=`rpm --eval "%{packager}"`
+if [ "${PACKAGER}" = "%{packager}" ]; then
+       PACKAGER="genclspec script <developers@privoxy.org>"
+fi
+
+export LC_ALL=
+export LANG=
+DATETAG=`date "+%a %b %d %Y"`
+
+if [ -r privoxy-cl.spec ]; then
+       echo Old CL specfile found. Removing it.
+fi
+
+cat privoxy-rh.spec | sed -e 's/^\(Release:[ ]*[^ ]\+\)[ ]*$/\1cl/' \
+                         -e "/^%changelog/a* ${DATETAG} ${PACKAGER}" \
+                         -e "/^%changelog/a+ privoxy-${CLTAG}" \
+                         -e "/^%changelog/a- Packaging for Conectiva Linux (automatic genarated specfile)" \
+                         -e '/^%changelog/a \
+' > privoxy-cl.spec
+
diff --git a/icons/denyrule.ico b/icons/denyrule.ico
deleted file mode 100644 (file)
index e5aa250..0000000
Binary files a/icons/denyrule.ico and /dev/null differ
diff --git a/icons/icon1.ico b/icons/icon1.ico
deleted file mode 100644 (file)
index b96fe7c..0000000
Binary files a/icons/icon1.ico and /dev/null differ
index 99470b5..5ef20fc 100644 (file)
Binary files a/icons/idle.ico and b/icons/idle.ico differ
diff --git a/icons/os2.ico b/icons/os2.ico
new file mode 100644 (file)
index 0000000..0ad4f56
Binary files /dev/null and b/icons/os2.ico differ
diff --git a/icons/os20.ico b/icons/os20.ico
new file mode 100644 (file)
index 0000000..ef5995b
Binary files /dev/null and b/icons/os20.ico differ
diff --git a/icons/os21.ico b/icons/os21.ico
new file mode 100644 (file)
index 0000000..cc61b61
Binary files /dev/null and b/icons/os21.ico differ
diff --git a/icons/os22.ico b/icons/os22.ico
new file mode 100644 (file)
index 0000000..d357dfb
Binary files /dev/null and b/icons/os22.ico differ
diff --git a/icons/os23.ico b/icons/os23.ico
new file mode 100644 (file)
index 0000000..8ac037f
Binary files /dev/null and b/icons/os23.ico differ
diff --git a/icons/os24.ico b/icons/os24.ico
new file mode 100644 (file)
index 0000000..f2b87f7
Binary files /dev/null and b/icons/os24.ico differ
diff --git a/icons/os25.ico b/icons/os25.ico
new file mode 100644 (file)
index 0000000..5bc68b5
Binary files /dev/null and b/icons/os25.ico differ
diff --git a/icons/os26.ico b/icons/os26.ico
new file mode 100644 (file)
index 0000000..408d89e
Binary files /dev/null and b/icons/os26.ico differ
diff --git a/icons/os27.ico b/icons/os27.ico
new file mode 100644 (file)
index 0000000..00a8814
Binary files /dev/null and b/icons/os27.ico differ
diff --git a/icons/os28.ico b/icons/os28.ico
new file mode 100644 (file)
index 0000000..9153636
Binary files /dev/null and b/icons/os28.ico differ
similarity index 59%
rename from icons/junkbust.ico
rename to icons/privoxy.ico
index 41aafd0..4c96d0b 100644 (file)
Binary files a/icons/junkbust.ico and b/icons/privoxy.ico differ
diff --git a/imagelist b/imagelist
deleted file mode 100644 (file)
index e83fed0..0000000
--- a/imagelist
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# This is /etc/junkbuster/imagelist which was put here by a junkbuster rpm
-#
-# Last modified on Fri Oct  1 22:42:21 1999 (CEST)
-#
-# --------------------------------------------------------------------------
-#
-# Newest version is always available from 
-#
-#          http://www.waldherr.org/imagelist
-#
-# Read http://www.waldherr.org/junkbuster/update.shtml on how to keep
-# this file up-to-date.
-#
-# Comments: Stefan Waldherr <stefan@waldherr.org>
-#
-# Note that the regexp is split into domain and path, hence the `/' as the 
-# beginning of a path.
-#
-
-# generic, most powerful regepxs, path contains `.gif', `.jpeg' or `.jpg'
-/.*\.gif
-/.*\.jpe?g
-
-adforce.imgis.com
-ad.preferences.com/image.*
-ads.web.aol.com
-focalink.com
-ad-adex3.flycast.com
-ad.doubleclick.net
-connect.247media.ads.link4ads.com
-ln.doubleclick.net
-mojofarm.mediaplex.com/ad/
-www.carbuyer.com/cgi-carbuyer/getimage.cgi
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..e9de238
--- /dev/null
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
index c5f73c9..a385965 100644 (file)
@@ -1,15 +1,15 @@
-const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.34 2002/04/08 20:31:41 swa Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/jbsockets.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/jbsockets.c,v $
  *
  * Purpose     :  Contains wrappers for system-specific sockets code,
- *                so that the rest of JunkBuster can be more
+ *                so that the rest of Junkbuster can be more
  *                OS-independent.  Contains #ifdefs to make this work
  *                on many platforms.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
@@ -35,6 +35,144 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.1 2001/05/13 21:57:06 adminis
  *
  * Revisions   :
  *    $Log: jbsockets.c,v $
+ *    Revision 1.34  2002/04/08 20:31:41  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.33  2002/04/03 16:02:18  gliptak
+ *    Correcting compile warning with older gcc
+ *
+ *    Revision 1.32  2002/03/31 17:18:59  jongfoster
+ *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
+ *
+ *    Revision 1.31  2002/03/29 03:33:13  david__schmidt
+ *    Fix Mac OSX compiler warnings
+ *
+ *    Revision 1.30  2002/03/27 14:32:43  david__schmidt
+ *    More compiler warning message maintenance
+ *
+ *    Revision 1.29  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.28  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.27  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.26  2002/03/11 22:07:02  david__schmidt
+ *    OS/2 port maintenance:
+ *    - Fixed EMX build - it had decayed a little
+ *    - Fixed inexplicable crash during FD_ZERO - must be due to a bad macro.
+ *      substituted a memset for now.
+ *
+ *    Revision 1.25  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.24  2002/03/07 03:51:36  oes
+ *     - Improved handling of failed DNS lookups
+ *     - Fixed compiler warnings etc
+ *
+ *    Revision 1.23  2002/03/05 00:36:01  jongfoster
+ *    Fixing bug 514988 - unable to restart Junkbuster
+ *
+ *    Revision 1.22  2002/03/04 02:08:02  david__schmidt
+ *    Enable web editing of actions file on OS/2 (it had been broken all this time!)
+ *
+ *    Revision 1.21  2002/01/09 14:32:33  oes
+ *    Added support for gethostbyname_r and gethostbyaddr_r.
+ *
+ *    Revision 1.20  2001/11/16 00:48:48  jongfoster
+ *    Enabling duplicate-socket detection for all platforms, not
+ *    just Win32.
+ *
+ *    Revision 1.19  2001/10/25 03:40:47  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.18  2001/09/21 23:02:02  david__schmidt
+ *    Cleaning up 2 compiler warnings on OS/2.
+ *
+ *    Revision 1.17  2001/09/13 20:11:46  jongfoster
+ *    Fixing 2 compiler warnings under Win32
+ *
+ *    Revision 1.16  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.15  2001/07/29 17:40:43  jongfoster
+ *    Fixed compiler warning by adding a cast
+ *
+ *    Revision 1.14  2001/07/18 13:47:59  oes
+ *    Eliminated dirty hack for getsockbyname()
+ *
+ *    Revision 1.13  2001/07/15 13:56:57  jongfoster
+ *    Removing unused local variable.
+ *
+ *    Revision 1.12  2001/07/01 17:04:11  oes
+ *    Bugfix: accept_connection no longer uses the obsolete hstrerror() function
+ *
+ *    Revision 1.11  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.10  2001/06/29 13:29:15  oes
+ *    - Added remote (server) host IP to csp->http->host_ip_addr_str
+ *    - Added detection of local socket IP and fqdn
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.9  2001/06/07 23:06:09  jongfoster
+ *    The host parameter to connect_to() is now const.
+ *
+ *    Revision 1.8  2001/06/03 19:12:07  oes
+ *    filled comment
+ *
+ *    Revision 1.7  2001/05/28 16:14:00  jongfoster
+ *    Fixing bug in LOG_LEVEL_LOG
+ *
+ *    Revision 1.6  2001/05/26 17:28:32  jongfoster
+ *    Fixed LOG_LEVEL_LOG
+ *
+ *    Revision 1.5  2001/05/26 15:26:15  jongfoster
+ *    ACL feature now provides more security by immediately dropping
+ *    connections from untrusted hosts.
+ *
+ *    Revision 1.4  2001/05/26 00:37:42  jongfoster
+ *    Cosmetic indentation correction.
+ *
+ *    Revision 1.3  2001/05/25 21:57:54  jongfoster
+ *    Now gives a warning under Windows if you try to bind
+ *    it to a port that's already in use.
+ *
+ *    Revision 1.2  2001/05/17 23:01:01  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:54  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -50,13 +188,18 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.1 2001/05/13 21:57:06 adminis
 
 #ifdef _WIN32
 
+#ifndef STRICT
+#define STRICT
+#endif
 #include <windows.h>
 #include <sys/timeb.h>
 #include <io.h>
 
 #else
 
+#ifndef __OS2__
 #include <unistd.h>
+#endif
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <sys/ioctl.h>
@@ -65,16 +208,26 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.1 2001/05/13 21:57:06 adminis
 
 #ifndef __BEOS__
 #include <netinet/tcp.h>
+#ifndef __OS2__
 #include <arpa/inet.h>
+#endif
 #else
 #include <socket.h>
 #endif
 
+#if defined(__EMX__) || defined (__OS2__)
+#include <sys/select.h>  /* OS/2/EMX needs a little help with select */
+#ifdef __OS2__
+#include <nerrno.h>
+#endif
+#endif
+
 #endif
 
 #include "project.h"
 #include "jbsockets.h"
 #include "filters.h"
+#include "errlog.h"
 
 const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
 
@@ -92,59 +245,72 @@ const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
  *          3  :  csp = Current client state (buffers, headers, etc...)
  *                      Not modified, only used for source IP and ACL.
  *
- * Returns     :  -1 => failure, else it is the socket file descriptor.
+ * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket
+ *                file descriptor.
  *
  *********************************************************************/
-int connect_to(char *host, int portnum, struct client_state *csp)
+jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
 {
    struct sockaddr_in inaddr;
-   int   fd, addr;
+   jb_socket fd;
+   int addr;
    fd_set wfds;
    struct timeval tv[1];
 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
    int   flags;
 #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
 
-#ifdef ACL_FILES
-   struct access_control_addr src[1], dst[1];
-#endif /* def ACL_FILES */
+#ifdef FEATURE_ACL
+   struct access_control_addr dst[1];
+#endif /* def FEATURE_ACL */
 
    memset((char *)&inaddr, 0, sizeof inaddr);
 
-   if ((addr = resolve_hostname_to_ip(host)) == -1)
+   if ((addr = resolve_hostname_to_ip(host)) == INADDR_NONE)
    {
-      return(-1);
+      csp->http->host_ip_addr_str = strdup("unknown");
+      return(JB_INVALID_SOCKET);
    }
 
-#ifdef ACL_FILES
-   src->addr = csp->ip_addr_long;
-   src->port = 0;
-
-   dst->addr = ntohl(addr);
+#ifdef FEATURE_ACL
+   dst->addr = ntohl((unsigned long) addr);
    dst->port = portnum;
 
-   if (block_acl(src, dst, csp))
+   if (block_acl(dst, csp))
    {
+#ifdef __OS2__
+      errno = SOCEPERM;
+#else
       errno = EPERM;
-      return(-1);
+#endif
+      return(JB_INVALID_SOCKET);
    }
-#endif /* def ACL_FILES */
+#endif /* def FEATURE_ACL */
 
    inaddr.sin_addr.s_addr = addr;
    inaddr.sin_family      = AF_INET;
+   csp->http->host_ip_addr_str = strdup(inet_ntoa(inaddr.sin_addr));
 
+#ifndef _WIN32
    if (sizeof(inaddr.sin_port) == sizeof(short))
+#endif /* ndef _WIN32 */
    {
-      inaddr.sin_port = htons((short)portnum);
+      inaddr.sin_port = htons((unsigned short) portnum);
    }
+#ifndef _WIN32
    else
    {
-      inaddr.sin_port = htonl(portnum);
+      inaddr.sin_port = htonl((unsigned long)portnum);
    }
+#endif /* ndef _WIN32 */
 
+#ifdef _WIN32
+   if ((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) == JB_INVALID_SOCKET)
+#else
    if ((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) < 0)
+#endif
    {
-      return(-1);
+      return(JB_INVALID_SOCKET);
    }
 
 #ifdef TCP_NODELAY
@@ -154,39 +320,45 @@ int connect_to(char *host, int portnum, struct client_state *csp)
    }
 #endif /* def TCP_NODELAY */
 
-#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)\r
+#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
    if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
    {
       flags |= O_NDELAY;
       fcntl(fd, F_SETFL, flags);
    }
-#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
+#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
 
-   while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == -1)
+   while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == JB_INVALID_SOCKET)
    {
 #ifdef _WIN32
       if (errno == WSAEINPROGRESS)
+#elif __OS2__ 
+      if (sock_errno() == EINPROGRESS)
 #else /* ifndef _WIN32 */
       if (errno == EINPROGRESS)
-#endif /* ndef _WIN32 */
+#endif /* ndef _WIN32 || __OS2__ */
       {
          break;
       }
 
+#ifdef __OS2__ 
+      if (sock_errno() != EINTR)
+#else
       if (errno != EINTR)
+#endif /* __OS2__ */
       {
          close_socket(fd);
-         return(-1);
+         return(JB_INVALID_SOCKET);
       }
    }
 
-#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
+#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
    if (flags != -1)
    {
       flags &= ~O_NDELAY;
       fcntl(fd, F_SETFL, flags);
    }
-#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
+#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
 
    /* wait for connection to complete */
    FD_ZERO(&wfds);
@@ -195,10 +367,11 @@ int connect_to(char *host, int portnum, struct client_state *csp)
    tv->tv_sec  = 30;
    tv->tv_usec = 0;
 
-   if (select(fd + 1, NULL, &wfds, NULL, tv) <= 0)
+   /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Wierd! */
+   if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
    {
       close_socket(fd);
-      return(-1);
+      return(JB_INVALID_SOCKET);
    }
    return(fd);
 
@@ -216,22 +389,51 @@ int connect_to(char *host, int portnum, struct client_state *csp)
  *          2  :  buf = pointer to data to be written.
  *          3  :  len = length of data to be written to the socket "fd".
  *
- * Returns     :  Win32: If no error occurs, returns the total number of
- *                bytes sent, which can be less than the number
- *                indicated by len. Otherwise, returns (-1).
- *                Unix: ??? (Please fill me in!)
+ * Returns     :  0 on success (entire buffer sent).
+ *                nonzero on error.
  *
  *********************************************************************/
-int write_socket(int fd, const char *buf, int len)
+int write_socket(jb_socket fd, const char *buf, size_t len)
 {
-   if (len <= 0) return(0);
+   if (len == 0)
+   {
+      return 0;
+   }
 
-   /* if (DEBUG(LOG)) fwrite(buf, n, 1, logfp); */
+   if (len < 0)
+   {
+      return 1;
+   }
 
-#if defined(_WIN32) || defined(__BEOS__) || defined(AMIGA)
-   return( send(fd, buf, len, 0));
+   log_error(LOG_LEVEL_LOG, "%N", len, buf);
+
+#if defined(_WIN32)
+   return (send(fd, buf, (int)len, 0) != (int)len);
+#elif defined(__BEOS__) || defined(AMIGA)
+   return (send(fd, buf, len, 0) != len);
+#elif defined(__OS2__)
+   /*
+    * Break the data up into SOCKET_SEND_MAX chunks for sending...
+    * OS/2 seemed to complain when the chunks were too large.
+    */
+#define SOCKET_SEND_MAX 65000
+   {
+      int write_len = 0, send_len, send_rc = 0, i = 0;
+      while ((i < len) && (send_rc != -1))
+      {
+         if ((i + SOCKET_SEND_MAX) > len)
+            send_len = len - i;
+         else
+            send_len = SOCKET_SEND_MAX;
+         send_rc = send(fd,(char*)buf + i, send_len, 0);
+         if (send_rc == -1)
+            return 1;
+         i = i + send_len;
+      }
+      return 0;
+   }
 #else
-   return( write(fd, buf, len));
+   return (write(fd, buf, len) != len);
 #endif
 
 }
@@ -255,24 +457,26 @@ int write_socket(int fd, const char *buf, int len)
  *                smaller than the number of bytes requested; this may hap-
  *                pen for example because fewer bytes are actually available
  *                right now (maybe because we were close to end-of-file, or
- *                because we are reading from a pipe, or from a terminal),
- *                or because read() was interrupted by a signal.  On error,
+ *                because we are reading from a pipe, or from a terminal,
+ *                or because read() was interrupted by a signal).  On error,
  *                -1 is returned, and errno is set appropriately.  In this
  *                case it is left unspecified whether the file position (if
  *                any) changes.
  *
  *********************************************************************/
-int read_socket(int fd, char *buf, int len)
+int read_socket(jb_socket fd, char *buf, int len)
 {
    if (len <= 0)
    {
       return(0);
    }
 
-#if defined(_WIN32) || defined(__BEOS__) || defined(AMIGA)
-   return( recv(fd, buf, len, 0));
+#if defined(_WIN32)
+   return(recv(fd, buf, len, 0));
+#elif defined(__BEOS__) || defined(AMIGA) || defined(__OS2__)
+   return(recv(fd, buf, (size_t)len, 0));
 #else
-   return( read(fd, buf, len));
+   return(read(fd, buf, (size_t)len));
 #endif
 }
 
@@ -289,12 +493,14 @@ int read_socket(int fd, char *buf, int len)
  * Returns     :  void
  *
  *********************************************************************/
-void close_socket(int fd)
+void close_socket(jb_socket fd)
 {
 #if defined(_WIN32) || defined(__BEOS__)
    closesocket(fd);
-#elif defined(AMIGA)\r
-   CloseSocket(fd); \r
+#elif defined(AMIGA)
+   CloseSocket(fd); 
+#elif defined(__OS2__)
+   soclose(fd);
 #else
    close(fd);
 #endif
@@ -312,39 +518,72 @@ void close_socket(int fd)
  * Parameters  :
  *          1  :  hostnam = TCP/IP address to bind/listen to
  *          2  :  portnum = port to listen on
+ *          3  :  pfd = pointer used to return file descriptor.
  *
- * Returns     :  if success, return file descriptor
- *                if failure, returns -2 if address is in use, otherwise -1
- *
+ * Returns     :  if success, returns 0 and sets *pfd.
+ *                if failure, returns -3 if address is in use,
+ *                                    -2 if address unresolvable,
+ *                                    -1 otherwise
  *********************************************************************/
-int bind_port(const char *hostnam, int portnum)
+int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
 {
    struct sockaddr_in inaddr;
-   int fd;
+   jb_socket fd;
+#ifndef _WIN32
    int one = 1;
+#endif /* ndef _WIN32 */
+
+   *pfd = JB_INVALID_SOCKET;
 
    memset((char *)&inaddr, '\0', sizeof inaddr);
 
    inaddr.sin_family      = AF_INET;
    inaddr.sin_addr.s_addr = resolve_hostname_to_ip(hostnam);
 
+   if (inaddr.sin_addr.s_addr == INADDR_NONE)
+   {
+      return(-2);
+   }
+
+#ifndef _WIN32
    if (sizeof(inaddr.sin_port) == sizeof(short))
+#endif /* ndef _WIN32 */
    {
-      inaddr.sin_port = htons((short)portnum);
+      inaddr.sin_port = htons((unsigned short) portnum);
    }
+#ifndef _WIN32
    else
    {
-      inaddr.sin_port = htonl(portnum);
+      inaddr.sin_port = htonl((unsigned long) portnum);
    }
+#endif /* ndef _WIN32 */
 
    fd = socket(AF_INET, SOCK_STREAM, 0);
 
+#ifdef _WIN32
+   if (fd == JB_INVALID_SOCKET)
+#else
    if (fd < 0)
+#endif
    {
       return(-1);
    }
 
+#ifndef _WIN32
+   /*
+    * This is not needed for Win32 - in fact, it stops
+    * duplicate instances of Junkbuster from being caught.
+    *
+    * On UNIX, we assume the user is sensible enough not
+    * to start Junkbuster multiple times on the same IP.
+    * Without this, stopping and restarting Junkbuster
+    * from a script fails.
+    * Note: SO_REUSEADDR is meant to only take over
+    * sockets which are *not* in listen state in Linux,
+    * e.g. sockets in TIME_WAIT. YMMV.
+    */
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
+#endif /* ndef _WIN32 */
 
    if (bind (fd, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
    {
@@ -355,7 +594,7 @@ int bind_port(const char *hostnam, int portnum)
       if (errno == EADDRINUSE)
 #endif
       {
-         return(-2);
+         return(-3);
       }
       else
       {
@@ -371,7 +610,8 @@ int bind_port(const char *hostnam, int portnum)
       }
    }
 
-   return fd;
+   *pfd = fd;
+   return 0;
 
 }
 
@@ -392,28 +632,93 @@ int bind_port(const char *hostnam, int portnum)
  *                On an error it returns 0 (FALSE).
  *
  *********************************************************************/
-int accept_connection(struct client_state * csp, int fd)
+int accept_connection(struct client_state * csp, jb_socket fd)
 {
-   struct sockaddr raddr;
-   struct sockaddr_in *rap = (struct sockaddr_in *) &raddr;
-   int   afd, raddrlen;
+   struct sockaddr_in client, server;
+   struct hostent *host = NULL;
+   jb_socket afd;
+#if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
+   /* Wierdness - fix a warning. */
+   int c_length, s_length;
+#else
+   socklen_t c_length, s_length;
+#endif
+#if defined(HAVE_GETHOSTBYADDR_R_8_ARGS) ||  defined(HAVE_GETHOSTBYADDR_R_7_ARGS) || defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
+   struct hostent result;
+#if defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
+   struct hostent_data hdata;
+#else
+   char hbuf[HOSTENT_BUFFER_SIZE];
+   int thd_err;
+#endif /* def HAVE_GETHOSTBYADDR_R_5_ARGS */
+#endif /* def HAVE_GETHOSTBYADDR_R_(8|7|5)_ARGS */
 
-   raddrlen = sizeof raddr;
+   c_length = s_length = sizeof(client);
+
+#ifdef _WIN32
+   afd = accept (fd, (struct sockaddr *) &client, &c_length);
+   if (afd == JB_INVALID_SOCKET)
+   {
+      return 0;
+   }
+#else
    do
    {
-      afd = accept (fd, &raddr, &raddrlen);
+      afd = accept (fd, (struct sockaddr *) &client, &c_length);
    } while (afd < 1 && errno == EINTR);
-
    if (afd < 0)
    {
       return 0;
    }
+#endif
+
+   /* 
+    * Determine the IP-Adress that the client used to reach us
+    * and the hostname associated with that address
+    */
+   if (!getsockname(afd, (struct sockaddr *) &server, &s_length))
+   {
+      csp->my_ip_addr_str = strdup(inet_ntoa(server.sin_addr));
+#if defined(HAVE_GETHOSTBYADDR_R_8_ARGS)
+      gethostbyaddr_r((const char *)&server.sin_addr,
+                      sizeof(server.sin_addr), AF_INET,
+                      &result, hbuf, HOSTENT_BUFFER_SIZE,
+                      &host, &thd_err);
+#elif defined(HAVE_GETHOSTBYADDR_R_7_ARGS)
+      host = gethostbyaddr_r((const char *)&server.sin_addr,
+                      sizeof(server.sin_addr), AF_INET,
+                      &result, hbuf, HOSTENT_BUFFER_SIZE, &thd_err);
+#elif defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
+      if (0 == gethostbyaddr_r((const char *)&server.sin_addr,
+                               sizeof(server.sin_addr), AF_INET,
+                               &result, &hdata))
+      {
+         host = &result;
+      }
+      else
+      {
+         host = NULL;
+      }
+#else
+      host = gethostbyaddr((const char *)&server.sin_addr, 
+                           sizeof(server.sin_addr), AF_INET);
+#endif
+      if (host == NULL)
+      {
+         log_error(LOG_LEVEL_ERROR, "Unable to get my own hostname: %E\n");
+      }
+      else
+      {
+         csp->my_hostname = strdup(host->h_name);
+      }
+   }
 
    csp->cfd    = afd;
-   csp->ip_addr_str  = strdup(inet_ntoa(rap->sin_addr));
-   csp->ip_addr_long = ntohl(rap->sin_addr.s_addr);
+   csp->ip_addr_str  = strdup(inet_ntoa(client.sin_addr));
+   csp->ip_addr_long = ntohl(client.sin_addr.s_addr);
 
    return 1;
+
 }
 
 
@@ -427,13 +732,22 @@ int accept_connection(struct client_state * csp, int fd)
  * Parameters  :
  *          1  :  host = hostname to resolve
  *
- * Returns     :  -1 => failure, INADDR_ANY or tcp/ip address if succesful.
+ * Returns     :  INADDR_NONE => failure, INADDR_ANY or tcp/ip address if succesful.
  *
  *********************************************************************/
-int resolve_hostname_to_ip(const char *host)
+unsigned long resolve_hostname_to_ip(const char *host)
 {
    struct sockaddr_in inaddr;
    struct hostent *hostp;
+#if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) || defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
+   struct hostent result;
+#if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
+   char hbuf[HOSTENT_BUFFER_SIZE];
+   int thd_err;
+#else /* defined(HAVE_GETHOSTBYNAME_R_3_ARGS) */
+   struct hostent_data hdata;
+#endif /* def HAVE_GETHOSTBYNAME_R_(6|5)_ARGS */
+#endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
 
    if ((host == NULL) || (*host == '\0'))
    {
@@ -444,10 +758,29 @@ int resolve_hostname_to_ip(const char *host)
 
    if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1)
    {
-      if ((hostp = gethostbyname(host)) == NULL)
+#if defined(HAVE_GETHOSTBYNAME_R_6_ARGS)
+      gethostbyname_r(host, &result, hbuf,
+                      HOSTENT_BUFFER_SIZE, &hostp, &thd_err);
+#elif defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
+      hostp = gethostbyname_r(host, &result, hbuf,
+                      HOSTENT_BUFFER_SIZE, &thd_err);
+#elif defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
+      if (0 == gethostbyname_r(host, &result, &hdata))
+      {
+         hostp = &result;
+      }
+      else
+      {
+         hostp = NULL;
+      }
+#else
+      hostp = gethostbyname(host);
+#endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
+      if (hostp == NULL)
       {
          errno = EINVAL;
-         return(-1);
+         log_error(LOG_LEVEL_ERROR, "could not resolve hostname %s", host);
+         return(INADDR_NONE);
       }
       if (hostp->h_addrtype != AF_INET)
       {
@@ -455,8 +788,9 @@ int resolve_hostname_to_ip(const char *host)
          errno = WSAEPROTOTYPE;
 #else
          errno = EPROTOTYPE;
-#endif
-         return(-1);
+#endif 
+         log_error(LOG_LEVEL_ERROR, "hostname %s resolves to unknown address type.", host);
+         return(INADDR_NONE);
       }
       memcpy(
          (char *) &inaddr.sin_addr,
index 6d77c4c..78f2ee0 100644 (file)
@@ -1,17 +1,17 @@
-#ifndef _JBSOCKETS_H
-#define _JBSOCKETS_H
-#define JBSOCKETS_H_VERSION "$Id: jbsockets.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef JBSOCKETS_H_INCLUDED
+#define JBSOCKETS_H_INCLUDED
+#define JBSOCKETS_H_VERSION "$Id: jbsockets.h,v 1.8 2002/03/26 22:29:54 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/jbsockets.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/jbsockets.h,v $
  *
  * Purpose     :  Contains wrappers for system-specific sockets code,
- *                so that the rest of JunkBuster can be more
+ *                so that the rest of Junkbuster can be more
  *                OS-independent.  Contains #ifdefs to make this work
  *                on many platforms.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: jbsockets.h,v $
+ *    Revision 1.8  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.7  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.6  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.5  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.4  2002/03/07 03:51:36  oes
+ *     - Improved handling of failed DNS lookups
+ *     - Fixed compiler warnings etc
+ *
+ *    Revision 1.3  2001/07/29 19:01:11  jongfoster
+ *    Changed _FILENAME_H to FILENAME_H_INCLUDED.
+ *    Added forward declarations for needed structures.
+ *
+ *    Revision 1.2  2001/06/07 23:06:09  jongfoster
+ *    The host parameter to connect_to() is now const.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:54  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
+#include "project.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern int connect_to(char *host, int portnum, struct client_state *csp);
-extern int write_socket(int fd, const char *buf, int n);
-extern int read_socket(int fd, char *buf, int n);
-extern void close_socket(int fd);
+struct client_state;
+
+extern jb_socket connect_to(const char *host, int portnum, struct client_state *csp);
+extern int write_socket(jb_socket fd, const char *buf, size_t n);
+extern int read_socket(jb_socket fd, char *buf, int n);
+extern void close_socket(jb_socket fd);
 
-extern int bind_port(const char *hostnam, int portnum);
-extern int accept_connection(struct client_state * csp, int fd);
+extern int bind_port(const char *hostnam, int portnum, jb_socket *pfd);
+extern int accept_connection(struct client_state * csp, jb_socket fd);
 
-extern int resolve_hostname_to_ip(const char *host);
+extern unsigned long resolve_hostname_to_ip(const char *host);
 
 /* Revision control strings from this header and associated .c file */
 extern const char jbsockets_rcs[];
@@ -63,7 +114,7 @@ extern const char jbsockets_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _JBSOCKETS_H */
+#endif /* ndef JBSOCKETS_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/jcc.c b/jcc.c
index e6d06bd..62694b0 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,19 +1,19 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.91 2002/04/08 20:35:58 swa Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/jcc.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
  *
- * Purpose     :  Main file.  Contains main() method, main loop, and 
+ * Purpose     :  Main file.  Contains main() method, main loop, and
  *                the main connection-handling function.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -33,6 +33,492 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.1 2001/05/13 21:57:06 administrator Exp $
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.91  2002/04/08 20:35:58  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.90  2002/04/02 14:57:28  oes
+ *    Made sending wafers independent of FEATURE_COOKIE_JAR
+ *
+ *    Revision 1.89  2002/03/31 17:18:59  jongfoster
+ *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
+ *
+ *    Revision 1.88  2002/03/27 14:32:43  david__schmidt
+ *    More compiler warning message maintenance
+ *
+ *    Revision 1.87  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.86  2002/03/25 17:04:55  david__schmidt
+ *    Workaround for closing the jarfile before load_config() comes around again
+ *
+ *    Revision 1.85  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.84  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.83  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.82  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.81  2002/03/12 01:42:50  oes
+ *    Introduced modular filters
+ *
+ *    Revision 1.80  2002/03/11 22:07:05  david__schmidt
+ *    OS/2 port maintenance:
+ *    - Fixed EMX build - it had decayed a little
+ *    - Fixed inexplicable crash during FD_ZERO - must be due to a bad macro.
+ *      substituted a memset for now.
+ *
+ *    Revision 1.79  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.78  2002/03/08 21:35:04  oes
+ *    Added optional group supplement to --user option. Will now use default group of user if no group given
+ *
+ *    Revision 1.77  2002/03/07 03:52:06  oes
+ *     - Fixed compiler warnings etc
+ *     - Improved handling of failed DNS lookups
+ *
+ *    Revision 1.76  2002/03/06 22:54:35  jongfoster
+ *    Automated function-comment nitpicking.
+ *
+ *    Revision 1.75  2002/03/06 10:02:19  oes
+ *    Fixed stupid bug when --user was not given
+ *
+ *    Revision 1.74  2002/03/06 00:49:31  jongfoster
+ *    Fixing warning on Windows
+ *    Making #ifdefs that refer to the same variable consistently
+ *    use #ifdef unix rather than mixing #ifdef unix & #ifndef OS2
+ *
+ *    Revision 1.73  2002/03/05 23:57:30  hal9
+ *    Stray character 's' on line 1618 was breaking build.
+ *
+ *    Revision 1.72  2002/03/05 21:33:45  david__schmidt
+ *    - Re-enable OS/2 building after new parms were added
+ *    - Fix false out of memory report when resolving CGI templates when no IP
+ *      address is available of failed attempt (a la no such domain)
+ *
+ *    Revision 1.71  2002/03/05 18:13:56  oes
+ *    Added --user option
+ *
+ *    Revision 1.70  2002/03/05 04:52:42  oes
+ *    Deleted non-errlog debugging code
+ *
+ *    Revision 1.69  2002/03/04 23:50:00  jongfoster
+ *    Splitting off bind_port() call into bind_port_helper(), with
+ *    improved logging.
+ *
+ *    Revision 1.68  2002/03/04 20:17:32  oes
+ *    Fixed usage info
+ *
+ *    Revision 1.67  2002/03/04 18:18:57  oes
+ *    - Removed _DEBUG mode
+ *    - Cleand up cmdline parsing
+ *    - Introduced --no-daemon, --pidfile options
+ *    - Cleaned up signal handling:
+ *      - Terminate cleanly on INT, TERM and ABRT
+ *      - Schedule logfile for re-opening on HUP
+ *      - Ignore CHLD and PIPE
+ *      - Leave the rest with their default handlers
+ *      - Uniform handler registration
+ *    - Added usage() function
+ *    - Played styleguide police
+ *
+ *    Revision 1.66  2002/03/03 15:06:55  oes
+ *    Re-enabled automatic config reloading
+ *
+ *    Revision 1.65  2002/03/03 14:49:11  oes
+ *    Fixed CLF logging: Now uses client's original HTTP request
+ *
+ *    Revision 1.64  2002/03/03 09:18:03  joergs
+ *    Made jumbjuster work on AmigaOS again.
+ *
+ *    Revision 1.63  2002/03/02 04:14:50  david__schmidt
+ *    Clean up a little CRLF unpleasantness that suddenly appeared
+ *
+ *    Revision 1.62  2002/02/20 23:17:23  jongfoster
+ *    Detecting some out-of memory conditions and exiting with a log message.
+ *
+ *    Revision 1.61  2002/01/17 21:01:52  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Revision 1.60  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.59  2001/12/13 14:07:18  oes
+ *    Fixed Bug: 503 error page now sent OK
+ *
+ *    Revision 1.58  2001/11/30 23:37:24  jongfoster
+ *    Renaming the Win32 config file to config.txt - this is almost the
+ *    same as the corresponding UNIX name "config"
+ *
+ *    Revision 1.57  2001/11/16 00:47:43  jongfoster
+ *    Changing the tty-disconnection code to use setsid().
+ *
+ *    Revision 1.56  2001/11/13 20:20:54  jongfoster
+ *    Tabs->spaces, fixing a bug with missing {} around an if()
+ *
+ *    Revision 1.55  2001/11/13 20:14:53  jongfoster
+ *    Patch for FreeBSD setpgrp() as suggested by Alexander Lazic
+ *
+ *    Revision 1.54  2001/11/07 00:03:14  steudten
+ *    Give reliable return value if an error
+ *    occurs not just 0 with new daemon mode.
+ *
+ *    Revision 1.53  2001/11/05 21:41:43  steudten
+ *    Add changes to be a real daemon just for unix os.
+ *    (change cwd to /, detach from controlling tty, set
+ *    process group and session leader to the own process.
+ *    Add DBG() Macro.
+ *    Add some fatal-error log message for failed malloc().
+ *    Add '-d' if compiled with 'configure --with-debug' to
+ *    enable debug output.
+ *
+ *    Revision 1.52  2001/10/26 20:11:20  jongfoster
+ *    Fixing type mismatch
+ *
+ *    Revision 1.51  2001/10/26 17:38:28  oes
+ *    Cosmetics
+ *
+ *    Revision 1.50  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.49  2001/10/23 21:41:35  jongfoster
+ *    Added call to initialize the (statically-allocated of course)
+ *    "out of memory" CGI response.
+ *
+ *    Revision 1.48  2001/10/10 19:56:46  jongfoster
+ *    Moving some code that wasn't cookie-related out of an #ifdef
+ *    FEATURE_COOKIE_JAR
+ *
+ *    Revision 1.47  2001/10/10 16:44:36  oes
+ *    Added CONNECT destination port limitation check
+ *
+ *    Revision 1.46  2001/10/08 15:17:41  oes
+ *    Re-enabled SSL forwarding
+ *
+ *    Revision 1.45  2001/10/07 15:42:11  oes
+ *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
+ *
+ *    Moved downgrading of the HTTP version from parse_http_request to
+ *      chat(), since we can't decide if it is necessary before we have
+ *      determined the actions for the URL. The HTTP command is now
+ *      *always* re-built so the repairs need no longer be special-cased.
+ *
+ *    filter_popups now gets a csp pointer so it can raise the new
+ *      CSP_FLAG_MODIFIED flag.
+ *
+ *    Bugfix
+ *
+ *    Added configurable size limit for the IOB. If the IOB grows so
+ *      large that the next read would exceed the limit, the header
+ *      is generated, and the header & unfiltered buffer are flushed
+ *      to the client. Chat then continues in non-buffering,
+ *      non-filtering body mode.
+ *
+ *    Revision 1.44  2001/10/02 18:13:57  oes
+ *    Ooops
+ *
+ *    Revision 1.43  2001/10/02 15:32:13  oes
+ *    Moved generation of hdr
+ *
+ *    Revision 1.42  2001/09/21 23:02:02  david__schmidt
+ *    Cleaning up 2 compiler warnings on OS/2.
+ *
+ *    Revision 1.41  2001/09/16 17:05:14  jongfoster
+ *    Removing unused #include showarg.h
+ *
+ *    Revision 1.40  2001/09/16 15:41:45  jongfoster
+ *    Fixing signed/unsigned comparison warning.
+ *
+ *    Revision 1.39  2001/09/16 13:21:27  jongfoster
+ *    Changes to use new list functions.
+ *
+ *    Revision 1.38  2001/09/16 13:01:46  jongfoster
+ *    Removing redundant function call that zeroed zalloc()'d memory.
+ *
+ *    Revision 1.37  2001/09/10 11:12:24  oes
+ *    Deleted unused variable
+ *
+ *    Revision 1.36  2001/09/10 10:56:15  oes
+ *    Silenced compiler warnings
+ *
+ *    Revision 1.35  2001/07/31 14:44:22  oes
+ *    Deleted unused size parameter from filter_popups()
+ *
+ *    Revision 1.34  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.33  2001/07/29 19:32:00  jongfoster
+ *    Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
+ *
+ *    Revision 1.32  2001/07/29 18:47:05  jongfoster
+ *    Adding missing #include "loadcfg.h"
+ *
+ *    Revision 1.31  2001/07/29 12:17:48  oes
+ *    Applied pthread fix by Paul Lieverse
+ *
+ *    Revision 1.30  2001/07/25 22:57:13  jongfoster
+ *    __BEOS__ no longer overrides FEATURE_PTHREAD.
+ *    This is because FEATURE_PTHREAD will soon be widely used, so I
+ *    want to keep it simple.
+ *
+ *    Revision 1.29  2001/07/24 12:47:06  oes
+ *    Applied BeOS support update by Eugenia
+ *
+ *    Revision 1.28  2001/07/23 13:26:12  oes
+ *    Fixed bug in popup-killing for the first read that caused binary garbage to be sent between headers and body
+ *
+ *    Revision 1.27  2001/07/19 19:09:47  haroon
+ *    - Added code to take care of the situation where while processing the first
+ *      server response (which includes the server header), after finding the end
+ *      of the headers we were not looking past the end of the headers for
+ *      content modification. I enabled it for filter_popups.
+ *      Someone else should look to see if other similar operations should be
+ *      done to the discarded portion of the buffer.
+ *
+ *      Note 2001/07/20: No, the other content modification mechanisms will process
+ *                       the whole iob later anyway. --oes
+ *
+ *    Revision 1.26  2001/07/18 12:31:36  oes
+ *    cosmetics
+ *
+ *    Revision 1.25  2001/07/15 19:43:49  jongfoster
+ *    Supports POSIX threads.
+ *    Also removed some unused #includes.
+ *
+ *    Revision 1.24  2001/07/13 14:00:40  oes
+ *     - Generic content modification scheme:
+ *       Each feature has its own applicability flag that is set
+ *       from csp->action->flags.
+ *       Replaced the "filtering" int flag , by a function pointer
+ *       "content_filter" to the function that will do the content
+ *       modification. If it is != NULL, the document will be buffered
+ *       and processed through *content_filter, which must set
+ *       csp->content_length and return a modified copy of the body
+ *       or return NULL (on failiure).
+ *     - Changed csp->is_text to the more generic bitmap csp->content_type
+ *       which can currently take the valued CT_TEXT or CT_GIF
+ *     - Reformatting etc
+ *     - Removed all #ifdef PCRS
+ *
+ *    Revision 1.23  2001/07/02 02:28:25  iwanttokeepanon
+ *    Added "#ifdef ACL_FILES" conditional compilation to line 1291 to exclude
+ *    the `block_acl' call.  This prevents a compilation error when the user
+ *    does not wish to use the "ACL" feature.
+ *
+ *    Revision 1.22  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.21  2001/06/29 13:29:36  oes
+ *    - Cleaned up, improved comments
+ *    - Unified all possible interceptors (CGI,
+ *      block, trust, fast_redirect) in one
+ *      place, with one (CGI) answer generation
+ *      mechansim. Much clearer now.
+ *    - Removed the GIF image generation, which
+ *      is now done in filters.c:block_url()
+ *    - Made error conditions like domain lookup
+ *      failiure or (various) problems while talking
+ *      to the server use cgi.c:error_response()
+ *      instead of generating HTML/HTTP in chat() (yuck!)
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.20  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.19  2001/06/07 23:12:52  jongfoster
+ *    Replacing function pointer in struct gateway with a directly
+ *    called function forwarded_connect().
+ *    Replacing struct gateway with struct forward_spec
+ *
+ *    Revision 1.18  2001/06/03 19:12:16  oes
+ *    introduced new cgi handling
+ *
+ *    Revision 1.17  2001/06/01 20:07:23  jongfoster
+ *    Now uses action +image-blocker{} rather than config->tinygif
+ *
+ *    Revision 1.16  2001/06/01 18:49:17  jongfoster
+ *    Replaced "list_share" with "list" - the tiny memory gain was not
+ *    worth the extra complexity.
+ *
+ *    Revision 1.15  2001/05/31 21:24:47  jongfoster
+ *    Changed "permission" to "action" throughout.
+ *    Removed DEFAULT_USER_AGENT - it must now be specified manually.
+ *    Moved vanilla wafer check into chat(), since we must now
+ *    decide whether or not to add it based on the URL.
+ *
+ *    Revision 1.14  2001/05/29 20:14:01  joergs
+ *    AmigaOS bugfix: PCRS needs a lot of stack, stacksize for child threads
+ *    increased.
+ *
+ *    Revision 1.13  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.12  2001/05/27 22:17:04  oes
+ *
+ *    - re_process_buffer no longer writes the modified buffer
+ *      to the client, which was very ugly. It now returns the
+ *      buffer, which it is then written by chat.
+ *
+ *    - content_length now adjusts the Content-Length: header
+ *      for modified documents rather than crunch()ing it.
+ *      (Length info in csp->content_length, which is 0 for
+ *      unmodified documents)
+ *
+ *    - For this to work, sed() is called twice when filtering.
+ *
+ *    Revision 1.11  2001/05/26 17:27:53  jongfoster
+ *    Added support for CLF and fixed LOG_LEVEL_LOG.
+ *    Also did CRLF->LF fix of my previous patch.
+ *
+ *    Revision 1.10  2001/05/26 15:26:15  jongfoster
+ *    ACL feature now provides more security by immediately dropping
+ *    connections from untrusted hosts.
+ *
+ *    Revision 1.9  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.8  2001/05/25 22:43:18  jongfoster
+ *    Fixing minor memory leak and buffer overflow.
+ *
+ *    Revision 1.7  2001/05/25 22:34:30  jongfoster
+ *    Hard tabs->Spaces
+ *
+ *    Revision 1.6  2001/05/23 00:13:58  joergs
+ *    AmigaOS support fixed.
+ *
+ *    Revision 1.5  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.4  2001/05/21 19:34:01  jongfoster
+ *    Made failure to bind() a fatal error.
+ *
+ *    Revision 1.3  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.2  2001/05/17 22:34:44  oes
+ *     - Added hint on GIF char array generation to jcc.c
+ *     - Cleaned CRLF's from the sources and related files
+ *     - Repaired logging for REF and FRC
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:56  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -47,15 +533,18 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.1 2001/05/13 21:57:06 administrator Exp $
 #include <fcntl.h>
 #include <errno.h>
 
-#ifdef _WIN32
+#ifdef FEATURE_PTHREAD
+#include <pthread.h>
+#endif /* def FEATURE_PTHREAD */
 
-# include <sys/timeb.h>
-# include <windows.h>
-# include <io.h>
-# include <process.h>
-# ifdef TOGGLE
-#  include <time.h>
-# endif /* def TOGGLE */
+#ifdef _WIN32
+# ifndef FEATURE_PTHREAD
+#  ifndef STRICT
+#   define STRICT
+#  endif
+#  include <windows.h>
+#  include <process.h>
+# endif /* ndef FEATURE_PTHREAD */
 
 # include "win32.h"
 # ifndef _WIN_CONSOLE
@@ -64,10 +553,23 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.1 2001/05/13 21:57:06 administrator Exp $
 
 #else /* ifndef _WIN32 */
 
+# if !defined (__OS2__)
 # include <unistd.h>
-# include <sys/time.h>
 # include <sys/wait.h>
+# endif /* ndef __OS2__ */
+# include <sys/time.h>
 # include <sys/stat.h>
+# include <sys/ioctl.h>
+
+#ifdef sun
+#include <sys/termios.h>
+#endif /* sun */
+
+#ifdef unix
+#include <pwd.h>
+#include <grp.h>
+#endif
+
 # include <signal.h>
 
 # ifdef __BEOS__
@@ -75,6 +577,15 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.1 2001/05/13 21:57:06 administrator Exp $
 #  include <OS.h>      /* declarations for threads and stuff. */
 # endif
 
+# if defined(__EMX__) || defined(__OS2__)
+#  include <sys/select.h>  /* OS/2/EMX needs a little help with select */
+# endif
+# ifdef __OS2__
+#define INCL_DOS
+# include <os2.h>
+#define bzero(B,N) memset(B,0x00,n)
+# endif
+
 # ifndef FD_ZERO
 #  include <select.h>
 # endif
@@ -82,120 +593,120 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.1 2001/05/13 21:57:06 administrator Exp $
 #endif
 
 #include "project.h"
+#include "list.h"
 #include "jcc.h"
 #include "filters.h"
 #include "loaders.h"
-#include "showargs.h"
 #include "parsers.h"
 #include "killpopup.h"
 #include "miscutil.h"
 #include "errlog.h"
 #include "jbsockets.h"
 #include "gateway.h"
+#include "actions.h"
+#include "cgi.h"
+#include "loadcfg.h"
+#include "urlmatch.h"
 
 const char jcc_h_rcs[] = JCC_H_VERSION;
 const char project_h_rcs[] = PROJECT_H_VERSION;
 
-const char DEFAULT_USER_AGENT[] ="User-Agent: Mozilla (X11; I; Linux 2.0.32 i586)";
-
+int no_daemon = 0;
 struct client_state  clients[1];
 struct file_list     files[1];
 
-#ifdef STATISTICS
+#ifdef FEATURE_STATISTICS
 int urls_read     = 0;     /* total nr of urls read inc rejected */
 int urls_rejected = 0;     /* total nr of urls rejected */
-#endif /* def STATISTICS */
+#endif /* def FEATURE_STATISTICS */
 
+#ifdef FEATURE_GRACEFUL_TERMINATION
+int g_terminate = 0;
+#endif
 
 static void listen_loop(void);
 static void chat(struct client_state *csp);
+#ifdef AMIGA
+void serve(struct client_state *csp);
+#else /* ifndef AMIGA */
 static void serve(struct client_state *csp);
+#endif /* def AMIGA */
+
 #ifdef __BEOS__
 static int32 server_thread(void *data);
 #endif /* def __BEOS__ */
 
-
-#define BODY   "<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
-
-static const char CFAIL[] =
-   "HTTP/1.0 503 Connect failed\n"
-   "Content-Type: text/html\n\n"
-   "<html>\n"
-   "<head>\n"
-   "<title>Internet Junkbuster: Connect failed</title>\n"
-   "</head>\n"
-   BODY
-   "<h1><center>"
-   BANNER
-   "</center></h1>"
-   "TCP connection to '%s' failed: %s.\n<br>"
-   "</body>\n"
-   "</html>\n";
-
-static const char CNXDOM[] =
-   "HTTP/1.0 404 Non-existent domain\n"
-   "Content-Type: text/html\n\n"
-   "<html>\n"
-   "<head>\n"
-   "<title>Internet Junkbuster: Non-existent domain</title>\n"
-   "</head>\n"
-   BODY
-   "<h1><center>"
-   BANNER
-   "</center></h1>"
-   "No such domain: %s\n"
-   "</body>\n"
-   "</html>\n";
-
-static const char CSUCCEED[] =
-   "HTTP/1.0 200 Connection established\n"
-   "Proxy-Agent: IJ/" VERSION "\n\n";
-
-static const char CHEADER[] =
-   "HTTP/1.0 400 Invalid header received from browser\n\n";
-
-static const char SHEADER[] =
-   "HTTP/1.0 502 Invalid header received from server\n\n";
-
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
-static const char BLANKGIF[] =
-   "HTTP/1.0 200 OK\r\n"
-   "Pragma: no-cache\r\n"
-   "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\r\n"\r
-   "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\r\n"\r
-   "Content-type: image/gif\r\n\r\n"
-   "GIF89a\001\000\001\000\200\000\000\377\377\377\000\000"
-   "\000!\371\004\001\000\000\000\000,\000\000\000\000\001"
-   "\000\001\000\000\002\002D\001\000;";
-
-static const char JBGIF[] =
-   "HTTP/1.0 200 OK\r\n"
-   "Pragma: no-cache\r\n"
-   "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\r\n"\r
-   "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\r\n"\r
-   "Content-type: image/gif\r\n\r\n"
-   "GIF89aD\000\013\000\360\000\000\000\000\000\377\377\377!"
-   "\371\004\001\000\000\001\000,\000\000\000\000D\000\013\000"
-   "\000\002a\214\217\251\313\355\277\000\200G&K\025\316hC\037"
-   "\200\234\230Y\2309\235S\230\266\206\372J\253<\3131\253\271"
-   "\270\215\342\254\013\203\371\202\264\334P\207\332\020o\266"
-   "N\215I\332=\211\312\3513\266:\026AK)\364\370\365aobr\305"
-   "\372\003S\275\274k2\354\254z\347?\335\274x\306^9\374\276"
-   "\037Q\000\000;";
-\r
-static const char FWGIF[] =\r
-   "HTTP/1.0 302 Blocked Advert\r\n" \r
-   "Pragma: no-cache\r\n"\r
-   "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\r\n"\r
-   "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\r\n"\r
-   "Location: ";\r
-\r
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
-
 #ifdef _WIN32
 #define sleep(N)  Sleep(((N) * 1000))
 #endif
 
+#ifdef __OS2__
+#define sleep(N)  DosSleep(((N) * 100))
+#endif
+
+#if defined(unix) || defined(__EMX__)
+const char *basedir;
+const char *pidfile = NULL;
+int received_hup_signal = 0;
+#endif /* defined unix */
+
+/* The vanilla wafer. */
+static const char VANILLA_WAFER[] =
+   "NOTICE=TO_WHOM_IT_MAY_CONCERN_"
+   "Do_not_send_me_any_copyrighted_information_other_than_the_"
+   "document_that_I_am_requesting_or_any_of_its_necessary_components._"
+   "In_particular_do_not_send_me_any_cookies_that_"
+   "are_subject_to_a_claim_of_copyright_by_anybody._"
+   "Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"
+   "(copyright_or_otherwise)_applying_to_any_cookie._";
+
+
+#if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
+/*********************************************************************
+ *
+ * Function    :  sig_handler 
+ *
+ * Description :  Signal handler for different signals.
+ *                Exit gracefully on ABRT, TERM and  INT
+ *                or set a flag that will cause the errlog
+ *                to be reopened by the main thread on HUP.
+ *
+ * Parameters  :
+ *          1  :  the_signal = the signal cause this function to call
+ *
+ * Returns     :  - 
+ *
+ *********************************************************************/
+static void sig_handler(int the_signal)
+{
+   switch(the_signal)
+   {
+      case SIGABRT:
+      case SIGTERM:
+      case SIGINT:
+         log_error(LOG_LEVEL_INFO, "exiting by signal %d .. bye", the_signal);
+#if defined(unix)
+         unlink(pidfile);
+#endif /* unix */
+         exit(the_signal);
+         break;
+
+      case SIGHUP:
+         received_hup_signal = 1;
+         break;         
+
+      default:
+         /* 
+          * We shouldn't be here, unless we catch signals
+          * in main() that we can't handle here!
+          */
+         log_error(LOG_LEVEL_FATAL, "sig_handler: exiting on unexpected signal %d", the_signal);
+   }
+   return;
+
+}
+#endif
+
 
 /*********************************************************************
  *
@@ -203,7 +714,7 @@ static const char FWGIF[] =
  *
  * Description :  Once a connection to the client has been accepted,
  *                this function is called (via serve()) to handle the
- *                main business of the communication.  When this 
+ *                main business of the communication.  When this
  *                function returns, the caller must close the client
  *                socket handle.
  *
@@ -220,17 +731,51 @@ static const char FWGIF[] =
  *********************************************************************/
 static void chat(struct client_state *csp)
 {
-   char buf[BUFSIZ], *hdr, *p, *req;
-   char *err = NULL;
-   char *eno;
+/*
+ * This next lines are a little ugly, but they simplifies the if statements
+ * below.  Basically if TOGGLE, then we want the if to test if the
+ * CSP_FLAG_TOGGLED_ON flag ist set, else we don't.  And if FEATURE_FORCE_LOAD,
+ * then we want the if to test for CSP_FLAG_FORCED , else we don't
+ */
+#ifdef FEATURE_TOGGLE
+#   define IS_TOGGLED_ON_AND (csp->flags & CSP_FLAG_TOGGLED_ON) &&
+#else /* ifndef FEATURE_TOGGLE */
+#   define IS_TOGGLED_ON_AND
+#endif /* ndef FEATURE_TOGGLE */
+#ifdef FEATURE_FORCE_LOAD
+#   define IS_NOT_FORCED_AND !(csp->flags & CSP_FLAG_FORCED) &&
+#else /* ifndef FEATURE_FORCE_LOAD */
+#   define IS_NOT_FORCED_AND
+#endif /* def FEATURE_FORCE_LOAD */
+
+#define IS_ENABLED_AND   IS_TOGGLED_ON_AND IS_NOT_FORCED_AND
+
+   char buf[BUFFER_SIZE];
+   char *hdr;
+   char *p;
+   char *req;
    fd_set rfds;
-   int n, maxfd, server_body, ms_iis5_hack = 0;
-   struct cookie_spec *cs;
-   const struct gateway *gw;
+   int n;
+   jb_socket maxfd;
+   int server_body;
+   int ms_iis5_hack = 0;
+   int byte_count = 0;
+   const struct forward_spec * fwd;
    struct http_request *http;
-#ifdef PCRS
-   int filtering = 0;
-#endif /* def PCRS */
+   int len; /* for buffer sizes */
+#ifdef FEATURE_KILL_POPUPS
+   int block_popups;         /* bool, 1==will block popups */
+   int block_popups_now = 0; /* bool, 1==currently blocking popups */
+#endif /* def FEATURE_KILL_POPUPS */
+
+   int pcrs_filter;        /* bool, 1==will filter through pcrs */
+   int gif_deanimate;      /* bool, 1==will deanimate gifs */
+
+   /* Function that does the content filtering for the current request */
+   char *(*content_filter)() = NULL;
+
+   /* Skeleton for HTTP response, if we should intercept the request */
+   struct http_response *rsp;
 
    http = csp->http;
 
@@ -239,43 +784,47 @@ static void chat(struct client_state *csp)
     * could get blocked here if a client connected, then didn't say anything!
     */
 
-   while (FOREVER)
+   for (;;)
    {
-      n = read_socket(csp->cfd, buf, sizeof(buf));
+      len = read_socket(csp->cfd, buf, sizeof(buf));
 
-      if (n <= 0) break;      /* error! */
-
-      add_to_iob(csp, buf, n);
+      if (len <= 0) break;      /* error! */
+      
+      /*
+       * If there is no memory left for buffering the
+       * request, there is nothing we can do but hang up
+       */
+      if (add_to_iob(csp, buf, len))
+      {
+         return;
+      }
 
       req = get_header(csp);
 
-      if (req == NULL)\r
-      {\r
-         break;    /* no HTTP request! */\r
+      if (req == NULL)
+      {
+         break;    /* no HTTP request! */
       }
 
-      if (*req == '\0')\r
-      {\r
-         continue;   /* more to come! */\r
+      if (*req == '\0')
+      {
+         continue;   /* more to come! */
       }
-#ifdef FORCE_LOAD
+
+#ifdef FEATURE_FORCE_LOAD
       /* If this request contains the FORCE_PREFIX,
-                * better get rid of it now and set the force flag --oes
+       * better get rid of it now and set the force flag --oes
        */
 
-               if(strstr(req, FORCE_PREFIX))
-      {
-                  strclean(req, FORCE_PREFIX);
-                  /* if DEBUG(FRC) fprintf(logfp, "%s: Enforcing request \"%s\".\n", prog, req); */
-                  csp->force = 1;
-               } 
-      else
+      if (strstr(req, FORCE_PREFIX))
       {
-                  csp->force = 0;
-               }
-#endif /* def FORCE_LOAD */
-  
+         strclean(req, FORCE_PREFIX);
+         log_error(LOG_LEVEL_FORCE, "Enforcing request \"%s\".\n", req);
+         csp->flags |= CSP_FLAG_FORCED;
+      }
+
+#endif /* def FEATURE_FORCE_LOAD */
+
       parse_http_request(req, http, csp);
       freez(req);
       break;
@@ -285,102 +834,193 @@ static void chat(struct client_state *csp)
    {
       strcpy(buf, CHEADER);
       write_socket(csp->cfd, buf, strlen(buf));
+
+      log_error(LOG_LEVEL_CLF, "%s - - [%T] \" \" 400 0", csp->ip_addr_str);
+
       return;
    }
 
    /* decide how to route the HTTP request */
 
-   if ((gw = forward_url(http, csp)) == NULL)
+   if ((fwd = forward_url(http, csp)) == NULL)
    {
-      log_error(LOG_LEVEL_ERROR, "gateway spec is NULL!?!?  This can't happen!");
-      abort();
+      log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!?  This can't happen!");
+      /* Never get here - LOG_LEVEL_FATAL causes program exit */
    }
 
    /* build the http request to send to the server
     * we have to do one of the following:
     *
     * create = use the original HTTP request to create a new
-    *          HTTP request that has only the path component
-    *          without the http://domainspec
-    * pass   = pass the original HTTP request unchanged
+    *          HTTP request that has either the path component
+    *          without the http://domainspec (w/path) or the
+    *          full orininal URL (w/url)
+    *          Note that the path and/or the HTTP version may
+    *          have been altered by now.
     *
-    * drop   = drop the HTTP request
+    * connect = Open a socket to the host:port of the server
+    *           and short-circuit server and client socket.
+    *
+    * pass =  Pass the request unchanged if forwarding a CONNECT
+    *         request to a parent proxy. Note that we'll be sending
+    *         the CFAIL message ourselves if connecting to the parent
+    *         fails, but we won't send a CSUCCEED message if it works,
+    *         since that would result in a double message (ours and the
+    *         parent's). After sending the request to the parent, we simply
+    *         tunnel.
     *
     * here's the matrix:
     *                        SSL
     *                    0        1
     *                +--------+--------+
     *                |        |        |
-    *             0  | create | drop   |
-    *                |        |        |
+    *             0  | create | connect|
+    *                | w/path |        |
     *  Forwarding    +--------+--------+
     *                |        |        |
-    *             1  | pass   | pass   |
-    *                |        |        |
+    *             1  | create | pass   |
+    *                | w/url  |        |
     *                +--------+--------+
     *
     */
 
-   if (gw->forward_host)
+   /*
+    * Determine the actions for this URL
+    */
+#ifdef FEATURE_TOGGLE
+   if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
    {
-      /* if forwarding, just pass the request as is */
-      enlist(csp->headers, http->cmd);
+      /* Most compatible set of actions (i.e. none) */
+      init_current_action(csp->action);
    }
    else
+#endif /* ndef FEATURE_TOGGLE */
    {
-      if (http->ssl == 0)
+      url_actions(http, csp);
+   }
+
+
+   /*
+    * Check if a CONNECT request is allowable:
+    * In the absence of a +limit-connect action, allow only port 443.
+    * If there is an action, allow whatever matches the specificaton.
+    */
+   if(http->ssl)
+   {
+      if(  ( !(csp->action->flags & ACTION_LIMIT_CONNECT) && csp->http->port != 443)
+           || (csp->action->flags & ACTION_LIMIT_CONNECT
+              && !match_portlist(csp->action->string[ACTION_STRING_LIMIT_CONNECT], csp->http->port)) )
       {
-         /* otherwise elide the host information from the url */
-         p = NULL;
-         p = strsav(p, http->gpc);
-         p = strsav(p, " ");
-         p = strsav(p, http->path);
-         p = strsav(p, " ");
-         p = strsav(p, http->ver);
-         enlist(csp->headers, p);
-         freez(p);
+         strcpy(buf, CFORBIDDEN);
+         write_socket(csp->cfd, buf, strlen(buf));
+
+         log_error(LOG_LEVEL_CONNECT, "Denying suspicious CONNECT request from %s", csp->ip_addr_str);
+         log_error(LOG_LEVEL_CLF, "%s - - [%T] \" \" 403 0", csp->ip_addr_str);
+
+         return;
       }
    }
 
-   /* decide what we're to do with cookies */
 
-#if defined(TOGGLE)
    /*
-    * by haroon - most of credit to srt19170
-    * if toggled_on flag is false IJB is disabled, pass cookies thru
+    * Downgrade http version from 1.1 to 1.0 if +downgrade
+    * action applies
     */
-   if (!csp->toggled_on)
+   if ( (http->ssl == 0)
+     && (!strcmpic(http->ver, "HTTP/1.1"))
+     && (csp->action->flags & ACTION_DOWNGRADE))
    {
-      csp->accept_server_cookie  = 1;
-      csp->send_user_cookie      = 1;
+      freez(http->ver);
+      http->ver = strdup("HTTP/1.0");
+
+      if (http->ver == NULL)
+      {
+         log_error(LOG_LEVEL_FATAL, "Out of memory downgrading HTTP version");
+      }
    }
-   else
-#endif
 
-   if ((cs = cookie_url(http, csp)))
+   /* 
+    * Save a copy of the original request for logging
+    */
+   http->ocmd = strdup(http->cmd);
+
+   if (http->ocmd == NULL)
    {
-      csp->accept_server_cookie  = cs->accept_server_cookie;
-      csp->send_user_cookie      = cs->send_user_cookie;
+      log_error(LOG_LEVEL_FATAL, "Out of memory copying HTTP request line");
    }
-   else
+
+   /*
+    * (Re)build the HTTP request for non-SSL requests.
+    * If forwarding, use the whole URL, else, use only the path.
+    */
+   if (http->ssl == 0)
+   {
+      freez(http->cmd);
+
+      http->cmd = strdup(http->gpc);
+      string_append(&http->cmd, " ");
+
+      if (fwd->forward_host)
+      {
+         string_append(&http->cmd, http->url);
+      }
+      else
+      {
+         string_append(&http->cmd, http->path);
+      }
+
+      string_append(&http->cmd, " ");
+      string_append(&http->cmd, http->ver);
+
+      if (http->cmd == NULL)
+      {
+         log_error(LOG_LEVEL_FATAL, "Out of memory rewiting SSL command");
+      }
+   }
+   enlist(csp->headers, http->cmd);
+
+
+   /*
+    * If the user has not supplied any wafers, and the user has not
+    * told us to suppress the vanilla wafer, then send the vanilla wafer.
+    */
+   if (list_is_empty(csp->action->multi[ACTION_MULTI_WAFER])
+       && ((csp->action->flags & ACTION_VANILLA_WAFER) != 0))
    {
-      csp->accept_server_cookie  = 0;
-      csp->send_user_cookie      = 0;
+      enlist(csp->action->multi[ACTION_MULTI_WAFER], VANILLA_WAFER);
    }
 
+
+#ifdef FEATURE_KILL_POPUPS
+   block_popups               = ((csp->action->flags & ACTION_NO_POPUPS) != 0);
+#endif /* def FEATURE_KILL_POPUPS */
+
+   pcrs_filter                = (csp->rlist != NULL) &&  /* There are expressions to be used */
+                                (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]));
+
+   gif_deanimate              = ((csp->action->flags & ACTION_DEANIMATE) != 0);
+
    /* grab the rest of the client's headers */
 
-   while (FOREVER)
+   for (;;)
    {
-      if ( ( p = get_header(csp) ) && ( *p == '\0' ) )
+      if ( ( ( p = get_header(csp) ) != NULL) && ( *p == '\0' ) )
       {
-         n = read_socket(csp->cfd, buf, sizeof(buf));
-         if (n <= 0)
+         len = read_socket(csp->cfd, buf, sizeof(buf));
+         if (len <= 0)
          {
             log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
             return;
          }
-         add_to_iob(csp, buf, n);
+         
+         /*
+          * If there is no memory left for buffering the
+          * request, there is nothing we can do but hang up
+          */
+         if (add_to_iob(csp, buf, len))
+         {
+            return;
+         }
          continue;
       }
 
@@ -389,105 +1029,61 @@ static void chat(struct client_state *csp)
       enlist(csp->headers, p);
       freez(p);
    }
-
-   /* filter it as required */
-
-   hdr = sed(client_patterns, add_client_headers, csp);
-
-   destroy_list(csp->headers);
-
-#ifdef TOGGLE
    /*
-    * by haroon - most of credit to srt19170
-    * if toggled_on flag is true then IJB is enabled, do the usual
-    * otherwise avoid crunching
+    * We have a request. Now, check to see if we need to
+    * intercept it, i.e. If ..
     */
 
-/* This next line is a little ugly, but it simplifies the if statement below. */
-/* Basically if TOGGLE, then we want the if to test "csp->toggled_on", else we don't */
-#define IS_TOGGLED_ON csp->toggled_on &&
-
-#else /* ifndef TOGGLE */
-
-/* We don't have TOGGLE, so we don't care about toggling. */
-#define IS_TOGGLED_ON
-
-#endif /* ndef TOGGLE */
+   if (
+       /* a CGI call was detected and answered */
+       (NULL != (rsp = dispatch_cgi(csp)))
 
+       /* or we are enabled and... */
+       || (IS_ENABLED_AND (
 
-#ifdef TRUST_FILES
-/* This next line is a little ugly, but it simplifies the if statement below. */
-/* Basically if TRUST_FILES, then we want the if to call "trust_url", else we don't */
-#define IS_TRUSTED_URL (p = trust_url(http, csp)) ||
+            /* ..the request was blocked */
+          ( NULL != (rsp = block_url(csp)))
 
-#else /* ifndef TRUST_FILES */
+          /* ..or untrusted */
+#ifdef FEATURE_TRUST
+          || ( NULL != (rsp = trust_url(csp)))
+#endif /* def FEATURE_TRUST */
 
-/* We don't have TRUST_FILES, so we don't care about trusted URL's. */
-#define IS_TRUSTED_URL
-
-#endif /* ndef TRUST_FILES */
-
-
-       /* Check the request against all rules, unless
-        * we're disabled or in force mode. 
-    */
-   if (IS_TOGGLED_ON
-#ifdef FORCE_LOAD
-       (!csp->force) && 
-#endif /* def FORCE_LOAD */
-       ( (p = intercept_url(http, csp)) ||
-         IS_TRUSTED_URL
-         (p = block_url(http, csp)) ))
+          /* ..or a fast redirect kicked in */
+#ifdef FEATURE_FAST_REDIRECTS
+          || (((csp->action->flags & ACTION_FAST_REDIRECTS) != 0) &&
+                (NULL != (rsp = redirect_url(csp))))
+#endif /* def FEATURE_FAST_REDIRECTS */
+          ))
+      )
    {
-#ifdef STATISTICS
-      csp->rejected = 1;
-#endif /* def STATISTICS */
-
-      log_error(LOG_LEVEL_GPC, "%s%s crunch!", http->hostport, http->path);
-
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
-      /* now use block_imageurl */
-      if ( (tinygif > 0) && block_imageurl(http, csp) )
-      {
-         /* Send "blocked" image */
-         log_error(LOG_LEVEL_GPC, "%s%s image crunch!",
-                   http->hostport, http->path);
-
-         if (tinygif == 1)
-         {
-            write_socket(csp->cfd, BLANKGIF, sizeof(BLANKGIF)-1);
-         }
-         else if ((tinygif == 3) && (tinygifurl))\r
-         {\r
-            write_socket(csp->cfd, FWGIF, sizeof(FWGIF)-1);\r
-            write_socket(csp->cfd, tinygifurl, strlen(tinygifurl));\r
-         }\r
-         else
-         {
-            write_socket(csp->cfd, JBGIF, sizeof(JBGIF)-1);
-         }
-      }
-      else
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
+      /* Write the answer to the client */
+      if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+       || write_socket(csp->cfd, rsp->body, rsp->content_length))
       {
-         /* Send HTML "blocked" message */
-         write_socket(csp->cfd, p, strlen(p));
+         log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
       }
 
-      log_error(LOG_LEVEL_LOG, "%s", p);
+#ifdef FEATURE_STATISTICS
+      /* Count as a rejected request */
+      csp->flags |= CSP_FLAG_REJECTED;
+#endif /* def FEATURE_STATISTICS */
 
-      freez(p);
-      freez(hdr);
+      /* Log (FIXME: All intercept reasons apprear as "crunch" with Status 200) */
+      log_error(LOG_LEVEL_GPC, "%s%s crunch!", http->hostport, http->path);
+      log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 3", csp->ip_addr_str, http->ocmd);
+
+      /* Clean up and return */
+      free_http_response(rsp);
       return;
    }
 
    log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
 
-   if (gw->forward_host)
+   if (fwd->forward_host)
    {
       log_error(LOG_LEVEL_CONNECT, "via %s:%d to: %s",
-               gw->forward_host, gw->forward_port, http->hostport);
+               fwd->forward_host, fwd->forward_port, http->hostport);
    }
    else
    {
@@ -496,56 +1092,81 @@ static void chat(struct client_state *csp)
 
    /* here we connect to the server, gateway, or the forwarder */
 
-   csp->sfd = (gw->conn)(gw, http, csp);
+   csp->sfd = forwarded_connect(fwd, http, csp);
 
-   if (csp->sfd < 0)
+   if (csp->sfd == JB_INVALID_SOCKET)
    {
       log_error(LOG_LEVEL_CONNECT, "connect to: %s failed: %E",
                 http->hostport);
 
       if (errno == EINVAL)
       {
-         err = zalloc(strlen(CNXDOM) + strlen(http->host));
-         sprintf(err, CNXDOM, http->host);
+         rsp = error_response(csp, "no-such-domain", errno);
+
+         log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 404 0",
+                   csp->ip_addr_str, http->ocmd);
       }
       else
       {
-         eno = safe_strerror(errno);
-         err = zalloc(strlen(CFAIL) + strlen(http->hostport) + strlen(eno));
-         sprintf(err, CFAIL, http->hostport, eno);
+         rsp = error_response(csp, "connect-failed", errno);
+
+         log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
+                   csp->ip_addr_str, http->ocmd);
       }
 
-      write_socket(csp->cfd, err, strlen(err));
 
-      log_error(LOG_LEVEL_LOG, err);
+      /* Write the answer to the client */
+      if(rsp)
+      {
+         if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+          || write_socket(csp->cfd, rsp->body, rsp->content_length))
+         {
+            log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
+         }
+      }
 
-      freez(err);
-      freez(hdr);
+      free_http_response(rsp);
       return;
    }
 
    log_error(LOG_LEVEL_CONNECT, "OK");
 
-   if (gw->forward_host || (http->ssl == 0))
+   hdr = sed(client_patterns, add_client_headers, csp);
+   if (hdr == NULL)
+   {
+      /* FIXME Should handle error properly */
+      log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
+   }
+
+   list_remove_all(csp->headers);
+
+   if (fwd->forward_host || (http->ssl == 0))
    {
       /* write the client's (modified) header to the server
        * (along with anything else that may be in the buffer)
        */
 
-      n = strlen(hdr);
-
-      if ((write_socket(csp->sfd, hdr, n) != n)
-          || (flush_socket(csp->sfd, csp   ) <  0))
+      if (write_socket(csp->sfd, hdr, strlen(hdr))
+       || (flush_socket(csp->sfd, csp) <  0))
       {
          log_error(LOG_LEVEL_CONNECT, "write header to: %s failed: %E",
                     http->hostport);
 
-         eno = safe_strerror(errno);
-         err = zalloc(strlen(CFAIL) + strlen(http->hostport) + strlen(eno));
-         sprintf(err, CFAIL, http->hostport, eno);
-         write_socket(csp->cfd, err, strlen(err));
+         log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
+                   csp->ip_addr_str, http->ocmd);
+
+         rsp = error_response(csp, "connect-failed", errno);
 
-         freez(err);
+         if(rsp)
+         {
+            if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+             || write_socket(csp->cfd, rsp->body, rsp->content_length))
+            {
+               log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
+            }
+         }
+
+         free_http_response(rsp);
          freez(hdr);
          return;
       }
@@ -557,7 +1178,10 @@ static void chat(struct client_state *csp)
        * so just send the "connect succeeded" message to the
        * client, flush the rest, and get out of the way.
        */
-      if (write_socket(csp->cfd, CSUCCEED, sizeof(CSUCCEED)-1) < 0)
+      log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 2\n",
+                csp->ip_addr_str, http->ocmd);
+
+      if (write_socket(csp->cfd, CSUCCEED, sizeof(CSUCCEED)-1))
       {
          freez(hdr);
          return;
@@ -576,14 +1200,21 @@ static void chat(struct client_state *csp)
 
    server_body = 0;
 
-   while (FOREVER)
+   for (;;)
    {
+#ifdef __OS2__
+      /*
+       * FD_ZERO here seems to point to an errant macro which crashes.
+       * So do this by hand for now...
+       */
+      memset(&rfds,0x00,sizeof(fd_set));
+#else
       FD_ZERO(&rfds);
-
+#endif
       FD_SET(csp->cfd, &rfds);
       FD_SET(csp->sfd, &rfds);
 
-      n = select(maxfd+1, &rfds, NULL, NULL, NULL);
+      n = select((int)maxfd+1, &rfds, NULL, NULL, NULL);
 
       if (n < 0)
       {
@@ -597,11 +1228,14 @@ static void chat(struct client_state *csp)
 
       if (FD_ISSET(csp->cfd, &rfds))
       {
-         n = read_socket(csp->cfd, buf, sizeof(buf));
+         len = read_socket(csp->cfd, buf, sizeof(buf));
 
-         if (n <= 0) break; /* "game over, man" */
+         if (len <= 0)
+         {
+            break; /* "game over, man" */
+         }
 
-         if (write_socket(csp->sfd, buf, n) != n)
+         if (write_socket(csp->sfd, buf, (size_t)len))
          {
             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
             return;
@@ -612,40 +1246,49 @@ static void chat(struct client_state *csp)
       /*
        * The server wants to talk.  It could be the header or the body.
        * If `hdr' is null, then it's the header otherwise it's the body.
-       * FIXME: Does `hdr' really mean `host'?
+       * FIXME: Does `hdr' really mean `host'? No.
        */
 
 
       if (FD_ISSET(csp->sfd, &rfds))
       {
          fflush( 0 );
-         n = read_socket(csp->sfd, buf, sizeof(buf) - 1);
+         len = read_socket(csp->sfd, buf, sizeof(buf) - 1);
 
-         if (n < 0)
+         if (len < 0)
          {
             log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
 
-            eno = safe_strerror(errno);
-            sprintf(buf, CFAIL, http->hostport, eno);
-            freez(eno);
-            write_socket(csp->cfd, buf, strlen(buf));
+            log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
+                      csp->ip_addr_str, http->ocmd);
+
+            rsp = error_response(csp, "connect-failed", errno);
+
+            if(rsp)
+            {
+               if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+                || write_socket(csp->cfd, rsp->body, rsp->content_length))
+               {
+                  log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
+               }
+            }
+
+            free_http_response(rsp);
             return;
          }
 
          /* Add a trailing zero.  This lets filter_popups
           * use string operations.
           */
-         buf[n] = '\0';
+         buf[len] = '\0';
 
-#ifdef KILLPOPUPS
+#ifdef FEATURE_KILL_POPUPS
          /* Filter the popups on this read. */
-         if ( IS_TOGGLED_ON
-              ( kill_all_popups ||
-              ( ( http->host != NULL ) && ( popupfile != NULL ) ) ) )
+         if (block_popups_now)
          {
-            filter_popups(csp, http->host, buf, n);
+            filter_popups(buf, csp);
          }
-#endif /* def KILLPOPUPS */
+#endif /* def FEATURE_KILL_POPUPS */
 
          /* Normally, this would indicate that we've read
           * as much as the server has sent us and we can
@@ -665,22 +1308,56 @@ static void chat(struct client_state *csp)
           * doesn't generate a valid header, then we won't
           * transmit anything to the client.
           */
-         if (n == 0)
+         if (len == 0)
          {
-            /* This hack must only be enforced for headers. */
+
             if (server_body || http->ssl)
             {
-#ifdef PCRS
-               if (filtering)
+               /*
+                * If we have been buffering up the document,
+                * now is the time to apply content modification
+                * and send the result to the client.
+                */
+               if (content_filter)
                {
-                  re_process_buffer(csp);
+                  /*
+                   * If the content filter fails, use the original
+                   * buffer and length.
+                   * (see p != NULL ? p : csp->iob->cur below)
+                   */
+                  if (NULL == (p = (*content_filter)(csp)))
+                  {
+                     csp->content_length = csp->iob->eod - csp->iob->cur;
+                  }
+
+                  hdr = sed(server_patterns, add_server_headers, csp);
+                  if (hdr == NULL)
+                  {
+                     /* FIXME Should handle error properly */
+                     log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
+                  }
+
+                  if (write_socket(csp->cfd, hdr, strlen(hdr))
+                   || write_socket(csp->cfd, p != NULL ? p : csp->iob->cur, csp->content_length))
+                  {
+                     log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
+                     return;
+                  }
+
+                  freez(hdr);
+                  if (NULL != p) {
+                     freez(p);
+                  }
                }
-#endif /* def PCRS */
+
                break; /* "game over, man" */
             }
 
-            /* Let's pretend the server just sent us a blank line. */
-            n = sprintf(buf, "\r\n");
+            /*
+             * This is NOT the body, so
+             * Let's pretend the server just sent us a blank line.
+             */
+            len = sprintf(buf, "\r\n");
 
             /*
              * Now, let the normal header parsing algorithm below do its
@@ -692,26 +1369,72 @@ static void chat(struct client_state *csp)
 
          /*
           * If this is an SSL connection or we're in the body
-          * of the server document, just write it to the client.
+          * of the server document, just write it to the client,
+          * unless we need to buffer the body for later content-filtering
           */
 
          if (server_body || http->ssl)
          {
-#ifdef PCRS
-            if (filtering)
+            if (content_filter)
             {
-               add_to_iob(csp, buf, n); /* Buffer the body for filtering */
+               /*
+                * If there is no memory left for buffering the content, or the buffer limit
+                * has been reached, switch to non-filtering mode, i.e. make & write the
+                * header, flush the iob and buf, and get out of the way.
+                */
+               if (add_to_iob(csp, buf, len))
+               {
+                  size_t hdrlen;
+                  int flushed;
+
+                  log_error(LOG_LEVEL_ERROR, "Flushing header and buffers. Stepping back from filtering.");
+
+                  hdr = sed(server_patterns, add_server_headers, csp);
+                  if (hdr == NULL)
+                  {
+                     /* 
+                      * Memory is too tight to even generate the header.
+                      * Send our static "Out-of-memory" page.
+                      */
+                     log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
+                     rsp = cgi_error_memory();
+
+                     if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+                         || write_socket(csp->cfd, rsp->body, rsp->content_length))
+                     {
+                        log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
+                     }
+                     return;
+                  }
+
+                  hdrlen = strlen(hdr);
+
+                  if (write_socket(csp->cfd, hdr, hdrlen)
+                   || ((flushed = flush_socket(csp->cfd, csp)) < 0)
+                   || (write_socket(csp->cfd, buf, len)))
+                  {
+                     log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E");
+
+                     freez(hdr);
+                     return;
+                  }
+
+                  byte_count += hdrlen + flushed + len;
+                  freez(hdr);
+                  content_filter = NULL;
+                  server_body = 1;
+
+               }
             }
             else
-#endif /* def PCRS */
             {
-               /* just write */
-               if (write_socket(csp->cfd, buf, n) != n)
+               if (write_socket(csp->cfd, buf, (size_t)len))
                {
                   log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
                   return;
                }
             }
+            byte_count += len;
             continue;
          }
          else
@@ -721,12 +1444,27 @@ static void chat(struct client_state *csp)
              * parsing an "out of body experience" ?
              */
 
-            /* buffer up the data we just read */
-            add_to_iob(csp, buf, n);
+            /* 
+             * buffer up the data we just read.  If that fails, 
+             * there's little we can do but send our static
+             * out-of-memory page.
+             */
+            if (add_to_iob(csp, buf, len))
+            {
+               log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
+               rsp = cgi_error_memory();
+               
+               if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+                   || write_socket(csp->cfd, rsp->body, rsp->content_length))
+               {
+                  log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
+               }
+               return;
+            }
 
             /* get header lines from the iob */
 
-            while ((p = get_header(csp)))
+            while ((p = get_header(csp)) != NULL)
             {
                if (*p == '\0')
                {
@@ -771,47 +1509,71 @@ static void chat(struct client_state *csp)
              */
 
             hdr = sed(server_patterns, add_server_headers, csp);
-            n   = strlen(hdr);
-
-            /* write the server's (modified) header to
-             * the client (along with anything else that
-             * may be in the buffer)
-             */
+            if (hdr == NULL)
+            {
+               /* FIXME Should handle error properly */
+               log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
+            }
 
-#ifdef PCRS
-            /* Decide if we want to re_filter this. */
+#ifdef FEATURE_KILL_POPUPS
+            /* Start blocking popups if appropriate. */
 
-            if (IS_TOGGLED_ON     /* Only filter if toggle is "on" */
-                csp->is_text  &&  /* It's a text / * MIME-Type */
-                re_filterfile &&  /* There are expressions to be used */
-                !http->ssl    &&  /* We talk plaintext */
-                (re_filter_all || !csp->send_user_cookie)) /* Policy allows */
+            if ((csp->content_type & CT_TEXT) &&  /* It's a text / * MIME-Type */
+                !http->ssl    &&                  /* We talk plaintext */
+                block_popups)                     /* Policy allows */
             {
-               filtering = 1;
+               block_popups_now = 1;
+               /*
+                * Filter the part of the body that came in the same read
+                * as the last headers:
+                */
+               filter_popups(csp->iob->cur, csp);
             }
 
-/* This next line is a little ugly, but it simplifies the if statement below. */
-/* Basically if using PCRS, we want the OR condition to require "!filtering"  */
-#define NOT_FILTERING_AND !filtering &&
+#endif /* def FEATURE_KILL_POPUPS */
 
-#else /* not def PCRS */
+            /* Buffer and pcrs filter this if appropriate. */
 
-#define NOT_FILTERING_AND
+            if ((csp->content_type & CT_TEXT) &&  /* It's a text / * MIME-Type */
+                !http->ssl    &&                  /* We talk plaintext */
+                pcrs_filter)                      /* Policy allows */
+            {
+               content_filter = pcrs_filter_response;
+            }
+
+            /* Buffer and gif_deanimate this if appropriate. */
+
+            if ((csp->content_type & CT_GIF)  &&  /* It's a image/gif MIME-Type */
+                !http->ssl    &&                  /* We talk plaintext */
+                gif_deanimate)                    /* Policy allows */
+            {
+               content_filter = gif_deanimate_response;
+            }
 
-#endif /* def PCRS */
+            /*
+             * Only write if we're not buffering for content modification
+             */
+            if (!content_filter)
+            {
+               /* write the server's (modified) header to
+                * the client (along with anything else that
+                * may be in the buffer)
+                */
 
+               if (write_socket(csp->cfd, hdr, strlen(hdr))
+                || ((len = flush_socket(csp->cfd, csp)) < 0))
+               {
+                  log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
 
-            if ((write_socket(csp->cfd, hdr, n) != n)
-                || (NOT_FILTERING_AND (flush_socket(csp->cfd, csp) < 0)))
-            {
-               log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
+                  /* the write failed, so don't bother
+                   * mentioning it to the client...
+                   * it probably can't hear us anyway.
+                   */
+                  freez(hdr);
+                  return;
+               }
 
-               /* the write failed, so don't bother
-                * mentioning it to the client...
-                * it probably can't hear us anyway.
-                */
-               freez(hdr);
-               return;
+               byte_count += len;
             }
 
             /* we're finished with the server's header */
@@ -835,7 +1597,8 @@ static void chat(struct client_state *csp)
       return; /* huh? we should never get here */
    }
 
-
+   log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %d",
+             csp->ip_addr_str, http->ocmd, byte_count);
 }
 
 
@@ -852,23 +1615,26 @@ static void chat(struct client_state *csp)
  * Returns     :  N/A
  *
  *********************************************************************/
+#ifdef AMIGA
+void serve(struct client_state *csp)
+#else /* ifndef AMIGA */
 static void serve(struct client_state *csp)
+#endif /* def AMIGA */
 {
    chat(csp);
    close_socket(csp->cfd);
 
-   if (csp->sfd >= 0)
+   if (csp->sfd != JB_INVALID_SOCKET)
    {
       close_socket(csp->sfd);
    }
 
-   csp->active = 0;
+   csp->flags &= ~CSP_FLAG_ACTIVE;
 
 }
 
 
 #ifdef __BEOS__
-
 /*********************************************************************
  *
  * Function    :  server_thread
@@ -887,10 +1653,31 @@ static int32 server_thread(void *data)
    return 0;
 
 }
-
 #endif
 
 
+/*********************************************************************
+ *
+ * Function    :  usage
+ *
+ * Description :  Print usage info & exit.
+ *
+ * Parameters  :  Pointer to argv[0] for identifying ourselves
+ *
+ * Returns     :  No. ,-)
+ *
+ *********************************************************************/
+void usage(const char *myname)
+{
+   printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n"
+           "Usage: %s [--help] [--version] [--no-daemon] [--pidfile pidfile] [--user user[.group]] [configfile]\n"
+           "Aborting.\n", myname);
+   exit(2);
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  main
@@ -910,75 +1697,156 @@ static int32 server_thread(void *data)
  *                any load fails, and can't bind port.
  *
  *                Else main never returns, the process must be signaled
- *                to terminate execution.  Or, on Windows, use the 
+ *                to terminate execution.  Or, on Windows, use the
  *                "File", "Exit" menu option.
  *
  *********************************************************************/
 #ifdef __MINGW32__
-int _main(int argc, const char *argv[])
+int real_main(int argc, const char *argv[])
 #else
 int main(int argc, const char *argv[])
 #endif
 {
+   int argc_pos = 0;
+#ifdef unix
+   struct passwd *pw = NULL;
+   struct group *grp = NULL;
+   char *p;
+#endif
+
+   Argc = argc;
+   Argv = argv;
+
    configfile =
-#ifndef _WIN32
+#if !defined(_WIN32)
    "config"
 #else
-   "junkbstr.txt"
+   "config.txt"
 #endif
       ;
 
-#if !defined(_WIN32) || defined(_WIN_CONSOLE)
-   if ((argc >= 2) && (strcmp(argv[1], "--help")==0))
-   {
-      printf("JunkBuster proxy version " VERSION ".\n\n"
-         "Usage: %s [configfile]\n\n"
-         "See " HOME_PAGE_URL " for details.\n"
-         "This program is distributed under the GNU GPL, version 2 or later.\n",
-         argv[0]);
-      exit(2);
-   }
-   if ((argc >= 2) && (strcmp(argv[1], "--version")==0))
+   /*
+    * Parse the command line arguments
+    */
+   while (++argc_pos < argc)
    {
-      printf(VERSION "\n");
-      exit(2);
-   }
-#endif /* !defined(_WIN32) || defined(_WIN_CONSOLE) */
+#if !defined(_WIN32) || defined(_WIN_CONSOLE)
 
-   Argc = argc;
-   Argv = argv;
+      if (strcmp(argv[argc_pos], "--help") == 0)
+      {
+         usage(argv[0]);
+      }
+
+      else if(strcmp(argv[argc_pos], "--version") == 0)
+      {
+         printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n");
+         exit(0);
+      }
+
+      else if (strcmp(argv[argc_pos], "--no-daemon" ) == 0)
+      {
+         no_daemon = 1;
+      }
+#if defined(unix)
+      else if (strcmp(argv[argc_pos], "--pidfile" ) == 0)
+      {
+         if (++argc_pos == argc) usage(argv[0]);
+         pidfile = strdup(argv[argc_pos]);
+      }
+
+      else if (strcmp(argv[argc_pos], "--user" ) == 0)
+      {
+         if (++argc_pos == argc) usage(argv[argc_pos]);
+
+         if ((NULL != (p = strchr(argv[argc_pos], '.'))) && *(p + 1) != '0')
+         {
+            *p++ = '\0';
+            if (NULL == (grp = getgrnam(p)))
+            {
+               log_error(LOG_LEVEL_FATAL, "Group %s not found.", p);
+            }
+         }
+
+         if (NULL == (pw = getpwnam(argv[argc_pos])))
+         {
+            log_error(LOG_LEVEL_FATAL, "User %s not found.", argv[argc_pos]);
+         }
+
+         if (p != NULL) *--p = '\0';
+      }
+#endif /* defined(unix) */
+      else
+#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
+      {
+         configfile = argv[argc_pos];
+      }
 
-   if (argc > 1)
+   } /* -END- while (more arguments) */
+
+#if defined(unix)
+   if ( *configfile != '/' )
    {
-      configfile = argv[1];
+      char *abs_file;
+
+      /* make config-filename absolute here */
+      if ( !(basedir = getcwd( NULL, 1024 )))
+      {
+         perror("get working dir failed");
+         exit( 1 );
+      }
+
+      if ( !(abs_file = malloc( strlen( basedir ) + strlen( configfile ) + 5 )))
+      {
+         perror("malloc failed");
+         exit( 1 );
+      }
+      strcpy( abs_file, basedir );
+      strcat( abs_file, "/" );
+      strcat( abs_file, configfile );
+      configfile = abs_file;
    }
+#endif /* defined unix */
+
 
-   remove_all_loaders();
-   memset( proxy_args, 0, sizeof( proxy_args ) );
    files->next = NULL;
 
-   load_config( 0 );
+#ifdef AMIGA
+   InitAmiga();
+#elif defined(_WIN32)
+   InitWin32();
+#endif
 
    /*
-    * Since load_config acts as a signal handler too, it returns
-    * its status in configret.  Check it for an error in loading.
+    * Unix signal handling
+    *
+    * Catch the abort, interrupt and terminate signals for a graceful exit
+    * Catch the hangup signal so the errlog can be reopened.
+    * Ignore the broken pipe and child signals
+    *  FIXME: Isn't ignoring the default for SIGCHLD anyway and why ignore SIGPIPE? 
     */
-   if ( 0 != configret )
+#if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
+{
+   int idx;
+   const int catched_signals[] = { SIGABRT, SIGTERM, SIGINT, SIGHUP, 0 };
+   const int ignored_signals[] = { SIGPIPE, SIGCHLD, 0 };
+
+   for (idx = 0; catched_signals[idx] != 0; idx++)
    {
-      /* load config failed!  Exit with error. */
-      return( 1 );
+      if (signal(catched_signals[idx], sig_handler) == SIG_ERR)
+      {
+         log_error(LOG_LEVEL_FATAL, "Can't set signal-handler for signal %d: %E", catched_signals[idx]);
+      }
    }
 
-#ifdef _WIN32
-   InitWin32();
-#endif
-
-
-#ifndef _WIN32
-   signal(SIGPIPE, SIG_IGN);
-   signal(SIGCHLD, SIG_IGN);
-   signal(SIGHUP, load_config);
+   for (idx = 0; ignored_signals[idx] != 0; idx++)
+   {
+      if (signal(ignored_signals[idx], SIG_IGN) == SIG_ERR)
+      {
+         log_error(LOG_LEVEL_FATAL, "Can't set ignore-handler for signal %d: %E", ignored_signals[idx]);
+      }
+   }
 
+}
 #else /* ifdef _WIN32 */
 # ifdef _WIN_CONSOLE
    /*
@@ -990,6 +1858,96 @@ int main(int argc, const char *argv[])
 #endif /* def _WIN32 */
 
 
+   /* Initialize the CGI subsystem */
+   cgi_init_error_messages();
+
+   /*
+    * If runnig on unix and without the --nodaemon
+    * option, become a daemon. I.e. fork, detach
+    * from tty and get process group leadership
+    */
+#if defined(unix)
+{
+   pid_t pid = 0;
+#if 0
+   int   fd;
+#endif
+
+   if (!no_daemon)
+   {
+      pid  = fork();
+
+      if ( pid < 0 ) /* error */
+      {
+         perror("fork");
+         exit( 3 );
+      }
+      else if ( pid != 0 ) /* parent */
+      {
+         int status;
+         pid_t wpid;
+         /*
+          * must check for errors
+          * child died due to missing files aso
+          */
+         sleep( 1 );
+         wpid = waitpid( pid, &status, WNOHANG );
+         if ( wpid != 0 )
+         {
+            exit( 1 );
+         }
+         exit( 0 );
+      }
+      /* child */
+#if 1
+      /* Should be more portable, but not as well tested */
+      setsid();
+#else /* !1 */
+#ifdef __FreeBSD__
+      setpgrp(0,0);
+#else /* ndef __FreeBSD__ */
+      setpgrp();
+#endif /* ndef __FreeBSD__ */
+      fd = open("/dev/tty", O_RDONLY);
+      if ( fd )
+      {
+         /* no error check here */
+         ioctl( fd, TIOCNOTTY,0 );
+         close ( fd );
+      }
+#endif /* 1 */
+      /* FIXME: should close stderr (fd 2) here too, but the test
+       * for existence
+       * and load config file is done in listen_loop() and puts
+       * some messages on stderr there.
+       */
+
+      close( 0 );
+      close( 1 );
+      chdir("/");
+
+   } /* -END- if (!no_daemon) */
+
+   /*
+    * As soon as we have written the PID file, we can switch
+    * to the user and group ID indicated by the --user option
+    */
+   write_pid_file();
+   
+   if (NULL != pw)
+   {
+      if (((NULL != grp) && setgid(grp->gr_gid)) || (setgid(pw->pw_gid)))
+      {
+         log_error(LOG_LEVEL_FATAL, "Cannot setgid(): Insufficient permissions.");
+      }
+      if (setuid(pw->pw_uid))
+      {
+         log_error(LOG_LEVEL_FATAL, "Cannot setuid(): Insufficient permissions.");
+      }
+   }
+}
+#endif /* defined unix */
+
    listen_loop();
 
    /* NOTREACHED */
@@ -998,6 +1956,78 @@ int main(int argc, const char *argv[])
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  bind_port_helper
+ *
+ * Description :  Bind the listen port.  Handles logging, and aborts
+ *                on failure.
+ *
+ * Parameters  :
+ *          1  :  config = Privoxy configuration.  Specifies port
+ *                         to bind to.
+ *
+ * Returns     :  Port that was opened.
+ *
+ *********************************************************************/
+static jb_socket bind_port_helper(struct configuration_spec * config)
+{
+   int result;
+   jb_socket bfd;
+
+   if ( (config->haddr != NULL)
+     && (config->haddr[0] == '1')
+     && (config->haddr[1] == '2')
+     && (config->haddr[2] == '7')
+     && (config->haddr[3] == '.') )
+   {
+      log_error(LOG_LEVEL_INFO, "Listening on port %d for local connections only",
+                config->hport);
+   }
+   else if (config->haddr == NULL)
+   {
+      log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses",
+                config->hport);
+   }
+   else
+   {
+      log_error(LOG_LEVEL_INFO, "Listening on port %d on IP address %s",
+                config->hport, config->haddr);
+   }
+
+   result = bind_port(config->haddr, config->hport, &bfd);
+
+   if (result < 0)
+   {
+      switch(result)
+      {
+         case -3 :
+            log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: "
+               "There may be another Privoxy or some other "
+               "proxy running on port %d",
+               (NULL != config->haddr) ? config->haddr : "INADDR_ANY",
+                      config->hport, config->hport);
+
+         case -2 :
+            log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: " 
+               "The hostname is not resolvable",
+               (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
+
+         default :
+            log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: because %E",
+               (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
+      }
+
+      /* shouldn't get here */
+      return JB_INVALID_SOCKET;
+   }
+
+   config->need_bind = 0;
+
+   return bfd;
+}
+
+
 /*********************************************************************
  *
  * Function    :  listen_loop
@@ -1012,47 +2042,71 @@ int main(int argc, const char *argv[])
 static void listen_loop(void)
 {
    struct client_state *csp = NULL;
-   int bfd;
-
-   log_error(LOG_LEVEL_CONNECT, "bind (%s, %d)",
-             haddr ? haddr : "INADDR_ANY", hport);
+   jb_socket bfd;
+   struct configuration_spec * config;
 
-   bfd = bind_port(haddr, hport);
-   config_changed = 0;
-
-   if (bfd < 0)
-   {
-      log_error(LOG_LEVEL_ERROR, "can't bind %s:%d: %E "
-         "- There may be another junkbuster or some other "
-         "proxy running on port %d", 
-         (NULL != haddr) ? haddr : "INADDR_ANY", hport, hport
-      );
-      return;
-   }
+   config = load_config();
 
+   bfd = bind_port_helper(config);
 
-   while (FOREVER)
+#ifdef FEATURE_GRACEFUL_TERMINATION
+   while (!g_terminate)
+#else
+   for (;;)
+#endif
    {
-#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
+#if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
       while (waitpid(-1, NULL, WNOHANG) > 0)
       {
          /* zombie children */
       }
-#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
+#endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
+
+      /*
+       * Free data that was used by died threads
+       */
       sweep();
 
-      if ( NULL == (csp = (struct client_state *) malloc(sizeof(*csp))) )
+#if defined(unix)
+      /*
+       * Re-open the errlog after HUP signal
+       */
+      if (received_hup_signal)
+      {
+         init_error_log(Argv[0], config->logfile, config->debug);
+         received_hup_signal = 0;
+      }
+#endif
+
+#ifdef __OS2__
+#ifdef FEATURE_COOKIE_JAR
+      /*
+       * Need a workaround here: we have to fclose() the jarfile, or we die because it's
+       * already open.  I think unload_configfile() is not being run, which should do
+       * this work.  Until that can get resolved, we'll use this workaround.
+       */
+       if (csp)
+         if(csp->config)
+           if (csp->config->jar)
+           {
+             fclose(csp->config->jar);
+             csp->config->jar = NULL;
+           }
+#endif /* FEATURE_COOKIE_JAR */
+#endif /* __OS2__ */
+
+      if ( NULL == (csp = (struct client_state *) zalloc(sizeof(*csp))) )
       {
-         log_error(LOG_LEVEL_ERROR, "malloc(%d) for csp failed: %E", sizeof(*csp));
+         log_error(LOG_LEVEL_FATAL, "malloc(%d) for csp failed: %E", sizeof(*csp));
          continue;
       }
 
-      memset(csp, '\0', sizeof(*csp));
+      csp->flags |= CSP_FLAG_ACTIVE;
+      csp->sfd    = JB_INVALID_SOCKET;
 
-      csp->active = 1;
-      csp->sfd    = -1;
+      csp->config = config = load_config();
 
-      if ( config_changed )
+      if ( config->need_bind )
       {
          /*
           * Since we were listening to the "old port", we will not see
@@ -1066,13 +2120,10 @@ static void listen_loop(void)
           * request.  This should not be a so common of an operation
           * that this will hurt people's feelings.
           */
-         close_socket(bfd);
 
-         log_error(LOG_LEVEL_CONNECT, "bind (%s, %d)",
-                   haddr ? haddr : "INADDR_ANY", hport);
-         bfd = bind_port(haddr, hport);
+         close_socket(bfd);
 
-         config_changed = 0;
+         bfd = bind_port_helper(config);
       }
 
       log_error(LOG_LEVEL_CONNECT, "accept connection ... ");
@@ -1080,13 +2131,14 @@ static void listen_loop(void)
       if (!accept_connection(csp, bfd))
       {
          log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
-\r
-#ifdef AMIGA\r
-         if(!childs)\r
-         {\r
-            exit(1); \r
-         }\r
-#endif\r
+
+#ifdef AMIGA
+         if(!childs)
+         {
+            exit(1);
+         }
+#endif
+         freez(csp);
          continue;
       }
       else
@@ -1094,32 +2146,68 @@ static void listen_loop(void)
          log_error(LOG_LEVEL_CONNECT, "OK");
       }
 
-#if defined(TOGGLE)
-      /* by haroon - most of credit to srt19170 */
-      csp->toggled_on = g_bToggleIJB;
-#endif
-
-      /* add it to the list of clients */
-      csp->next = clients->next;
-      clients->next = csp;
+#ifdef FEATURE_TOGGLE
+      if (g_bToggleIJB)
+      {
+         csp->flags |= CSP_FLAG_TOGGLED_ON;
+      }
+#endif /* def FEATURE_TOGGLE */
 
       if (run_loader(csp))
       {
-         log_error(LOG_LEVEL_ERROR, "a loader failed - must exit");
-         return;
+         log_error(LOG_LEVEL_FATAL, "a loader failed - must exit");
+         /* Never get here - LOG_LEVEL_FATAL causes program exit */
+      }
+
+#ifdef FEATURE_ACL
+      if (block_acl(NULL,csp))
+      {
+         log_error(LOG_LEVEL_CONNECT, "Connection dropped due to ACL");
+         close_socket(csp->cfd);
+         freez(csp);
+         continue;
       }
+#endif /* def FEATURE_ACL */
+
+      /* add it to the list of clients */
+      csp->next = clients->next;
+      clients->next = csp;
 
-      if (multi_threaded)
+      if (config->multi_threaded)
       {
          int child_id;
 
 /* this is a switch () statment in the C preprocessor - ugh */
 #undef SELECTED_ONE_OPTION
 
+/* Use Pthreads in preference to native code */
+#if defined(FEATURE_PTHREAD) && !defined(SELECTED_ONE_OPTION)
+#define SELECTED_ONE_OPTION
+         {
+            pthread_t the_thread;
+            pthread_attr_t attrs;
+
+            pthread_attr_init(&attrs);
+            pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
+            child_id = (pthread_create(&the_thread, &attrs,
+               (void*)serve, csp) ? -1 : 0);
+            pthread_attr_destroy(&attrs);
+         }
+#endif
+
 #if defined(_WIN32) && !defined(_CYGWIN) && !defined(SELECTED_ONE_OPTION)
 #define SELECTED_ONE_OPTION
          child_id = _beginthread(
-            (void*)serve,
+            (void (*)(void *))serve,
+            64 * 1024,
+            csp);
+#endif
+
+#if defined(__OS2__) && !defined(SELECTED_ONE_OPTION)
+#define SELECTED_ONE_OPTION
+         child_id = _beginthread(
+            (void(* _Optlink)(void*))serve,
+            NULL,
             64 * 1024,
             csp);
 #endif
@@ -1141,47 +2229,27 @@ static void listen_loop(void)
          }
 #endif
 
-#if defined(AMIGA) && !defined(SELECTED_ONE_OPTION)\r
-#define SELECTED_ONE_OPTION\r
-         csp->cfd = ReleaseSocket(csp->cfd, -1);\r
-         if((child_id = (int)CreateNewProcTags(\r
-            NP_Entry, (ULONG)server_thread,\r
-            NP_Output, Output(),\r
-            NP_CloseOutput, FALSE,\r
-            NP_Name, (ULONG)"junkbuster child",\r
-            NP_StackSize, 20*1024,\r
-            TAG_DONE)))\r
-         {\r
-            childs++;\r
-            ((struct Task *)child_id)->tc_UserData = csp;\r
-            Signal((struct Task *)child_id, SIGF_SINGLE);\r
-            Wait(SIGF_SINGLE);\r
-         }\r
-#endif\r
-\r
-#if !defined(SELECTED_ONE_OPTION)
-         child_id = fork();
-#endif
-
-#undef SELECTED_ONE_OPTION
-/* end of cpp switch () */
-
-         if (child_id < 0) /* failed */
+#if defined(AMIGA) && !defined(SELECTED_ONE_OPTION)
+#define SELECTED_ONE_OPTION
+         csp->cfd = ReleaseSocket(csp->cfd, -1);
+         if((child_id = (int)CreateNewProcTags(
+            NP_Entry, (ULONG)server_thread,
+            NP_Output, Output(),
+            NP_CloseOutput, FALSE,
+            NP_Name, (ULONG)"privoxy child",
+            NP_StackSize, 200*1024,
+            TAG_DONE)))
          {
-            char buf[BUFSIZ];
-
-            log_error(LOG_LEVEL_ERROR, "can't fork: %E");
-
-            sprintf(buf , "JunkBuster: can't fork: errno = %d", errno);
-
-            write_socket(csp->cfd, buf, strlen(buf));
-            close_socket(csp->cfd);
-            csp->active = 0;
-            sleep(5);
-            continue;
+            childs++;
+            ((struct Task *)child_id)->tc_UserData = csp;
+            Signal((struct Task *)child_id, SIGF_SINGLE);
+            Wait(SIGF_SINGLE);
          }
+#endif
+
+#if !defined(SELECTED_ONE_OPTION)
+         child_id = fork();
 
-#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
          /* This block is only needed when using fork().
           * When using threads, the server thread was
           * created and run by the call to _beginthread().
@@ -1192,7 +2260,7 @@ static void listen_loop(void)
             _exit(0);
 
          }
-         else  /* parent */
+         else if (child_id > 0) /* parent */
          {
             /* in a fork()'d environment, the parent's
              * copy of the client socket and the CSP
@@ -1203,16 +2271,75 @@ static void listen_loop(void)
             wait( NULL );
 #endif /* !defined(_WIN32) && defined(__CYGWIN__) */
             close_socket(csp->cfd);
-            csp->active = 0;
+            csp->flags &= ~CSP_FLAG_ACTIVE;
+         }
+#endif
+
+#undef SELECTED_ONE_OPTION
+/* end of cpp switch () */
+
+         if (child_id < 0) /* failed */
+         {
+            char buf[BUFFER_SIZE];
+
+            log_error(LOG_LEVEL_ERROR, "can't fork: %E");
+
+            sprintf(buf , "Privoxy: can't fork: errno = %d", errno);
+
+            write_socket(csp->cfd, buf, strlen(buf));
+            close_socket(csp->cfd);
+            csp->flags &= ~CSP_FLAG_ACTIVE;
+            sleep(5);
+            continue;
          }
-#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
       }
       else
       {
          serve(csp);
       }
    }
-   /* NOTREACHED */
+
+   /* NOTREACHED unless FEATURE_GRACEFUL_TERMINATION is defined */
+
+   /* Clean up.  Aim: free all memory (no leaks) */
+#ifdef FEATURE_GRACEFUL_TERMINATION
+
+   log_error(LOG_LEVEL_ERROR, "Graceful termination requested");
+
+   unload_current_config_file();
+   unload_current_actions_file();
+   unload_current_re_filterfile();
+#ifdef FEATURE_TRUST
+   unload_current_trust_file();
+#endif
+
+   if (config->multi_threaded)
+   {
+      int i = 60;
+      do
+      {
+         sleep(1);
+         sweep();
+      } while ((clients->next != NULL) && (--i > 0));
+
+      if (i <= 0)
+      {
+         log_error(LOG_LEVEL_ERROR, "Graceful termination failed - still some live clients after 1 minute wait.");
+      }
+   }
+   sweep();
+   sweep();
+
+#if defined(unix)
+   free(basedir);
+#endif
+#if defined(_WIN32) && !defined(_WIN_CONSOLE)
+   /* Cleanup - remove taskbar icon etc. */
+   TermLogWindow();
+#endif
+
+   exit(0);
+#endif /* FEATURE_GRACEFUL_TERMINATION */
 
 }
 
diff --git a/jcc.h b/jcc.h
index fcafbb7..1778f1e 100644 (file)
--- a/jcc.h
+++ b/jcc.h
@@ -1,15 +1,15 @@
-#ifndef _JCC_H
-#define _JCC_H
-#define JCC_H_VERSION "$Id: jcc.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef JCC_H_INCLUDED
+#define JCC_H_INCLUDED
+#define JCC_H_VERSION "$Id: jcc.h,v 1.11 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/jcc.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/jcc.h,v $
  *
  * Purpose     :  Main file.  Contains main() method, main loop, and 
  *                the main connection-handling function.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: jcc.h,v $
+ *    Revision 1.11  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.10  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.9  2002/03/07 03:52:44  oes
+ *    Set logging to tty for --no-daemon mode
+ *
+ *    Revision 1.8  2002/03/04 18:19:49  oes
+ *    Added extern const char *pidfile
+ *
+ *    Revision 1.7  2001/11/05 21:41:43  steudten
+ *    Add changes to be a real daemon just for unix os.
+ *    (change cwd to /, detach from controlling tty, set
+ *    process group and session leader to the own process.
+ *    Add DBG() Macro.
+ *    Add some fatal-error log message for failed malloc().
+ *    Add '-d' if compiled with 'configure --with-debug' to
+ *    enable debug output.
+ *
+ *    Revision 1.6  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.5  2001/07/29 19:32:00  jongfoster
+ *    Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
+ *
+ *    Revision 1.4  2001/07/29 18:58:15  jongfoster
+ *    Removing nested #includes, adding forward declarations for needed
+ *    structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
+ *
+ *    Revision 1.3  2001/07/18 12:31:58  oes
+ *    moved #define freez from jcc.h to project.h
+ *
+ *    Revision 1.2  2001/05/31 21:24:47  jongfoster
+ *    Changed "permission" to "action" throughout.
+ *    Removed DEFAULT_USER_AGENT - it must now be specified manually.
+ *    Moved vanilla wafer check into chat(), since we must now
+ *    decide whether or not to add it based on the URL.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:56  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
-/* Declare struct FILE for vars and funcs. */
-#include <stdio.h>
-
-/* All of our project's data types. */
-#include "project.h"
-
-#include "loadcfg.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define freez(X)  if(X) free(X); X = NULL
-
+struct client_state;
+struct file_list;
 
 /* Global variables */
 
-
-#ifdef STATISTICS
+#ifdef FEATURE_STATISTICS
 extern int urls_read;
 extern int urls_rejected;
-#endif /*def STATISTICS*/
+#endif /*def FEATURE_STATISTICS*/
 
 extern struct client_state clients[];
-
 extern struct file_list    files[];
 
-/* Global constants */
-
-extern const char DEFAULT_USER_AGENT[];
+#ifdef unix
+extern const char *pidfile;
+#endif
+extern int no_daemon;
 
+#ifdef FEATURE_GRACEFUL_TERMINATION
+extern int g_terminate;
+#endif
 
 /* Functions */
 
 #ifdef __MINGW32__
-int _main(int argc, const char *argv[]);
+int real_main(int argc, const char *argv[]);
 #else
 int main(int argc, const char *argv[]);
 #endif
@@ -87,7 +131,7 @@ extern const char jcc_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _JCC_H */
+#endif /* ndef JCC_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/junkbstr.txt b/junkbstr.txt
deleted file mode 100644 (file)
index cbe2104..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-#  Sample Configuration file for the Internet Junkbuster 2.0
-
-#
-# $Id: config,v 1.2 2001/04/30 03:05:11 rodney Exp $
-#
-
-#
-#
-# Copyright 1997-8 Junkbusters Corp.  For distribution, modification and use
-# under the GNU General Public License. These files come with NO WARRANTY.
-# See http://www.junkbusters.com/ht/en/gpl.html or README file for details.
-#
-# When starting the proxy, give the name of this file as an argument.
-# Any changes made to this file are *not* automatically loaded; you have 
-# to stop and restart the proxy.
-
-# For information see http://www.junkbusters.com/ht/en/ijbman.html
-# or the documentation that came with the release
-
-# Lines beginning with a # character are comments; they are ignored.
-# Many example lines are provided here commented out
-
-# the blockfile contains patterns to be blocked by the proxy
-blockfile      ./blocklist # comments are OK here, too
-
-# the imagefile contains patterns to detect blocked images
-imagefile      ./imagelist
-
-# the popfile contains patterns of servers where javascript popups are disabled
-#
-# if the next line is not commented out, all javascript popups from the sites 
-# that match the patterns in popup will be blocked
-# popupfile     ./popup
-
-# File containing content modification rules
-#re_filterfile   ./re_filterfile
-
-# Uncomment to filter *all* traffic. Default is to
-# filter only if we wouldn't send a cookie either.
-#
-#re_filter_all
-
-
-# the cookiefile contains patterns to specify the cookie management policy
-#
-cookiefile     ./cookiefile
-
-# the logfile is where all logging and error messages are written
-#
-logfile        ./junkbuster.log
-
-# the jarfile is where cookies can be stored
-#
-#jarfile    ./jarfile
-
-# the forwardfile defines domain-specific routing
-#
-forwardfile    ./forward
-
-# file which lists and into which trusted domains are written
-#
-#trustfile     ./trust
-# files specify locations of "for information about trusted referers, see.."
-# multiple trust_info_url lines are OK
-#
-# trust_info_url     http://internet.junkbuster.com/
-# trust_info_url     http://www.yoursite.com/our_trust_policy.html
-#
-
-# The access control list file can be used to restrict IP addresses
-# that are permitted to use the proxy (see warnings in the FAQ).
-#
-#aclfile ./aclfile
-
-# add an "X-Forwarded-For:" specification to each request header
-#
-#add-forwarded-header
-
-# if logging cookies into a jarfile, and no other wafers were
-# explicity set, then by default a vanilla wafer is sent with
-# each request.
-#
-# setting 'suppress-vanilla-wafer' stops this vanilla wafer from
-# being sent.
-#
-suppress-vanilla-wafer
-
-# add these wafers to each request header
-# multiple wafer lines are OK
-#
-#wafer    NOTE=Like most people, I want my browsing to be anonymous.
-#wafer    WARNING=Please do not attempt to track me.
-
-# Anything can be added to the request headers. Please don't litter.
-# multiple add-header lines are OK
-#
-#add-header     Forwarded: by http://stay-out-of-my-backyard.net
-#add-header    Forwarded: by http://pro-privacy-isp.net
-#add-header    Proxy-Connection: Keep-Alive
-
-# listen-address specifies where the Junkbuster will listen for connections
-# Specifying a port is optional; if unspecified the defaults is 8000.
-# Before Version 2.0.2 the default was to bind to all IP addresses (INADDR_ANY)
-# This has been restricted to localhost to avoid unintended security breaches.
-# To open the proxy to all, uncomment the following line:
-#listen-address      :8000
-# other example usage:
-#listen-address      124.207.250.245:8080
-# to explicitly state what is now the default:
-#listen-address      localhost
-# or equivalently:
-listen-address    127.0.0.1:8000
-
-# user-agent specifies treatment of the "User-Agent:" (and "UA-*:") header(s)
-# default: Forge the "User-Agent:" 
-# 'text' : Always send <text> as the "User-Agent:"
-# .      : Pass the "User-Agent:" unchanged
-# @      : Pass the "User-Agent:" if the server is in the cookie file,
-#          forge the "User-Agent:" otherwise
-#user-agent     @
-
-# note: Russian browsers may be confused if user agent misidentifies
-# the operating system (Mac vs Windows); see FAQ
-user-agent    .
-
-# referer specifies treatment of the "Referer:" header
-# New option by "Andreas S. Oesterhelt" <oes@paradis.rhein.de>
-#
-# default: Kill the referrer-header from the client
-# 'text' : Always send <text> as the referrer
-# .      : Pass the referrer unchanged
-# @      : Pass the referrer if the server is in the cookie file,
-#          kill the referrer otherwise
-# Â§      : Pass the referrer if the server is in the cookie file,
-#       send a forged referrer that points to the root-diretory URL
-#       of the current request otherwise
-referer     Â§
-
-# from specifies value to be subsituted if browser provides a "From:" header
-#
-#from        spam-me-senseless@sittingduck.net
-
-# tinygif allows you to change the appearance of blocked images
-#
-# tinygif  0  # Show a "broken icon"
-# tinygif  1  # Show a GIF of one transparent pixel
-tinygif  2  # Show a GIF with the word "JUNKBUSTER"
-# tinygif  3 http://localhost/1x1.gif   # Temporary redirect to this URL
-
-# Andrew <anw@tirana.freewire.co.uk> added
-# The following can be used to suppress display of the block lists when the
-# page http://x.x/show-proxy-args is displayed. With a long block list this
-# accelerates loading of the configuration page and also hides the contents of
-# the block lists (for whatever reason). Maintainers of junkbuster proxies for 
-# multiple use can specify a message for any use who wants to know what is in
-# these files.
-#
-#suppress-blocklists Contact sysadmin@example.com for details.
-# suppress-blocklists
-
-# debug sets the level of debugging information to log in the logfile
-#
-# debug         1 # GPC  = show each GET/POST/CONNECT request
-# debug         2 # CONN = show each connection status
-# debug         4 # IO   = show I/O status
-# debug         8 # HDR  = show header parsing
-# debug        16 # LOG  = log all data into the logfile
-# debug        32 # FRC  = debug force feature
-# debug        64 # REF  = debug regular expression filter 
-#
-# multiple "debug" directives, are OK - they're logical-OR'd together
-#
-#debug         15 # same as setting the first 4 listed above
-debug 1
-# debug 255        # Log *everything*
-
-# single-threaded operation (i.e. disallows multiple threads or processes)
-# This is most often used for debugging because it keeps the
-# debugging output "in order" for easy reading.
-#
-#single-threaded
-
-# Toggle flag.  0 => disabled, anything else (ie. 1) => enabled
-toggle 1
-
-
-# Win32 GUI specific options.  Moved here from ijbw32.ini
-# in hopes of keep all of our config settings together.
-
-activity-animation      1
-log-messages            1
-log-highlight-messages  1
-log-buffer-size         1
-log-max-lines           200
-log-font-name           Comic Sans MS
-log-font-size           8
-show-on-task-bar        0
-close-button-minimizes  1
-
-# hide-console is used only on Win32 console mode. It instructs
-# the Internet Junkbuster to disconnect from and hide the
-# command console.
-#
-#hide-console
-
-
diff --git a/junkbuster.1 b/junkbuster.1
deleted file mode 100644 (file)
index d88294d..0000000
+++ /dev/null
@@ -1,871 +0,0 @@
-.TH JUNKBUSTER 1 "http://www.junkbusters.com/ht/en/ijb2.0man.html"\r
-.SH NAME\r
-\fBjunkbuster\fP\r
-- The\r
-Internet Junkbuster\r
-Proxy\r
-\s-2(TM)\s+2\r
-.SH SYNOPSIS\r
-\fBjunkbuster\fP\r
-\fI\&configfile\fP\r
-(Version 2.0 onwards)\r
-.br\r
-\fBjunkbstr.exe\fP\r
-\fI\&configfile\fP\r
-(Windows)\r
-.br\r
-\fBjunkbuster\fP\r
-[-a]\r
-[-y]\r
-[-s]\r
-[-c]\r
-[-v]\r
-.br\r
-[-u user_agent]\r
-[-r referer]\r
-[-t from]\r
-.br\r
-[-b blockfile]\r
-[-j jarfile]\r
-[-l logfile]\r
-.br\r
-[-w NAME=VALUE]\r
-[-x Header_text]\r
-.br\r
-[-h [bind_host_address][:bind_port]]\r
-.br\r
-[-f forward_host[:port]]\r
-[-d N]\r
-.br\r
-[-g gw_protocol[:[gw_host][:gw_port]]]\r
-.br\r
-(Version 1.4 and earlier)\r
-.SH DESCRIPTION\r
-\fBjunkbuster\fP\r
-is an instrumentable proxy that filters the \r
-\s-2HTTP\s0\r
-stream between\r
-web servers and browsers.\r
-Its main purpose is to enhance privacy.\r
-.P\r
-Versions before 2.0 used command-line options;\r
-Versions from 2.0 onward use a configuration file.\r
-The following descriptions of the options first give the older\r
-command-line usage, then the new configfile line.\r
-.P\r
-In Versions 2.0.1 upwards on Windows,\r
-a start-up message is printed and the configuration is read from the file\r
-\fC\&junkbstr.ini\fP\r
-if it exists and no argument was given.\r
-.P\r
-All files except the configfile\r
-are checked for changes before each page is fetched,\r
-so they may edited without restarting the proxy.\r
-.SS OPTIONS\r
-.TP\r
-.\" anchor: o_b blockfile\r
-\fI-b blockfile\fP (Old) blockfile \fIblockfile\fP (New)\r
-Block\" ijbfaq.html#blocking\r
-requests to\r
-\s-2URL\s0s\r
-matching any pattern given in the lines of the\r
-\fI\&blockfile\fP.\r
-The\r
-\fBjunkbuster\fP\r
-instead returns status 202, indicating that the request has been accepted\r
-(though not completed),\r
-and a\r
-message identifying itself\" ijbfaq.html#show\r
-(though the browser may\r
-display only a broken image icon).\r
-(Versions before 2.0 returned an error 403 (Forbidden).)\r
-The syntax of a pattern is\r
-\fB\&[domain][:port][/path]\fP\r
-(the\r
-\fB\&http://\fP\r
-or\r
-\fB\&https://\fP\r
-protocol part is omitted).\r
-To decide if a pattern matches a target, the domains are compared first,\r
-then the paths. \r
-.P\r
-To compare the domains,\r
-the pattern domain and the target\r
-domain specified in the\r
-\s-2URL\s0\r
-are each broken into their components.\r
-(Components are separated by the\r
-\fC\&.\fP\r
-(period) character.)\r
-Next each of the target components\r
-is compared with the corresponding pattern component: last with last,\r
-next-to-last with next-to-last, and so on.\r
-(This is called\r
-\fIright-anchored\fP\r
-matching.)\r
-If all of the pattern components find their match in the target,\r
-then the domains are considered a match.\r
-Case is irrelevant when comparing domain components.\r
-.P\r
-A successfully\r
-matching pattern can be an anchored substring of a target, but\r
-not vice versa.\r
-Thus if a pattern doesn't specify a domain,\r
-it matches all domains.\r
-.\" anchor: wildcard\r
-Furthermore, when comparing two components,\r
-the components must either match in their entirety or up to a wildcard\r
-\fC\&* \fP\r
-(star character) in the pattern.  The wildcard feature\r
-implements only a "prefix" match capability ("abc*" vs. "abcdefg"),\r
-not suffix matching ("*efg" vs. "abcdefg") or\r
-infix matching ("abc*efg" vs. "abcdefg").\r
-The feature is restricted to the domain component;\r
-it is unrelated to the optional\r
-regular expression\r
-feature in the path\r
-(described below).\" ijbman.html#regex\r
-.P\r
-If a numeric port\r
-is specified in the pattern domain, then the target port must\r
-match as well.  The default port in a target is port 80.\r
-.P\r
-If the domain and port match,\r
-then the target\r
-\s-2URL\s0\r
-path is checked for\r
-a match against the path in the pattern.\r
-Paths are compared with a simple case-sensitive\r
-left-anchored substring comparison.\r
-Once again, the pattern can be an\r
-anchored substring of the target, but not vice versa.\r
-A path of\r
-\fC\&/\fP\r
-(slash) would match all paths.  Wildcards are not considered in\r
-path comparisons.\r
-.P\r
-For example, the target\r
-\s-2URL\s0\r
-.br\r
-.ti +0.25i\r
-\fB\&the.yellow-brick-road.com/TinMan/has_no_brain\fP\r
-.br\r
-would be matched (and blocked) by the following patterns\r
-.br\r
-.ti +0.25i\r
-\fB\&yellow-brick-road.com\fP\r
-.br\r
-and\r
-.br\r
-.ti +0.25i\r
-\fB\&Yellow*.COM\fP\r
-.br\r
-and\r
-.br\r
-.ti +0.25i\r
-\fB\&/TinM\fP\r
-.br\r
-but not\r
-.br\r
-.ti +0.25i\r
-\fB\&follow.the.yellow-brick-road.com\fP\r
-.br\r
-or\r
-.br\r
-.ti +0.25i\r
-\fB\&/tinman\fP\r
-.br\r
-.P\r
-Comments in a blockfile start with a\r
-\fB\&#\fP\r
-(hash) character and end at a new line.\r
-Blank lines are also ignored.\r
-.P\r
-Lines beginning with a\r
-\fC\&~\fP\r
-(tilde) character are taken to be\r
-exceptions:\" ijbfaq.html#exceptions\r
-a\r
-\s-2URL\s0\r
-blocked by previous patterns that matches the rest of\r
-the line is let through. (The last match wins.)\r
-.P\r
-Patterns\r
-may contain\r
-\s-2POSIX\s0\r
-regular expressions\" ijbfaq.html#regex\r
-provided the\r
-\fBjunkbuster\fP\r
-was compiled with this option\r
-(the default in Version 2.0 on).\r
-The idiom\r
-\fC\&/*.*/ad\fP\r
-can then be used\r
-to match any\r
-\s-2URL\s0\r
-containing\r
-\fC\&/ad\fP\r
-(such as\r
-\fC\&http://nomatterwhere.com/images/advert/g3487.gif\fP\r
-for example).\r
-These expressions\r
-don't work\" ijbman.html#substring\r
-in the domain part.\r
-.P\r
-In version 1.3 and later\r
-the blockfile and cookiefile are checked for changes before each request.\r
-.TP\r
-tinygif \fIN\fP\r
-Set appearance of blocked GIFs. You can select one of the following\r
-values:\r
-.br\r
-.br\r
-\h'-\w"0 = "u'0 = Show a ``broken icon'' in the browser\r
-.br\r
-\h'-\w"1 = "u'1 = Show a one pixel transparent GIF\r
-.br\r
-\h'-\w"2 = "u'2 = Show a GIF with the word ``JUNKBUSTER''\r
-.TP\r
-popupfile \fI\&popup\fP\r
-Sets the name of the popupfile. If uncommented, the popupfile\r
-controls on which sites Javascript popup windows are disabled.\r
-.TP\r
-.\" anchor: o_w wafer\r
-\fI-w NAME=VALUE\fP (Old) wafer \fINAME=VALUE\fP (New)\r
-Specifies a pair to be sent as a cookie with every request\r
-to the server.\" ijbfaq.html#wafers\r
-(Such boring cookies are called\r
-\fI\&wafers\fP.)\r
-This option may be called more than once to generate multiple wafers.\r
-The original\r
-Netscape specification\r
-prohibited\r
-semi-colons, commas and white space;\r
-these characters will be\r
-\s-2URL\s0-encoded\r
-if used in wafers.\r
-The Path and Domain attributes are not currently supported.\r
-.TP\r
-.\" anchor: o_c cookiefile\r
-\fI-c cookiefile\fP (Old) cookiefile \fIcookiefile\fP (New)\r
-Enforce the cookie management policy specified in the\r
-\fI\&cookiefile.\fP\r
-.\" anchor: java\r
-If this option is not used all cookies are silently crunched,\r
-so that users who never want cookies aren't bothered by browsers\r
-asking whether each cookie should be accepted.\r
-However, cookies can\r
-still get through\" ijbfaq.html#breakthrough\r
-via\r
-JavaScript\" links.html#javascript\r
-and\r
-\s-2SSL\s0,\r
-so alerts should be left on.\r
-.P\r
-In Version 1.2 and later\r
-this option must be followed by a\r
-filename\" ijbfaq.html#crumble\r
-containing instructions on which sites are allowed to\r
-receive and set cookies.\r
-.\" anchor: drop\r
-By default cookies are dropped in both the browser's request\r
-and the server's response, unless the\r
-\s-2URL\s0\r
-requested matches an entry in the\r
-\fI\&cookiefile\fP.\r
-The matching algorithm is the same as for the blockfile.\r
-A leading\r
-\fC\&>\fP\r
-character allows\r
-server-bound\" ijbfaq.html#directional\r
-cookies only;\r
-a\r
-\fC\&<\fP\r
-allows only browser-bound cookies;\r
-a\r
-\fC\&~\fP\r
-character stops cookies in\r
-both directions.\" ijbfaq.html#crumble\r
-Thus a cookiefile containing a single line with the two characters\r
-\fC\&>*\fP\r
-will pass on all cookies to servers but not give any new ones to the browser.\r
-.TP\r
-.\" anchor: o_j jarfile\r
-\fI-j jarfile\fP (Old) jarfile \fIjarfile\fP (New)\r
-All Set-cookie attempts by the server are\r
-logged\" ijbfaq.html#jar\r
-to\r
-\fI\&jarfile\fP.\r
-If no wafer is specified,\r
-one containing a\r
-canned notice\" ijbfaq.html#notice\r
-(the \r
-\fI\&vanilla wafer\fP)\r
-is added as an alert to the server\r
-unless the\r
-suppress-vanilla-wafer\" ijbman.html#suppress-vanilla-wafer\r
-option is invoked.\r
-.TP\r
-.\" anchor: o_v suppress-vanilla-wafer\r
-\fI-v\fP (Old) suppress-vanilla-wafer \fI\fP (New)\r
-Suppress the vanilla wafer.\r
-.TP\r
-.\" anchor: o_t from\r
-\fI-t from\fP (Old) from \fIfrom\fP (New)\r
-If the browser\r
-discloses an email address\" ijbfaq.html#from\r
-in the\r
-\fB\&FROM\fP\r
-header (most don't),\r
-replace it with\r
-\fI\&from.\fP\r
-If\r
-\fI\&from\fP\r
-is set to\r
-\fB\&.\fP\r
-(the period character)\r
-the\r
-\fB\&FROM\fP\r
-is passed to the server unchanged.\r
-The default is to delete the\r
-\fB\&FROM\fP\r
-header.\r
-.TP\r
-.\" anchor: o_r referer\r
-\fI-r referer\fP (Old) referer \fIreferer\fP (New)\r
-Whenever the browser discloses the\r
-\s-2URL\s0\r
-that\r
-led to\" ijbfaq.html#referer\r
-the current request,\r
-replace it with\r
-\fI\&referer.\fP\r
-If\r
-\fI\&referer\fP\r
-is set to\r
-\fB\&.\fP\r
-(period)\r
-the \r
-\s-2URL\s0\r
-is passed to the server unchanged.\r
-In \r
-Version 1.4\r
-and later, if referer is set to \r
-\fB\&@\fP\r
-(at) the\r
-\s-2URL\s0\r
-is sent in cases where the cookiefile\r
-specifies that a cookie would be sent.\r
-(No way to send bogus referers selectively is provided.)\r
-The default is to delete Referer.\r
-.P\r
-Version 2.0 also accepts the spelling\r
-\fC\&referrer\fP,\r
-which most dictionaries consider correct.\r
-.TP\r
-.\" anchor: o_u user-agent\r
-\fI-u user-agent\fP (Old) user-agent \fIuser-agent\fP (New)\r
-Information disclosed by the browser\r
-about itself\" ijbfaq.html#agent\r
-is replaced with the value\r
-\fI\&user-agent.\fP\r
-If\r
-\fI\&user-agent\fP\r
-is set to\r
-\fB\&.\fP\r
-(period)\r
-the\r
-\fB\&User-Agent\fP\r
-header is passed to the server unchanged,\r
-along with any\r
-\fB\&UA\fP\r
-headers produced by\r
-\s-2MS-IE\s0\r
-(which would otherwise be deleted).\r
-In \r
-Version 1.4\r
-and later, if\r
-\fI\&user-agent\fP\r
-is set to\r
-\fB\&@\fP\r
-(at) these headers are sent unchanged in cases where the cookiefile\r
-specifies that a cookie would be sent,\r
-otherwise only default\r
-\fB\&User-Agent\fP\r
-header is sent.\r
-That default\r
-is Mozilla/3.0 (Netscape)\r
-with an unremarkable\r
-Macintosh\" ijbfaq.html#infer\r
-configuration.\r
-If used with a browser less advanced than Mozilla/3.0 or IE-3, the default\r
-may encourage pages containing extensions that confuse the browser.\r
-.TP\r
-.\" anchor: o_h listen-address\r
-\fI-h [host][:port]\fP (Old) listen-address \fI[host][:port]\fP (New)\r
-If\r
-\fI\&host\fP\r
-is specified,\r
-bind the\r
-\fBjunkbuster\fP\r
-to that\r
-\s-2IP\s0\r
-address.\r
-If a\r
-\fI\&port\fP\r
-is specified, use it.\r
-The default\r
-port\r
-is 8000;\r
-the default host is\r
-\fC\&localhost\fP.\r
-Before Version 2.0.2,\r
-the default was to bind to all \r
-\s-2IP\s0\r
-addresses\r
-(\fB\&INADDR_ANY\fP);\r
-but this has been restricted to\r
-\fB\&localhost\fP\r
-to avoid unintended security breaches.\r
-(To open the proxy to all, use the line\r
-.br\r
-.ti +0.25i\r
-\fB\&listen-address :8000\fP\r
-.br\r
-in the configuration file.)\r
-.TP\r
-.\" anchor: o_f forwardfile\r
-\fI-f forward_host[:port]\fP (Old) forwardfile \fIforwardfile\fP (New)\r
-Version 1.X required all\r
-\s-2HTTP\s0\r
-requests from the client to be forwarded to the same destination.\r
-Version 2.0 takes its routing specification from a\r
-\fI\&forwardfile\fP,\r
-allowing selection of the proxy (a.k.a. forwarding host) and gateway\r
-according to the\r
-\s-2URL\s0.\r
-Here is a typical line.\r
-.br\r
-.ft CW\r
-.S 8\r
-.nf\r
-.sp\r
-*         lpwa.com:8000      .      .\r
-.S\r
-.ft\r
-.fi\r
-.sp\r
-\r
-.P\r
-Each line contains four fields:\r
-\fB\&target\fP,\r
-\fB\&forward_to\fP,\r
-\fB\&via_gateway_type\fP\r
-and\r
-\fB\&gateway\fP.\r
-As usual, the\r
-last\" ijbman.html#compare\r
-\fB\&target\fP\r
-domain that matches the requested\r
-\s-2URL\s0\r
-wins,\r
-and the\r
-\fC\&*\fP\r
-character alone matches any domain.\r
-The target domain need not be a fully qualified\r
-hostname; it can be a general domain such as\r
-\fC\&com\fP\r
-or\r
-\fC\&co.uk\fP\r
-or even just a port number.\r
-.\" anchor: nose\r
-For example, because\r
-<a href="http://lpwa.com">LPWA</a>\r
-does not handle\r
-SSL,\" ijbfaq.html#encrypt\r
-the line above will typically be followed by a line such as\r
-.br\r
-.ft CW\r
-.S 8\r
-.nf\r
-.sp\r
-:443  .      .      .\r
-.S\r
-.ft\r
-.fi\r
-.sp\r
-\r
-to allow SSL transactions to proceed directly.\r
-The cautious would also\r
-add an entry in their blockfile to stop transactions\r
-to port 443 for all but specified trusted sites.\r
-.P\r
-If the winning\r
-\fB\&forward_to\fP\r
-field is\r
-\fC\&.\fP\r
-(the dot character) the proxy connects \r
-directly to the server given in the\r
-\s-2URL\s0,\r
-otherwise it forwards to the host and port number specified.\r
-The default port is 8000.\r
-The\r
-\fC\&via_gateway_type\fP\r
-and\r
-\fC\&gateway\fP\r
-fields also use a dot to indicate no gateway protocol.\r
-The gateway protocols are explained\r
-below.\" ijbman.html#o_g\r
-.P\r
-The example line above in a forwardfile alone\r
-would send everything through port 8000 at\r
-\fC\&lpwa.com\fP\r
-with no gateway protocol,\r
-and is equivalent to the old\r
-\fC\&-f lpwa.com:8000\fP\r
-with no\r
-\fC\&-g\fP\r
-option.\r
-For more information see the example file provided with the distribution.\r
-.P\r
-Configure with care: no loop detection is performed.\r
-When setting up chains of proxies that might loop back, try adding\r
-Squid.\" ijbman.html#squid\r
-.TP\r
-.\" anchor: o_g \r
-\fI-g gw_protocol[:[gw_host][:gw_port]]\fP (Old) \r
-Use\r
-\fI\&gw_protocol\fP\r
-as the gateway protocol.\r
-This option was introduced in Version 1.4,\r
-but was folded into the\r
-forwardfile\" ijbman.html#forwardfile\r
-option in Version 2.0.\r
-The default is to use no gateway protocol;\r
-this may be explicitly specified as\r
-\fB\&direct\fP\r
-on the command line\r
-or the dot character in the forwardfile.\r
-The\r
-\fC\&SOCKS4\fP\r
-protocol may be specified as\r
-\fB\&socks\fP\r
-or\r
-\fB\&socks4\fP.\r
-The\r
-\fC\&SOCKS4A\fP\r
-protocol is specified as\r
-\fB\&socks4a\fP.\r
-The\r
-\fC\&SOCKS5\fP\r
-protocol is not currently supported.\r
-The default\r
-\s-2SOCKS\s0\r
-\fI\&gw_port\fP\r
-is 1080.\r
-.P\r
-The user's browser should\r
-\fInot\fP\r
-be\r
-configured\" ijbfaq.html#socks\r
-to use\r
-\fC\&SOCKS\fP;\r
-the proxy conducts the negotiations, not the browser.\r
-.P\r
-The user identification capabilities of\r
-\fC\&SOCKS4\fP\r
-are deliberately not used;\r
-the user is always identified to the\r
-\fC\&SOCKS\fP\r
-server as\r
-\fC\&userid=anonymous\fP.\r
-If the server's policy is to reject requests from\r
-\fC\&anonymous\fP,\r
-the proxy will not work.\r
-Use a\r
-debug\" ijbman.html#o_d\r
-value of 3\r
-to see the status returned by the server.\r
-.TP\r
-.\" anchor: o_d debug\r
-\fI-d N\fP (Old) debug \fIN\fP (New)\r
-Set debug mode.\r
-The most common value is 1,\r
-to\r
-pinpoint\" ijbfaq.html#pinpoint\r
-offensive\r
-\s-2URL\s0s,\r
-so they can be added to the blockfile.\r
-The value of\r
-\fB\&N\fP\r
-is a bitwise\r
-logical-\s-2OR\s0\r
-of the following values:\r
-.br\r
-.br\r
-\h'-\w"1 = "u'1 = URLs (show each URL requested by the browser);\r
-.br\r
-\h'-\w"2 = "u'2 = Connections (show each connection to or from the proxy);\r
-.br\r
-\h'-\w"4 = "u'4 = I/O (log I/O errors);\r
-.br\r
-\h'-\w"8 = "u'8 = Headers (as each header is scanned, show the header and what is done to it);\r
-.br\r
-\h'-\w"16 = "u'16 = Log everything (including debugging traces and the contents of the pages).\r
-.\" anchor: or\r
-Multiple\r
-\fB\&debug\fP\r
-lines are permitted; they are logical OR-ed together.\r
-.P\r
-Because most browsers send several requests in parallel\r
-the debugging output may appear intermingled, so the\r
-single-threaded\" ijbman.html#single-threaded\r
-option is recommended when using\r
-debug\" ijbman.html#debug\r
-with\r
-\fB\&N\fP\r
-greater than 1.\r
-.TP\r
-.\" anchor: o_y add-forwarded-header\r
-\fI-y\fP (Old) add-forwarded-header \fI\fP (New)\r
-Add \r
-\fB\&X-Forwarded-For\fP\r
-headers to the server-bound \r
-\s-2HTTP\s0\r
-stream\r
-indicating the client \r
-\s-2IP\s0\r
-address\r
-to the server,\" ijbfaq.html#detect\r
-in the new style of\r
-Squid 1.1.4.\" ijbman.html#squid\r
-If you want the traditional\r
-\fC\&HTTP_FORWARDED\fP\r
-response header, add it manually with the\r
--x\" ijbman.html#o_x\r
-option.\r
-.TP\r
-.\" anchor: o_x add-header\r
-\fI-x HeaderText\fP (Old) add-header \fIHeaderText\fP (New)\r
-Add the\r
-\fI\&HeaderText\fP\r
-verbatim to requests to the server.\r
-Typical uses include\r
-adding old-style forwarding notices such as\r
-\fB\&Forwarded: by http://pro-privacy-isp.net\fP\r
-and reinstating the\r
-\fB\&Proxy-Connection: Keep-Alive\fP\r
-header\r
-(which the\r
-\fBjunkbuster\fP\r
-deletes so as\r
-not\" ijbfaq.html#detect\r
-to reveal its existence).\r
-No checking is done for correctness or plausibility,\r
-so it can be used to throw any old trash into the server-bound \r
-\s-2HTTP\s0\r
-stream.\r
-Please don't litter.\r
-.TP\r
-.\" anchor: o_s single-threaded\r
-\fI-s\fP (Old) single-threaded \fI\fP (New)\r
-Doesn't\r
-\fB\&fork()\fP\r
-a separate process\r
-(or create a separate thread)\r
-to handle each connection.\r
-Useful when debugging to keep the process single threaded.\r
-.TP\r
-.\" anchor: o_l logfile\r
-\fI-l logfile\fP (Old) logfile \fIlogfile\fP (New)\r
-Write all debugging data into\r
-\fI\&logfile.\fP\r
-The default\r
-\fI\&logfile\fP\r
-is the standard output.\r
-.TP\r
-.\" anchor: o_acl aclfile\r
-aclfile \fIaclfile\fP (New)\r
-Unless this option is used, the proxy talks to anyone who can connect to it,\r
-and everyone who can has equal permissions on where they can go.\r
-An access file allows restrictions to be placed on these two policies,\r
-by distinguishing some\r
-\fIsource\fP\r
-\s-2IP\s0\r
-addresses and/or\r
-some\r
-\fIdestination\fP\r
-addresses.\r
-(If a\r
-forwarder or a gateway\" ijbman.html#forwardfile\r
-is being used, its address is considered the destination address,\r
-not the ultimate\r
-\s-2IP\s0\r
-address of the\r
-\s-2URL\s0\r
-requested.)\r
-.P\r
-Each line of the access file begins with\r
-either the word\r
-\fB\&permit\fP\r
-or\r
-\fB\&deny\fP\r
-followed by source and (optionally) destination addresses \r
-to be matched against those of the\r
-\s-2HTTP\s0\r
-request.\r
-The last matching line specifies the result: if it was a\r
-\fB\&deny\fP\r
-line or if no line matched,\r
-the request will be refused.\r
-.P\r
-A source or destination\r
-can be specified as a single numeric\r
-\s-2IP\s0\r
-address,\r
-or with a hostname, provided that the host's name\r
-can be resolved to a numeric address: this cannot be used to block all\r
-\fB\&.mil \fP\r
-domains for example,\r
-because there is no single address associated with that domain name.\r
-Either form may be followed by a slash and an integer\r
-\fB\&N\fP,\r
-specifying a subnet mask of\r
-\fB\&N\fP\r
-bits.\r
-For example,\r
-\fB\&permit 207.153.200.72/24\fP\r
-matches the entire Class-C subnet from\r
-207.153.200.0\r
-through 207.153.200.255.\r
-(A netmask of 255.255.255.0 corresponds to 24 bits of\r
-ones in the netmask, as with\r
-\fC\&*_MASKLEN=24\fP.)\r
-A value of 16 would be used for a Class-B subnet.\r
-A value of zero for\r
-\fB\&N\fP\r
-in the subnet mask length will cause any address to match;\r
-this can be used to express a default rule.\r
-For more information see the example file provided with the distribution.\r
-.P\r
-If you like these access controls\r
-you should probably have\r
-firewall;\" ijbfaq.html#firewall\r
-they are not intended to replace one.\r
-.TP\r
-.\" anchor: o_tf trustfile\r
-trustfile \fItrustfile\fP (New)\r
-This feature is experimental, has not been fully documented and is\r
-very subject to change.\r
-The goal is for parents to be able to choose a page or site whose\r
-links they regard suitable for their\r
-young children\" ijbfaq.html#children\r
-and for the proxy to allow access only to sites mentioned there.\r
-To do this the proxy examines the\r
-referer\" ijbman.html#o_r\r
-variable on each page request to check they resulted from\r
-a click on the ``trusted referer'' site: if so the referred site\r
-is added to a list of trusted sites, so that the child can\r
-then move around that site.\r
-There are several uncertainties in this scheme that experience may be\r
-able to iron out; check back in the months ahead.\r
-.TP\r
-.\" anchor: o_ti trust_info_url\r
-trust_info_url \fItrust_info_url\fP (New)\r
-When access is denied due to lack of a trusted referer, this\r
-\s-2URL\s0\r
-is displayed with a message pointing the user to it for further information.\r
-.TP\r
-.\" anchor: o_hc hide-console\r
-hide-console \fI\fP (New)\r
-In the Windows version only, instructs the program\r
-to disconnect from and hide the command console after starting.\r
-.TP\r
-.\" anchor: o_a \r
-\fI-a\fP (Old) \r
-(Obsolete) Accept the server's\r
-\fB\&Set-cookie\fP\r
-headers, passing them through to the browser.\r
-.\" anchor: obsolete\r
-This option was removed in Version 1.2\r
-and replaced by an improvement to the\r
--c\" ijbman.html#o_c\r
-option.\r
-.LE\r
-.SH INSTALLATION AND USE\r
-Browsers must be told where to find the\r
-\fBjunkbuster\fP\r
-(e.g.\r
-\fB\&localhost\fP\r
-port 8000).\r
-To set the \r
-\s-2HTTP\s0\r
-proxy in Netscape 3.0,\r
-go through:\r
-\fB\&Options\fP;\r
-\fB\&Network Preferences\fP;\r
-\fB\&Proxies\fP;\r
-\fB\&Manual Proxy Configuration\fP;\r
-\fB\&View\fP.\r
-See the\r
-\s-2FAQ\s0\r
-for other browsers.\r
-The\r
-Security Proxy\" ijbfaq.html#security\r
-should also be set to the same values,\r
-otherwise\r
-\fB\&shttp:\fP\r
-\s-2URL\s0s\r
-won't work.\r
-.P\r
-Note the limitations\r
-explained in the\r
-\s-2FAQ\s0.\r
-.SH CHECKING OPTIONS\r
-To allow users to\r
-check\" ijbfaq.html#show\r
-that a\r
-\fBjunkbuster\fP\r
-is running and how it is configured,\r
-it intercepts requests for any\r
-\s-2URL\s0\r
-ending in\r
-\fB\&/show-proxy-args\fP\r
-and blocks it,\r
-returning instead returns information on its\r
-version number and\r
-current configuration\r
-including the contents of its blockfile.\r
-To get an explicit warning that no\r
-\fBjunkbuster\fP\r
-intervened if the proxy was not configured,\r
-it's best to point it to a\r
-\s-2URL\s0\r
-that does this, such as\r
-http://internet.junkbuster.com/cgi-bin/show-proxy-args\r
-on Junkbusters's website.\r
-.SH SEE ALSO\r
-http://www.waldherr.org/junkbuster/\" waldherr.org#\r
-.br\r
-http://www.junkbusters.com/ht/en/ijbfaq.html\" ijbfaq.html#\r
-.br\r
-http://www.junkbusters.com/ht/en/cookies.html\" cookies.html#\r
-.br\r
-http://internet.junkbuster.com/cgi-bin/show-proxy-args\r
-.br\r
-http://www.cis.ohio-state.edu/htbin/rfc/rfc2109.html\r
-.br\r
-http://squid.nlanr.net/Squid/\r
-.br\r
-http://www-math.uni-paderborn.de/~axel/\r
-.SH COPYRIGHT AND GPL\r
-Written and copyright by the Anonymous Coders and Junkbusters Corporation\r
-and made available under the\r
-GNU General Public License (GPL).\" gpl.html#\r
-This software comes with\r
-NO WARRANTY.\" gpl.html#nowarr\r
-Internet Junkbuster\r
-Proxy\r
-is a\r
-trademark\" legal.html#marks\r
-of Junkbusters Corporation.\r
diff --git a/junkbuster.init b/junkbuster.init
deleted file mode 100644 (file)
index c74b6b7..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/bin/sh\r
-#\r
-# $Id: junkbuster.init,v 1.2 2001/04/30 02:36:54 rodney Exp $\r
-#\r
-# This is file is either \r
-#\r
-#         /etc/rc.d/init.d/junkbuster \r
-#\r
-# or\r
-#\r
-#         /sbin/init.d/junkbuster\r
-#\r
-# and was put here by the junkbuster rpm\r
-#\r
-# junkbuster  This shell script takes care of starting and stopping\r
-#             junkbuster.\r
-#\r
-# This works only correctly if the user `nobody' is allowed\r
-# to be in the directory where this file is called \r
-# (for example: /root is NOT ok)\r
-# ---------------------------------------------------------------------------\r
-# Force /bin/sh as shell (padraic@renaghan.com).\r
-# Augmented with help by Sterling <wolffe@sempai.org>\r
-# Hints from mjohnson11@uswest.net\r
-# Hints from rochedav@primenet.com\r
-# ---------------------------------------------------------------------------\r
-# These lines are needed so Redhat's config tools will "see" this script:\r
-# chkconfig: 35 84 09\r
-# description: Blocks annoying ads from the internet, along with cookies \\r
-#              and a few other privacy features.      \r
-# processname: junkbuster\r
-# config: /etc/junkbuster/config\r
-\r
-\r
-# ---------------------------------------------------------------------------\r
-#\r
-# SuSE only\r
-#\r
-# ---------------------------------------------------------------------------\r
-if [ -f /etc/rc.config ]; then\r
-\r
-# Author: Daniel Bischof <daniel@suse.de>, 1999\r
-# Adjustment: Axel Braun <doc.b@gmx.de>, 17.08.2000 \r
-. /etc/rc.config\r
-#base=${0##*/}\r
-#link=${base#*[SK][0-9][0-9]}\r
-#test $link = $base && START_IJB=yes\r
-#test "$START_IJB" = "yes" || exit 0\r
-return=$rc_done\r
-case "$1" in\r
-    start)\r
-        echo -n "Starting The Internet Junkbuster"\r
-        su - nobody -c 'nohup /usr/sbin/junkbuster /etc/junkbuster/config < /dev/null > /dev/null &'         \r
-        sleep 1\r
-        echo -e "$return"\r
-        ;;\r
-    stop)\r
-        echo -n "Shutting down The Internet Junkbuster"\r
-        killproc -TERM /usr/sbin/junkbuster || return=$rc_failed\r
-        echo -e "$return"\r
-        ;;\r
-    restart|reload)\r
-        echo -n "Reload The Internet Junkbuster"\r
-        killproc -HUP /usr/sbin/junkbuster || return=$rc_failed\r
-        echo -e "$return"\r
-        ;;\r
-    status)\r
-        checkproc /usr/sbin/junkbuster && echo OK || echo No process\r
-        ;;\r
-    *)\r
-        echo "Usage: $0 {start|restart|status|stop}"\r
-        exit 1\r
-esac\r
-test "$return" = "$rc_done" || exit 1\r
-exit 0\r
-\r
-else\r
-# ---------------------------------------------------------------------------\r
-#\r
-# RedHat only\r
-#\r
-# ---------------------------------------------------------------------------\r
-\r
-# Source function library.\r
-if [ -f /etc/rc.d/init.d/functions ]; then\r
-. /etc/rc.d/init.d/functions\r
-fi\r
-\r
-if [ -f /etc/sysconfig/network ]; then\r
-. /etc/sysconfig/network\r
-fi\r
-\r
-#  Check that networking is up.\r
-[ ${NETWORKING} = "no" ] && exit 0\r
-\r
-[ -f /etc/junkbuster/config ] || exit 0\r
-\r
-[ -f /usr/sbin/junkbuster ] || exit 0\r
-\r
-RETVAL=0\r
-\r
-# See how we were called.\r
-case "$1" in\r
-\r
-   start)\r
-           # abort if already started\r
-      pid=`pidofproc junkbuster`\r
-      [ -n "$pid" ] && ps h $pid >/dev/null 2>&1 && \\r
-      echo -n "Already started: " && status junkbuster && \\r
-      exit 0\r
-\r
-      # Start daemon.\r
-      echo -n "Starting junkbuster:" && RETVAL=1\r
-      ulimit -c 0\r
-                su - nobody -s /bin/sh -c '/usr/sbin/junkbuster /etc/junkbuster/config' &\r
-      sleep 1\r
-      pid=`pidofproc junkbuster`\r
-      [ -n "$pid" ] && ps h $pid >/dev/null 2>&1 && RETVAL=0 && echo_success && touch /var/lock/subsys/junkbuster\r
-      [ $RETVAL -eq 1 ] && echo_failure\r
-      echo\r
-      ;;\r
-\r
-   stop)\r
-      # Stop daemon.\r
-      echo -n "Shutting down junkbuster:"\r
-                killproc junkbuster\r
-      RETVAL=$?\r
-      [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/junkbuster\r
-      echo\r
-      ;;\r
-\r
-   status)\r
-      status junkbuster\r
-      RETVAL=$?\r
-      ;;\r
-\r
-   restart|reload)\r
-                $0 stop && $0 start\r
-      ;;\r
-\r
-   *)\r
-      echo "Usage: junkbuster {start|stop|status|restart|reload}"\r
-      exit 1\r
-esac\r
-\r
-exit $RETVAL\r
-\r
-fi\r
-\r
diff --git a/junkbuster.logrotate b/junkbuster.logrotate
deleted file mode 100644 (file)
index e8e8b92..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Logrotate file for Junkbuster RPM
-#
-# $Id: junkbuster.logrotate,v 1.1 2001/04/30 03:17:00 rodney Exp $
-
-# Fixed problems of 
-#  filename.1 -> filename.1.2 -> filename.1.3
-#  filename.1.2.2, filename.1.2.3, filename.1.3.2, filename.1.3.3
-#  filename.1.2.2.2, filename.1.2.2.3  ...
-# by explicitly listing each logfile in the directory instead of `*'.
-#
-
-/var/log/junkbuster/junkbuster {
-   compress
-        weekly
-}
-
-
-#/var/log/junkbuster/jarfile {
-#  compress
-#        weekly
-#}
diff --git a/junkbuster.monthly b/junkbuster.monthly
deleted file mode 100644 (file)
index 44ff349..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh\r
-\r
-# $Id: junkbuster.monthly,v 1.1 2001/04/16 21:10:38 rodney Exp $\r
-#\r
-# bug fixed, which downloaded all three files to the file blocklist\r
-#\r
-# Revised: Mon Dec 06 10:46:08 PST 1999 by Jon Hamkins\r
-# Hints by Ulrik Haugen <qha@lysator.liu.se>\r
-# Hints by mirjamv@theochem.kun.nl\r
-#\r
-set -e\r
-\r
-# blocklist\r
-wget -q --output-document=/etc/junkbuster/blocklist.new \\r
-     http://www.waldherr.org/blocklist\r
-\r
-mv -f /etc/junkbuster/blocklist.new /etc/junkbuster/blocklist\r
-\r
-if [ -f /etc/junkbuster/blocklist.local ] ; then\r
-   cat /etc/junkbuster/blocklist.local >> /etc/junkbuster/blocklist\r
-fi\r
-chmod 644 /etc/junkbuster/blocklist\r
-\r
-# cookiefile\r
-wget -q --output-document=/etc/junkbuster/cookiefile.new \\r
-     http://www.waldherr.org/cookiefile\r
-\r
-mv -f /etc/junkbuster/cookiefile.new /etc/junkbuster/cookiefile\r
-\r
-if [ -f /etc/junkbuster/cookiefile.local ] ; then\r
-   cat /etc/junkbuster/cookiefile.local >> /etc/junkbuster/cookiefile\r
-fi\r
-chmod 644 /etc/junkbuster/cookiefile\r
-\r
-# imagelist\r
-wget -q --output-document=/etc/junkbuster/imagelist.new \\r
-     http://www.waldherr.org/imagelist\r
-\r
-mv -f /etc/junkbuster/imagelist.new /etc/junkbuster/imagelist\r
-\r
-if [ -f /etc/junkbuster/imagelist.local ] ; then\r
-   cat /etc/junkbuster/imagelist.local >> /etc/junkbuster/imagelist\r
-fi\r
-chmod 644 /etc/junkbuster/imagelist\r
diff --git a/junkbuster.weekly b/junkbuster.weekly
deleted file mode 100644 (file)
index bc07b23..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh\r
-\r
-# $Id: junkbuster.weekly,v 1.1 2001/04/16 21:10:38 rodney Exp $\r
-\r
-# Revised: Mon Dec 06 10:46:08 PST 1999 by Jon Hamkins\r
-# Hints by Ulrik Haugen <qha@lysator.liu.se>\r
-# Hints by mirjamv@theochem.kun.nl\r
-\r
-set -e\r
-\r
-# blocklist\r
-wget -q --output-document=/etc/junkbuster/blocklist.new \\r
-     http://www.waldherr.org/blocklist\r
-\r
-mv -f /etc/junkbuster/blocklist.new /etc/junkbuster/blocklist\r
-\r
-if [ -f /etc/junkbuster/blocklist.local ] ; then\r
-   cat /etc/junkbuster/blocklist.local >> /etc/junkbuster/blocklist\r
-fi\r
-\r
-chmod 644 /etc/junkbuster/blocklist\r
index 7004962..3465373 100644 (file)
@@ -1,18 +1,18 @@
-const char killpopup_rcs[] = "$Id: killpopup.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char killpopup_rcs[] = "$Id: killpopup.c,v 1.15 2002/03/24 13:25:43 swa Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/killpopup.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/killpopup.c,v $
  *
  * Purpose     :  Handles the filtering of popups.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -32,6 +32,73 @@ const char killpopup_rcs[] = "$Id: killpopup.c,v 1.1 2001/05/13 21:57:06 adminis
  *
  * Revisions   :
  *    $Log: killpopup.c,v $
+ *    Revision 1.15  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.14  2002/03/07 03:46:53  oes
+ *    Fixed compiler warnings etc
+ *
+ *    Revision 1.13  2001/11/13 00:16:40  jongfoster
+ *    Replacing references to malloc.h with the standard stdlib.h
+ *    (See ANSI or K&R 2nd Ed)
+ *
+ *    Revision 1.12  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.11  2001/10/07 15:42:41  oes
+ *    filter_popups now gets a csp pointer so it can raise the new
+ *      CSP_FLAG_MODIFIED flag.
+ *
+ *    Revision 1.10  2001/09/22 16:34:44  jongfoster
+ *    Removing unneeded #includes
+ *
+ *    Revision 1.9  2001/07/31 14:44:22  oes
+ *    Deleted unused size parameter from filter_popups()
+ *
+ *    Revision 1.8  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.7  2001/07/20 19:29:25  haroon
+ *    - In v1.5 forgot to add that I implemented LOG_LEVEL_POPUPS in errlog.c,
+ *      errlog.h and killpopup.c. In that case, it is superfluous to have define for
+ *      POPUP_VERBOSE, so I removed the defines and logging is now done
+ *      via log_error(LOG_LEVEL_POPUPS, ....)
+ *
+ *    Revision 1.6  2001/07/19 19:11:35  haroon
+ *    - Implemented Guy's idea of replacing window.open( with 1;''.concat(
+ *    - Implemented Guy's idea of replacing .resizeTo( with .scrollTo(
+ *
+ *    Revision 1.5  2001/07/18 15:02:52  haroon
+ *    improved nuking of window.open
+ *
+ *    Revision 1.4  2001/06/29 13:29:55  oes
+ *    Added FIXMEs (and didn't repair, hehe)
+ *
+ *    Revision 1.3  2001/05/22 18:56:28  oes
+ *    CRLF -> LF
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:58  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -42,201 +109,102 @@ const char killpopup_rcs[] = "$Id: killpopup.c,v 1.1 2001/05/13 21:57:06 adminis
 #include <stdlib.h>
 #include <sys/types.h>
 #include <string.h>
-#include <malloc.h>
 #include <errno.h>
 #include <sys/stat.h>
 #include <ctype.h>
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__OS2__)
 #include <unistd.h>
 #endif
 
 #include "project.h"
 #include "killpopup.h"
-#include "jcc.h"
+#include "errlog.h"
 
 const char killpopup_h_rcs[] = KILLPOPUP_H_VERSION;
 
-#ifdef KILLPOPUPS
-
-/* Change these for debug output.  *lots*. */
-/*#define POPUP_VERBOSE 1*/
-/* CHANGED - added the below and shifted the more spammy stuff into it ;-) */
-#undef POPUP_VERY_VERBOSE
-#undef POPUP_VERBOSE
-
+#ifdef FEATURE_KILL_POPUPS
 
 /*********************************************************************
  *
  * Function    :  filter_popups
  *
- * Description :  Filter the block of data that's been read from the server.
- *                IF NECESSARY.
+ * Description :  Filter the block of data that's been read from the server
+ *                for javascript popup code and replace by syntactically
+ *                neutral code of the same size.
+ *                Raise the CSP_FLAG_MODIFIED flag on success.
  *
  * Parameters  :
- *          1  :  csp = Client state
- *          2  :  host_name = hostname of originating web page to
- *                look up on blocklist
- *          3  :  buff = Buffer to scan and modify.  Null terminated.
- *          4  :  size = Buffer size, excluding null terminator.
+ *          1  :  buff = Buffer to scan and modify.  Null terminated.
+ *          2  :  csp = Client state pointer
  *
  * Returns     :  void
  *
  *********************************************************************/
-void filter_popups(struct client_state *csp, char *host_name, char *buff, int size)
+void filter_popups(char *buff, struct client_state *csp)
 {
-   struct popup_settings * data;
-   struct popup_blocklist * cur;
-   int i;
-   int found = 0;
-   char *popup = NULL;
-   char *close = NULL;
+   char *start_p = NULL;
+   char *close_p = NULL;
    char *p     = NULL;
-   char *q     = NULL; /* by BREITENB NEW! */
-
-   if ( (!csp->plist) || ((data = csp->plist->f) == NULL) )
-   {
-      /* Disabled. */
-      return;
-   }
 
-   /* If the hostname is on our list for blocking then mark it
-    * as a host to   block from.  (This may be later changed if the
-    * host is also on the list-to-allow list).
+   /*
+    * replace the window.open( with a harmless JavaScript replacement
+    * (notice the two single quotes)
     */
-
-   for (i=0; (i < 50) && (i < size); i++)   /* avoid scanning binary data! */
-   {
-      if ((unsigned int)(buff[i])>127)
-      {
-#ifdef  POPUP_VERBOSE
-         fprintf(logfp, "I'm not scanning binary stuff! (%i)\n",buff[i]);
-#endif
-         return;
-      }
-   }
-
-
-   for (cur = data->blocked ; cur ; cur = cur->next)
-   {
-      if ( host_name != 0 )
-      {
-         if ( strcmp( cur->host_name, host_name ) == 0 )
-         {
-#ifdef  POPUP_VERBOSE
-            fprintf(logfp, "Blocking %s\n", host_name );
-#endif
-            found = 1;
-         }
-      }
-   }
-
-   /* Force match if we're supposed to nuke _all_ popups, globally. */
-   if ( kill_all_popups != 0 )
-   {
-#ifdef POPUP_VERBOSE
-      fprintf(logfp, "Indescriminatly nuking popups..\n" );
-#endif
-      found = 1;
-   }
-   /* an exception-from blocking should still be an exception! by BREITENB NEW! */
-
-
-   /*    Now, if its allowed adjust the filtering, so it _doesn't_ happen. */
-   for (cur = data->allowed ; cur ; cur = cur->next)
+   while ((start_p = strstr(buff, "window.open(")) != NULL)
    {
-      if ( host_name != 0 )
+      if (start_p)
       {
-         if ( strcmp( cur->host_name, host_name ) == 0 )
-         {
-#ifdef POPUP_VERBOSE
-            fprintf(logfp, "Reversing block decision for %s\n", host_name );
-#endif
-            found = 0;
-         }
+         strncpy(start_p, "1;''.concat(", 12);
+         log_error(LOG_LEVEL_POPUPS, "Blocked popup window open");
+         csp->flags |= CSP_FLAG_MODIFIED;
       }
    }
 
-   if ( found == 0)
-   {
-#ifdef POPUP_VERBOSE
-      fprintf(logfp, "Allowing %s\n", host_name );
-#endif
-      return;
-   }
-
-   while ((popup = strstr( buff, "window.open(" )) != NULL)
-      /* if ( popup  )  by BREITENB filter ALL popups! NEW! */
+   /*
+    * replace the .resizeTo( with a harmless JavaScript replacement
+    */
+   while ((start_p = strstr(buff, ".resizeTo(")) != NULL)
    {
-#ifdef POPUP_VERBOSE
-      fprintf(logfp, "Found start of window open" );
-#endif
-      close = strstr( popup+1, ");" );
-      if ( close )
-      {
-#ifdef POPUP_VERBOSE
-         fprintf(logfp, "Found end of window open" );
-#endif
-         for ( p = popup; p != (close+1); p++ )
-         {
-            *p = ' ';
-         }
-#ifdef POPUP_VERBOSE
-         fprintf(logfp, "Blocked %s\n", host_name );
-#endif
-      }
-      else
+      if (start_p)
       {
-#ifdef POPUP_VERBOSE
-         fprintf(logfp, "Couldn't find end, turned into comment.  Read boundary?\n" );
-#endif
-         *popup = '/';
-         popup++;
-         *popup = '/';
-      }
-
-
-      q=popup; /* by BREITENB NEW! */
-      while (q>=buff)
-      {
-         if (*q==' ' || *q=='\t')
-            q--;
-         else break;
-      }
-      if (q>=buff)
-      {
-         if (*q=='=') *++q='1';
-         /* result of popup is assigned to a variable! ensure success. hehehe. */
+         strncpy(start_p, ".scrollTo(", 10);
+         log_error(LOG_LEVEL_POPUPS, "Blocked popup window resize");
+         csp->flags |= CSP_FLAG_MODIFIED;
       }
    }
 
-   /* Filter all other crap like onUnload onExit etc.  (by BREITENB) NEW!*/
-   popup=strstr( buff, "<body");
-   if (!popup) popup=strstr( buff, "<BODY");
-   if (!popup) popup=strstr( buff, "<Body");
-   if (!popup) popup=strstr( buff, "<BOdy");
-   if (popup)
+   /* 
+    * Filter onUnload and onExit
+    */
+   start_p = strstr(buff, "<body");
+   if (!start_p) start_p = strstr(buff, "<BODY");
+   if (!start_p) start_p = strstr(buff, "<Body");
+   if (!start_p) start_p = strstr(buff, "<BOdy");
+   if (start_p)
    {
-      q=strchr(popup,'>');
-      if (q)
+      close_p = strchr(start_p, '>');
+      if (close_p)
       {
          /* we are now between <body and the ending > */
-         p=strstr(popup, "onUnload");
+         p = strstr(start_p, "onUnload");
          if (p)
          {
-            strncpy(p,"_nU_",4);
+            strncpy(p, "_nU_", 4);
+            csp->flags |= CSP_FLAG_MODIFIED;
          }
-         p=strstr(popup, "onExit");
+         p = strstr(start_p, "onExit");
          if (p)
          {
-            strncpy(p,"_nE_",4);
+            strncpy(p, "_nE_", 4);
+            csp->flags |= CSP_FLAG_MODIFIED;
          }
       }
    }
 
 }
 
-#endif /* def KILLPOPUPS */
+#endif /* def FEATURE_KILL_POPUPS */
 
 /*
   Local Variables:
index 42602ea..7d2eadf 100644 (file)
@@ -1,14 +1,14 @@
-#ifndef _KILLPOPUP_H
-#define _KILLPOPUP_H
-#define KILLPOPUP_H_VERSION "$Id: killpopup.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef KILLPOPUP_H_INCLUDED
+#define KILLPOPUP_H_INCLUDED
+#define KILLPOPUP_H_VERSION "$Id: killpopup.h,v 1.7 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/killpopup.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/killpopup.h,v $
  *
  * Purpose     :  Handles the filtering of popups.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: killpopup.h,v $
+ *    Revision 1.7  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.6  2001/10/07 15:42:41  oes
+ *    filter_popups now gets a csp pointer so it can raise the new
+ *      CSP_FLAG_MODIFIED flag.
+ *
+ *    Revision 1.5  2001/07/31 14:44:22  oes
+ *    Deleted unused size parameter from filter_popups()
+ *
+ *    Revision 1.4  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.3  2001/07/29 18:59:21  jongfoster
+ *    - Changing #define _KILLPOPUP_H to KILLPOPUP_H_INCLUDED
+ *    - Adding extern "C" {}
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:58  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
 #include "project.h"
 
-#ifdef KILLPOPUPS
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-extern void filter_popups(struct client_state *csp, char *host_name, char *buff, int size);
+#ifdef FEATURE_KILL_POPUPS
 
-#endif /* def KILLPOPUPS */
+extern void filter_popups(char *buff, struct client_state *csp);
+
+#endif /* def FEATURE_KILL_POPUPS */
 
 /* Revision control strings from this header and associated .c file */
 extern const char killpopup_rcs[];
 extern const char killpopup_h_rcs[];
 
-#endif /* ndef _KILLPOPUP_H */
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef KILLPOPUP_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/list.c b/list.c
new file mode 100644 (file)
index 0000000..6cd7f89
--- /dev/null
+++ b/list.c
@@ -0,0 +1,1064 @@
+const char list_rcs[] = "$Id: list.c,v 1.14 2002/03/24 13:25:43 swa Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/list.c,v $
+ *
+ * Purpose     :  Declares functions to handle lists.
+ *                Functions declared include:
+ *                   `destroy_list', `enlist' and `list_to_text'
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: list.c,v $
+ *    Revision 1.14  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.13  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.12  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.11  2001/10/23 21:21:03  jongfoster
+ *    New error handling - error codes are now jb_errs, not ints.
+ *    Changed the way map() handles out-of-memory, to dramatically
+ *    reduce the amount of error-checking clutter needed.
+ *
+ *    Revision 1.10  2001/09/16 17:30:24  jongfoster
+ *    Fixing a compiler warning.
+ *
+ *    Revision 1.9  2001/09/16 13:20:29  jongfoster
+ *    Rewrite of list library.  Now has seperate header and list_entry
+ *    structures.  Also added a large sprinking of assert()s to the list
+ *    code.
+ *
+ *    Revision 1.8  2001/08/07 14:00:20  oes
+ *    Fixed comment
+ *
+ *    Revision 1.7  2001/08/05 16:06:20  jongfoster
+ *    Modifiying "struct map" so that there are now separate header and
+ *    "map_entry" structures.  This means that functions which modify a
+ *    map no longer need to return a pointer to the modified map.
+ *    Also, it no longer reverses the order of the entries (which may be
+ *    important with some advanced template substitutions).
+ *
+ *    Revision 1.6  2001/07/31 14:44:51  oes
+ *    list_to_text() now appends empty line at end
+ *
+ *    Revision 1.5  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.4  2001/06/29 13:30:22  oes
+ *    - Added Convenience function enlist_unique_header(),
+ *      which takes the Header name and value as separate
+ *      arguments and thus saves the pain of sprintf()ing
+ *      and determining the Header name length to enlist_unique
+ *    - Improved comments
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.3  2001/06/03 19:12:24  oes
+ *    functions for new struct map, extended enlist_unique
+ *
+ *    Revision 1.2  2001/06/01 18:49:17  jongfoster
+ *    Replaced "list_share" with "list" - the tiny memory gain was not
+ *    worth the extra complexity.
+ *
+ *    Revision 1.1  2001/05/31 21:11:53  jongfoster
+ *    - Moved linked list support to new "list.c" file.
+ *      Structure definitions are still in project.h,
+ *      function prototypes are now in "list.h".
+ *    - Added support for "struct list_share", which is identical
+ *      to "struct list" except it saves memory by not duplicating
+ *      the strings.  Obviously, this only works if there is some
+ *      other way of managing the memory used by the strings.
+ *      (These list_share lists are used for lists which last
+ *      for only 1 request, and where all the list entries are
+ *      just coming directly from entries in the actionsfile.)
+ *      Note that you still need to destroy list_share lists
+ *      properly to free the nodes - it's only the strings
+ *      which are shared.
+ *
+ *
+ *********************************************************************/
+\f
+
+#include "config.h"
+
+#ifndef _WIN32
+/* FIXME: The following headers are not needed for Win32.  Are they
+ * needed on other platforms?
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <ctype.h>
+#endif
+#include <string.h>
+
+#if !defined(_WIN32) && !defined(__OS2__)
+#include <unistd.h>
+#endif
+
+#include <assert.h>
+
+#include "project.h"
+#include "list.h"
+#include "miscutil.h"
+
+const char list_h_rcs[] = LIST_H_VERSION;
+
+
+static int list_is_valid (const struct list *the_list);
+
+
+/*********************************************************************
+ *
+ * Function    :  list_init
+ *
+ * Description :  Create a new, empty list in user-allocated memory.
+ *                Caller should allocate a "struct list" variable,
+ *                then pass it to this function.
+ *                (Implementation note:  Rather than calling this
+ *                function, you can also just memset the memory to
+ *                zero, e.g. if you have a larger structure you
+ *                want to initialize quickly.  However, that isn't
+ *                really good design.)
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void init_list(struct list *the_list)
+{
+   memset(the_list, '\0', sizeof(*the_list));
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  destroy_list
+ *
+ * Description :  Destroy a string list (opposite of list_init).
+ *                On return, the memory used by the list entries has
+ *                been freed, but not the memory used by the_list
+ *                itself.  You should not re-use the_list without
+ *                calling list_init().
+ *
+ *                (Implementation note:  You *can* reuse the_list
+ *                without calling list_init(), but please don't.
+ *                If you want to remove all entries from a list
+ *                and still have a usable list, then use
+ *                list_remove_all().)
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void destroy_list (struct list *the_list)
+{
+   struct list_entry *cur_entry, *next_entry;
+
+   assert(the_list);
+
+   for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
+   {
+      next_entry = cur_entry->next;
+      freez(cur_entry->str);
+      free(cur_entry);
+   }
+
+   the_list->first = NULL;
+   the_list->last = NULL;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_is_valid
+ *
+ * Description :  Check that a string list is valid.  The intended
+ *                usage is "assert(list_is_valid(the_list))".
+ *                Currently this checks that "the_list->last"
+ *                is correct, and that the list dosn't contain
+ *                circular references.  It is likely to crash if
+ *                it's passed complete garbage.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list.  Must be non-null.
+ *
+ * Returns     :  1 if list is valid, 0 otherwise.
+ *
+ *********************************************************************/
+static int list_is_valid (const struct list *the_list)
+{
+   /*
+    * If you don't want this check, just change the line below
+    * from "#if 1" to "#if 0".
+    */
+#if 1
+   const struct list_entry *cur_entry;
+   const struct list_entry *last_entry = NULL;
+   int length = 0;
+
+   assert(the_list);
+
+   for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
+   {
+      last_entry = cur_entry;
+
+      if (cur_entry->str)
+      {
+         /*
+          * Just check that this string can be accessed - i.e. it's a valid
+          * pointer.
+          */
+         strlen(cur_entry->str);
+      }
+
+      /*
+       * Check for looping back to first
+       */
+      if ((length != 0) && (cur_entry == the_list->first))
+      {
+         return 0;
+      }
+
+      /*
+       * Arbitrarily limit length to prevent infinite loops.
+       */
+      if (++length > 1000)
+      {
+         return 0;
+      }
+
+      /*
+       * Check this isn't marked as the last entry, unless of course it's
+       * *really* the last entry.
+       */
+      if ((the_list->last == cur_entry) && (cur_entry->next != NULL))
+      {
+         /* This is the last entry, but there's data after it !!?? */
+         return 0;
+      }
+   }
+
+   return (the_list->last == last_entry);
+#else
+   return 1;
+#endif
+}
+
+/*********************************************************************
+ *
+ * Function    :  enlist
+ *
+ * Description :  Append a string into a specified string list.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *          2  :  str = string to add to the list (maybe NULL)
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *                On error, the_list will be unchanged.
+ *
+ *********************************************************************/
+jb_err enlist(struct list *the_list, const char *str)
+{
+   struct list_entry *cur;
+
+   assert(the_list);
+   assert(list_is_valid(the_list));
+
+   if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   if (str)
+   {
+      if (NULL == (cur->str = strdup(str)))
+      {
+         free(cur);
+         return JB_ERR_MEMORY;
+      }
+   }
+   /* else { cur->str = NULL; }  - implied by zalloc */
+
+   /* cur->next = NULL;  - implied by zalloc */
+
+   if (the_list->last)
+   {
+      the_list->last->next = cur;
+      the_list->last = cur;
+   }
+   else
+   {
+      the_list->first = cur;
+      the_list->last = cur;
+   }
+
+   assert(list_is_valid(the_list));
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  enlist_first
+ *
+ * Description :  Append a string as first element into a specified
+ *                string list.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *          2  :  str = string to add to the list (maybe NULL)
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *                On error, the_list will be unchanged.
+ *
+ *********************************************************************/
+jb_err enlist_first(struct list *the_list, const char *str)
+{
+   struct list_entry *cur;
+
+   assert(the_list);
+   assert(list_is_valid(the_list));
+
+   if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   if (str)
+   {
+      if (NULL == (cur->str = strdup(str)))
+      {
+         free(cur);
+         return JB_ERR_MEMORY;
+      }
+   }
+   /* else { cur->str = NULL; }  - implied by zalloc */
+
+   cur->next = the_list->first;
+
+   the_list->first = cur;
+   if (the_list->last == NULL)
+   {
+      the_list->last = cur;
+   }
+
+   assert(list_is_valid(the_list));
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  enlist_unique
+ *
+ * Description :  Append a string into a specified string list,
+ *                if & only if it's not there already.
+ *                If the num_significant_chars argument is nonzero,
+ *                only compare up to the nth character.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *          2  :  str = string to add to the list
+ *          3  :  num_significant_chars = number of chars to use
+ *                for uniqueness test, or 0 to require an exact match.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *                On error, the_list will be unchanged.
+ *                "Success" does not indicate whether or not the
+ *                item was already in the list.
+ *
+ *********************************************************************/
+jb_err enlist_unique(struct list *the_list, const char *str,
+                     size_t num_significant_chars)
+{
+   struct list_entry *cur_entry;
+
+   assert(the_list);
+   assert(list_is_valid(the_list));
+   assert(str);
+   assert(num_significant_chars >= 0);
+   assert(num_significant_chars <= strlen(str));
+
+   if (num_significant_chars > 0)
+   {
+      for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
+      {
+         if ( (cur_entry->str != NULL)
+           && (0 == strncmp(str, cur_entry->str, num_significant_chars)))
+         {
+            /* Already there */
+            return JB_ERR_OK;
+         }
+      }
+   }
+   else
+   {
+      /* Test whole string */
+      for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
+      {
+         if ( (cur_entry->str != NULL) && (0 == strcmp(str, cur_entry->str)))
+         {
+            /* Already there */
+            return JB_ERR_OK;
+         }
+      }
+   }
+
+   return enlist(the_list, str);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  enlist_unique_header
+ *
+ * Description :  Make a HTTP header from the two strings name and value,
+ *                and append the result into a specified string list,
+ *                if & only if there isn't already a header with that name.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *          2  :  name = HTTP header name (e.g. "Content-type")
+ *          3  :  value = HTTP header value (e.g. "text/html")
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *                On error, the_list will be unchanged.
+ *                "Success" does not indicate whether or not the
+ *                header was already in the list.
+ *
+ *********************************************************************/
+jb_err enlist_unique_header(struct list *the_list, const char *name,
+                            const char *value)
+{
+   size_t length;
+   jb_err result;
+   char *str;
+
+   assert(the_list);
+   assert(list_is_valid(the_list));
+   assert(name);
+   assert(value);
+
+   length = strlen(name) + 2;
+   if (NULL == (str = (char *)malloc(length + strlen(value) + 1)))
+   {
+      return JB_ERR_MEMORY;
+   }
+   strcpy(str, name);
+   str[length - 2] = ':';
+   str[length - 1] = ' ';
+   strcpy(str + length, value);
+
+   result = enlist_unique(the_list, str, length);
+
+   free(str);
+
+   assert(list_is_valid(the_list));
+
+   return result;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_remove_all
+ *
+ * Description :  Remove all entries from a list.  On return, the_list
+ *                is a valid, empty list.  Note that this is similar
+ *                to destroy_list(), but the difference is that this
+ *                function guarantees that the list structure is still
+ *                valid after the call.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void list_remove_all(struct list *the_list)
+{
+   struct list_entry *cur_entry;
+   struct list_entry *next_entry;
+
+   assert(the_list);
+   assert(list_is_valid(the_list));
+
+   for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
+   {
+      next_entry = cur_entry->next;
+      freez(cur_entry->str);
+      free(cur_entry);
+   }
+
+   the_list->first = the_list->last = NULL;
+
+   assert(list_is_valid(the_list));
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_to_text
+ *
+ * Description :  "Flatten" a string list into 1 long \r\n delimited string,
+ *                adding an empty line at the end.  NULL entries are ignored.
+ *                This function does not change the_list.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *
+ * Returns     :  NULL on malloc error, else new long string.
+ *                Caller must free() it.
+ *
+ *********************************************************************/
+char *list_to_text(const struct list *the_list)
+{
+   struct list_entry *cur_entry;
+   char *ret = NULL;
+   char *s;
+   size_t size = 2;
+
+   assert(the_list);
+   assert(list_is_valid(the_list));
+
+   for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
+   {
+      if (cur_entry->str)
+      {
+         size += strlen(cur_entry->str) + 2;
+      }
+   }
+
+   if ((ret = (char *)malloc(size + 1)) == NULL)
+   {
+      return NULL;
+   }
+
+   ret[size] = '\0';
+
+   s = ret;
+
+   for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
+   {
+      if (cur_entry->str)
+      {
+         strcpy(s, cur_entry->str);
+         s += strlen(s);
+         *s++ = '\r'; *s++ = '\n';
+      }
+   }
+   *s++ = '\r'; *s++ = '\n';
+
+   return ret;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_remove_item
+ *
+ * Description :  Remove a string from a specified string list.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list
+ *          2  :  str = string to remove from the list - non-NULL
+ *
+ * Returns     :  Number of times it was removed.
+ *
+ *********************************************************************/
+int list_remove_item(struct list *the_list, const char *str)
+{
+   struct list_entry *prev = NULL;
+   struct list_entry *cur;
+   struct list_entry *next;
+   int count = 0;
+
+   assert(the_list);
+   assert(list_is_valid(the_list));
+   assert(str);
+
+   cur = the_list->first;
+
+   while (cur != NULL)
+   {
+      next = cur->next;
+
+      if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
+      {
+         count++;
+
+         if (prev != NULL)
+         {
+            prev->next = next;
+         }
+         else
+         {
+            the_list->first = next;
+         }
+         free((char *)cur->str);
+         free(cur);
+      }
+      else
+      {
+         prev = cur;
+      }
+      cur = next;
+   }
+
+   the_list->last = prev;
+
+   assert(list_is_valid(the_list));
+
+   return count;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_remove_list
+ *
+ * Description :  Remove all strings in one list from another list.
+ *                This is currently a brute-force algorithm
+ *                (it compares every pair of strings).
+ *
+ * Parameters  :
+ *          1  :  dest = list to change
+ *          2  :  src = list of strings to remove
+ *
+ * Returns     :  Total number of strings removed.
+ *
+ *********************************************************************/
+int list_remove_list(struct list *dest, const struct list *src)
+{
+   struct list_entry *cur;
+   int count = 0;
+
+   assert(src);
+   assert(dest);
+   assert(list_is_valid(src));
+   assert(list_is_valid(dest));
+
+   for (cur = src->first; cur != NULL; cur = cur->next)
+   {
+      if (cur->str != NULL)
+      {
+         count += list_remove_item(dest, cur->str);
+      }
+   }
+
+   assert(list_is_valid(src));
+   assert(list_is_valid(dest));
+
+   return count;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_duplicate
+ *
+ * Description :  Copy a string list
+ *
+ * Parameters  :
+ *          1  :  dest = Destination list.  Must be a valid list.
+ *                       All existing entries will be removed.
+ *          1  :  src = pointer to source list for copy.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *                On error, dest will be empty.
+ *
+ *********************************************************************/
+jb_err list_duplicate(struct list *dest, const struct list *src)
+{
+   struct list_entry * cur_src;
+   struct list_entry * cur_dest;
+
+   assert(src);
+   assert(dest);
+   assert(list_is_valid(src));
+   assert(list_is_valid(dest));
+
+   list_remove_all(dest);
+
+   /* Need to process first entry specially so we can set dest->first */
+   cur_src = src->first;
+   if (cur_src)
+   {
+      cur_dest = dest->first = (struct list_entry *)zalloc(sizeof(*cur_dest));
+      if (cur_dest == NULL)
+      {
+         destroy_list(dest);
+
+         assert(list_is_valid(src));
+         assert(list_is_valid(dest));
+
+         return JB_ERR_MEMORY;
+      }
+
+      if (cur_src->str)
+      {
+         cur_dest->str = strdup(cur_src->str);
+         if (cur_dest->str == NULL)
+         {
+            destroy_list(dest);
+
+            assert(list_is_valid(src));
+            assert(list_is_valid(dest));
+
+            return JB_ERR_MEMORY;
+         }
+      }
+      /* else { cur_dest->str = NULL; }  - implied by zalloc */
+
+      /* Now process the rest */
+      for (cur_src = cur_src->next; cur_src; cur_src = cur_src->next)
+      {
+         cur_dest = cur_dest->next = (struct list_entry *)zalloc(sizeof(*cur_dest));
+         if (cur_dest == NULL)
+         {
+            destroy_list(dest);
+
+            assert(list_is_valid(src));
+            assert(list_is_valid(dest));
+
+            return JB_ERR_MEMORY;
+         }
+         if (cur_src->str)
+         {
+            cur_dest->str = strdup(cur_src->str);
+            if (cur_dest->str == NULL)
+            {
+               destroy_list(dest);
+
+               assert(list_is_valid(src));
+               assert(list_is_valid(dest));
+
+               return JB_ERR_MEMORY;
+            }
+         }
+         /* else { cur_dest->str = NULL; }  - implied by zalloc */
+      }
+
+      dest->last = cur_dest;
+   }
+
+   assert(list_is_valid(src));
+   assert(list_is_valid(dest));
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_append_list_unique
+ *
+ * Description :  Append a string list to another list.
+ *                Duplicate items are not added.
+ *
+ * Parameters  :
+ *          1  :  dest = pointer to destination list for merge.
+ *          2  :  src = pointer to source for merge.
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *                On error, some (but not all) of src might have
+ *                been copied into dest.
+ *
+ *********************************************************************/
+jb_err list_append_list_unique(struct list *dest, const struct list *src)
+{
+   struct list_entry * cur;
+
+   assert(src);
+   assert(dest);
+   assert(list_is_valid(src));
+   assert(list_is_valid(dest));
+
+   for (cur = src->first; cur; cur = cur->next)
+   {
+      if (cur->str)
+      {
+         if (enlist_unique(dest, cur->str, 0))
+         {
+            assert(list_is_valid(src));
+            assert(list_is_valid(dest));
+
+            return JB_ERR_MEMORY;
+         }
+      }
+   }
+
+   assert(list_is_valid(src));
+   assert(list_is_valid(dest));
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  list_is_empty
+ *
+ * Description :  Test whether a list is empty.  Does not change the list.
+ *
+ * Parameters  :
+ *          1  :  the_list = pointer to list to test.
+ *
+ * Returns     :  Nonzero iff the list contains no entries.
+ *
+ *********************************************************************/
+int list_is_empty(const struct list *the_list)
+{
+   assert(the_list);
+   assert(list_is_valid(the_list));
+
+   return (the_list->first == NULL);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  new_map
+ *
+ * Description :  Create a new, empty map.
+ *
+ * Parameters  :  N/A
+ *
+ * Returns     :  A new, empty map, or NULL if out of memory.
+ *
+ *********************************************************************/
+struct map *new_map(void)
+{
+   return (struct map *) zalloc(sizeof(struct map));
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_map
+ *
+ * Description :  Free the memory occupied by a map and its
+ *                depandant strings
+ *
+ * Parameters  :
+ *          1  :  the_map = map to be freed.  May be NULL.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void free_map(struct map *the_map)
+{
+   struct map_entry *cur_entry;
+   struct map_entry *next_entry;
+
+   if (the_map == NULL)
+   {
+      return;
+   }
+
+   for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = next_entry)
+   {
+      freez(cur_entry->name);
+      freez(cur_entry->value);
+
+      next_entry = cur_entry->next;
+      free(cur_entry);
+   }
+
+   the_map->first = the_map->last = NULL;
+
+   free(the_map);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  map
+ *
+ * Description :  Add a mapping from given name to given value to a
+ *                given map.
+ *
+ *                Note: Since all strings will be free()d in free_map()
+ *                      later, set the copy flags for constants or
+ *                      strings that will be independantly free()d.
+ *
+ *                Note2: This function allows NULL parameters - it
+ *                       returns JB_ERR_MEMORY in that case.
+ *
+ *                Note3: If this function returns JB_ERR_MEMORY,
+ *                       it will free(name) unless you specify
+ *                       name_needs_copying, and similarly it will
+ *                       free(value) unless you specify
+ *                       value_needs_copying.
+ *
+ *                Due to Note2 and Note3 above, the following code
+ *                is legal, and will never crash or leak memory even
+ *                if the system runs out of memory:
+ *
+ *                    err = map(mymap, "xyz", 1, html_encode(somestring), 0);
+ *
+ *                err will be set to JB_ERR_MEMORY if either call runs
+ *                out-of-memory.  Without these features, you would
+ *                need to check the return value of html_encode in the
+ *                above example for NULL, which (at least) doubles the
+ *                amount of error-checking code needed.
+ *
+ * Parameters  :
+ *          1  :  the_map = map to add to
+ *          2  :  name = name to add
+ *          3  :  name_needs_copying = flag set if a copy of name should be used
+ *          4  :  value = value to add
+ *          5  :  value_needs_copying = flag set if a copy of value should be used
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err map(struct map *the_map,
+           const char *name, int name_needs_copying,
+           const char *value, int value_needs_copying)
+{
+   struct map_entry *new_entry;
+
+   assert(the_map);
+
+   if ( (NULL == value)
+     || (NULL == name)
+     || (NULL == (new_entry = zalloc(sizeof(*new_entry)))) )
+   {
+      if ((name != NULL) && (!name_needs_copying))
+      {
+          free((char *)name);
+      }
+      if ((value != NULL) && (!value_needs_copying))
+      {
+          free((char *)value);
+      }
+      return JB_ERR_MEMORY;
+   }
+
+   if (name_needs_copying)
+   {
+      if (NULL == (name = strdup(name)))
+      {
+         free(new_entry);
+         if (!value_needs_copying)
+         {
+             free((char *)value);
+         }
+         return JB_ERR_MEMORY;
+      }
+   }
+
+   if (value_needs_copying)
+   {
+      if (NULL == (value = strdup(value)))
+      {
+         free((char *)name);
+         free(new_entry);
+         return JB_ERR_MEMORY;
+      }
+   }
+
+   new_entry->name = name;
+   new_entry->value = value;
+   /* new_entry->next = NULL;  - implied by zalloc */
+
+   if (the_map->last)
+   {
+      the_map->last->next = new_entry;
+      the_map->last = new_entry;
+   }
+   else
+   {
+      the_map->first = new_entry;
+      the_map->last = new_entry;
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  lookup
+ *
+ * Description :  Look up an item with a given name in a map, and
+ *                return its value
+ *
+ * Parameters  :
+ *          1  :  the_map = map to look in
+ *          2  :  name = name parameter to look for
+ *
+ * Returns     :  the value if found, else the empty string.
+ *                Return value is alloced as part of the map, so
+ *                it is freed when the map is destroyed.  Caller
+ *                must not free or modify it.
+ *
+ *********************************************************************/
+const char *lookup(const struct map *the_map, const char *name)
+{
+   const struct map_entry *cur_entry;
+
+   assert(the_map);
+   assert(name);
+
+   for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = cur_entry->next)
+   {
+      if (!strcmp(name, cur_entry->name))
+      {
+         return cur_entry->value;
+      }
+   }
+   return "";
+}
+
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/list.h b/list.h
new file mode 100644 (file)
index 0000000..afa4423
--- /dev/null
+++ b/list.h
@@ -0,0 +1,164 @@
+#ifndef LIST_H_INCLUDED
+#define LIST_H_INCLUDED
+#define LIST_H_VERSION "$Id: list.h,v 1.11 2002/03/24 13:25:43 swa Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/list.h,v $
+ *
+ * Purpose     :  Declares functions to handle lists.
+ *                Functions declared include:
+ *                   `destroy_list', `enlist' and `list_to_text'
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: list.h,v $
+ *    Revision 1.11  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.10  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.9  2001/10/23 21:21:03  jongfoster
+ *    New error handling - error codes are now jb_errs, not ints.
+ *    Changed the way map() handles out-of-memory, to dramatically
+ *    reduce the amount of error-checking clutter needed.
+ *
+ *    Revision 1.8  2001/09/16 17:30:24  jongfoster
+ *    Fixing a compiler warning.
+ *
+ *    Revision 1.7  2001/09/16 13:20:29  jongfoster
+ *    Rewrite of list library.  Now has seperate header and list_entry
+ *    structures.  Also added a large sprinking of assert()s to the list
+ *    code.
+ *
+ *    Revision 1.6  2001/08/05 16:06:20  jongfoster
+ *    Modifiying "struct map" so that there are now separate header and
+ *    "map_entry" structures.  This means that functions which modify a
+ *    map no longer need to return a pointer to the modified map.
+ *    Also, it no longer reverses the order of the entries (which may be
+ *    important with some advanced template substitutions).
+ *
+ *    Revision 1.5  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.4  2001/06/29 13:30:37  oes
+ *    - Introduced enlist_unique_header()
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.3  2001/06/03 11:03:48  oes
+ *    introduced functions for new list type "map": map(), lookup(),
+ *    free_map(), and extended enlist_unique
+ *
+ *    Revision 1.2  2001/06/01 18:49:17  jongfoster
+ *    Replaced "list_share" with "list" - the tiny memory gain was not
+ *    worth the extra complexity.
+ *
+ *    Revision 1.1  2001/05/31 21:11:53  jongfoster
+ *    - Moved linked list support to new "list.c" file.
+ *      Structure definitions are still in project.h,
+ *      function prototypes are now in "list.h".
+ *    - Added support for "struct list_share", which is identical
+ *      to "struct list" except it saves memory by not duplicating
+ *      the strings.  Obviously, this only works if there is some
+ *      other way of managing the memory used by the strings.
+ *      (These list_share lists are used for lists which last
+ *      for only 1 request, and where all the list entries are
+ *      just coming directly from entries in the actionsfile.)
+ *      Note that you still need to destroy list_share lists
+ *      properly to free the nodes - it's only the strings
+ *      which are shared.
+ *
+ *
+ *********************************************************************/
+\f
+
+#include "project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * struct list
+ *
+ * A linked list class.
+ */
+
+extern void init_list    (struct list *the_list);
+extern void destroy_list (struct list *the_list);
+
+extern jb_err enlist                 (struct list *the_list, const char *str);
+extern jb_err enlist_unique          (struct list *the_list, const char *str, size_t num_significant_chars);
+extern jb_err enlist_unique_header   (struct list *the_list, const char *name, const char *value);
+extern jb_err enlist_first           (struct list *the_list, const char *str);
+extern jb_err list_append_list_unique(struct list *dest,     const struct list *src);
+extern jb_err list_duplicate         (struct list *dest,     const struct list *src);
+
+extern int    list_remove_item(struct list *the_list, const char *str);
+extern int    list_remove_list(struct list *dest,     const struct list *src);
+extern void   list_remove_all (struct list *the_list);
+
+extern int    list_is_empty(const struct list *the_list);
+
+extern char * list_to_text(const struct list *the_list);
+
+
+/*
+ * struct map
+ *
+ * A class which maps names to values.
+ *
+ * Note: You must allocate this through new_map() and free it
+ * through free_map().
+ */
+
+extern struct map * new_map  (void);
+extern void         free_map (struct map * the_map);
+
+extern int          map      (struct map * the_map,
+                              const char * name, int name_needs_copying,
+                              const char * value, int value_needs_copying);
+extern const char * lookup   (const struct map * the_map, const char * name);
+
+
+/* Revision control strings from this header and associated .c file */
+extern const char list_rcs[];
+extern const char list_h_rcs[];
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef LIST_H_INCLUDED */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
index f29d665..1d6a10e 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -1,21 +1,21 @@
-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.47 2002/05/12 21:36:29 jongfoster Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/loadcfg.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
  *
  * Purpose     :  Loads settings from the configuration file into
- *                global variables.  This file contains both the 
+ *                global variables.  This file contains both the
  *                routine to load the configuration and the global
  *                variables it writes to.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -35,6 +35,268 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.1 2001/05/13 21:57:06 administrat
  *
  * Revisions   :
  *    $Log: loadcfg.c,v $
+ *    Revision 1.47  2002/05/12 21:36:29  jongfoster
+ *    Correcting function comments
+ *
+ *    Revision 1.46  2002/04/26 12:55:14  oes
+ *     - New option "user-manual", defaults to our site
+ *       via project.h #define
+ *     - savearg now embeds option names in help links
+ *
+ *    Revision 1.45  2002/04/24 02:11:54  oes
+ *    Jon's multiple AF patch: Allow up to MAX_ACTION_FILES actionsfile options
+ *
+ *    Revision 1.44  2002/04/08 20:37:13  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.43  2002/04/08 20:36:50  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.42  2002/04/05 15:50:15  oes
+ *    fix for invalid HTML proxy_args
+ *
+ *    Revision 1.41  2002/03/31 17:19:00  jongfoster
+ *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
+ *
+ *    Revision 1.40  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.39  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.38  2002/03/24 13:05:48  jongfoster
+ *    Renaming re_filterfile to filterfile
+ *
+ *    Revision 1.37  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.36  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.35  2002/03/07 03:52:44  oes
+ *    Set logging to tty for --no-daemon mode
+ *
+ *    Revision 1.34  2002/03/06 23:14:35  jongfoster
+ *    Trivial cosmetic changes to make function comments easier to find.
+ *
+ *    Revision 1.33  2002/03/05 04:52:42  oes
+ *    Deleted non-errlog debugging code
+ *
+ *    Revision 1.32  2002/03/04 18:24:53  oes
+ *    Re-enabled output of unknown config directive hash
+ *
+ *    Revision 1.31  2002/03/03 15:07:20  oes
+ *    Re-enabled automatic config reloading
+ *
+ *    Revision 1.30  2002/01/22 23:31:43  jongfoster
+ *    Replacing strsav() with string_append()
+ *
+ *    Revision 1.29  2002/01/17 21:02:30  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Renaming free_url to free_url_spec, since it frees a struct url_spec.
+ *
+ *    Revision 1.28  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.27  2001/11/07 00:02:13  steudten
+ *    Add line number in error output for lineparsing for
+ *    actionsfile and configfile.
+ *    Special handling for CLF added.
+ *
+ *    Revision 1.26  2001/11/05 21:41:43  steudten
+ *    Add changes to be a real daemon just for unix os.
+ *    (change cwd to /, detach from controlling tty, set
+ *    process group and session leader to the own process.
+ *    Add DBG() Macro.
+ *    Add some fatal-error log message for failed malloc().
+ *    Add '-d' if compiled with 'configure --with-debug' to
+ *    enable debug output.
+ *
+ *    Revision 1.25  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.24  2001/10/23 21:40:30  jongfoster
+ *    Added support for enable-edit-actions and enable-remote-toggle config
+ *    file options.
+ *
+ *    Revision 1.23  2001/10/07 15:36:00  oes
+ *    Introduced new config option "buffer-limit"
+ *
+ *    Revision 1.22  2001/09/22 16:36:59  jongfoster
+ *    Removing unused parameter fs from read_config_line()
+ *
+ *    Revision 1.21  2001/09/16 17:10:43  jongfoster
+ *    Moving function savearg() here, since it was the only thing left in
+ *    showargs.c.
+ *
+ *    Revision 1.20  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.19  2001/07/15 17:45:16  jongfoster
+ *    Removing some unused #includes
+ *
+ *    Revision 1.18  2001/07/13 14:01:14  oes
+ *     - Removed all #ifdef PCRS
+ *     - Removed vim-settings
+ *
+ *    Revision 1.17  2001/06/29 13:31:03  oes
+ *    - Improved comments
+ *    - Fixed (actionsfile) and sorted hashes
+ *    - Introduced admin_address and proxy-info-url
+ *      as config parameters
+ *    - Renamed config->proxy_args_invocation (which didn't have
+ *      the invocation but the options!) to config->proxy_args
+ *    - Various adaptions
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.16  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.15  2001/06/07 23:13:40  jongfoster
+ *    Merging ACL and forward files into config file.
+ *    Cosmetic: Sorting config file options alphabetically.
+ *    Cosmetic: Adding brief syntax comments to config file options.
+ *
+ *    Revision 1.14  2001/06/07 14:46:25  joergs
+ *    Missing make_path() added for re_filterfile.
+ *
+ *    Revision 1.13  2001/06/05 22:33:54  jongfoster
+ *
+ *    Fixed minor memory leak.
+ *    Also now uses make_path to prepend the pathnames.
+ *
+ *    Revision 1.12  2001/06/05 20:04:09  jongfoster
+ *    Now uses _snprintf() in place of snprintf() under Win32.
+ *
+ *    Revision 1.11  2001/06/04 18:31:58  swa
+ *    files are now prefixed with either `confdir' or `logdir'.
+ *    `make redhat-dist' replaces both entries confdir and logdir
+ *    with redhat values
+ *
+ *    Revision 1.10  2001/06/03 19:11:54  oes
+ *    introduced confdir option
+ *
+ *    Revision 1.9  2001/06/01 20:06:24  jongfoster
+ *    Removed support for "tinygif" option - moved to actions file.
+ *
+ *    Revision 1.8  2001/05/31 21:27:13  jongfoster
+ *    Removed many options from the config file and into the
+ *    "actions" file: add_forwarded, suppress_vanilla_wafer,
+ *    wafer, add_header, user_agent, referer, from
+ *    Also globally replaced "permission" with "action".
+ *
+ *    Revision 1.7  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.6  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.5  2001/05/25 22:34:30  jongfoster
+ *    Hard tabs->Spaces
+ *
+ *    Revision 1.4  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.3  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.2  2001/05/17 23:01:01  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:58  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -49,43 +311,46 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.1 2001/05/13 21:57:06 administrat
 #include <fcntl.h>
 #include <errno.h>
 #include <ctype.h>
+#include <assert.h>
 
 #ifdef _WIN32
 
-# include <sys/timeb.h>
+# ifndef STRICT
+#  define STRICT
+# endif
 # include <windows.h>
-# include <io.h>
-# include <process.h>
-# ifdef TOGGLE
-#  include <time.h>
-# endif /* def TOGGLE */
 
 # include "win32.h"
 # ifndef _WIN_CONSOLE
 #  include "w32log.h"
 # endif /* ndef _WIN_CONSOLE */
 
+/* VC++ has "_snprintf", not "snprintf" */
+#define snprintf _snprintf
+
 #else /* ifndef _WIN32 */
 
+#ifndef __OS2__
 # include <unistd.h>
-# include <sys/time.h>
 # include <sys/wait.h>
+#endif
+# include <sys/time.h>
 # include <sys/stat.h>
 # include <signal.h>
 
 #endif
 
 #include "loadcfg.h"
+#include "list.h"
 #include "jcc.h"
 #include "filters.h"
 #include "loaders.h"
-#include "showargs.h"
-#include "parsers.h"
-#include "killpopup.h"
 #include "miscutil.h"
 #include "errlog.h"
-#include "jbsockets.h"
-#include "gateway.h"
+#include "ssplit.h"
+#include "encode.h"
+#include "urlmatch.h"
+#include "cgi.h"
 
 const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
 
@@ -100,155 +365,171 @@ const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
 #define ijb_isupper(__X) isupper((int)(unsigned char)(__X))
 #define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
 
-static const char VANILLA_WAFER[] =
-   "NOTICE=TO_WHOM_IT_MAY_CONCERN_"
-   "Do_not_send_me_any_copyrighted_information_other_than_the_"
-   "document_that_I_am_requesting_or_any_of_its_necessary_components._"
-   "In_particular_do_not_send_me_any_cookies_that_"
-   "are_subject_to_a_claim_of_copyright_by_anybody._"
-   "Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"
-   "(copyright_or_otherwise)_applying_to_any_cookie._";
-
-#ifdef TOGGLE
+#ifdef FEATURE_TOGGLE
 /* by haroon - indicates if ijb is enabled */
-int g_bToggleIJB        = 1;   /* JunkBusters is enabled by default. */
-#endif
-
-int debug               = 0;
-int multi_threaded      = 1;
-
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
-int tinygif             = 0;
-const char *tinygifurl  = NULL;\r
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
-
-const char *logfile     = NULL;
+int g_bToggleIJB        = 1;   /* Privoxy is enabled by default. */
+#endif /* def FEATURE_TOGGLE */
 
+/* The filename of the configfile */
 const char *configfile  = NULL;
 
-const char *blockfile   = NULL;
-const char *cookiefile  = NULL;
-const char *forwardfile = NULL;
-
-#ifdef ACL_FILES
-const char *aclfile     = NULL;
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-const char *imagefile   = NULL;
-#endif /* def USE_IMAGE_LIST */
+/*
+ * CGI functions will later need access to the invocation args,
+ * so we will make argc and argv global.
+ */
+int Argc = 0;
+const char **Argv = NULL;
 
-#ifdef KILLPOPUPS
-const char *popupfile   = NULL;
-int kill_all_popups     = 0;     /* Not recommended really ... */
-#endif /* def KILLPOPUPS */
+static struct file_list *current_configfile = NULL;
 
-#ifdef PCRS
-const char *re_filterfile = NULL;
-int re_filter_all       = 0;
-#endif /* def PCRS */
 
-#ifdef TRUST_FILES
-const char *trustfile   = NULL;
-#endif /* def TRUST_FILES */
+/*
+ * This takes the "cryptic" hash of each keyword and aliases them to
+ * something a little more readable.  This also makes changing the
+ * hash values easier if they should change or the hash algorthm changes.
+ * Use the included "hash" program to find out what the hash will be
+ * for any string supplied on the command line.  (Or just put it in the
+ * config file and read the number from the error message in the log).
+ *
+ * Please keep this list sorted alphabetically (but with the Windows
+ * console and GUI specific options last).
+ */
 
-#ifdef JAR_FILES
-const char *jarfile     = NULL;
-FILE *jar = NULL;
-#endif /* def JAR_FILES */
+#define hash_actions_file              1196306641ul /* "actionsfile" */
+#define hash_admin_address             4112573064ul /* "admin-address" */
+#define hash_buffer_limit              1881726070ul /* "buffer-limit */
+#define hash_confdir                      1978389ul /* "confdir" */
+#define hash_debug                          78263ul /* "debug" */
+#define hash_deny_access               1227333715ul /* "deny-access" */
+#define hash_enable_edit_actions       2517097536ul /* "enable-edit-actions" */
+#define hash_enable_remote_toggle      2979744683ul /* "enable-remote-toggle" */
+#define hash_filterfile                 250887266ul /* "filterfile" */
+#define hash_forward                      2029845ul /* "forward" */
+#define hash_forward_socks4            3963965521ul /* "forward-socks4" */
+#define hash_forward_socks4a           2639958518ul /* "forward-socks4a" */
+#define hash_jarfile                      2046641ul /* "jarfile" */
+#define hash_listen_address            1255650842ul /* "listen-address" */
+#define hash_logdir                        422889ul /* "logdir" */
+#define hash_logfile                      2114766ul /* "logfile" */
+#define hash_permit_access             3587953268ul /* "permit-access" */
+#define hash_proxy_info_url            3903079059ul /* "proxy-info-url" */
+#define hash_single_threaded           4250084780ul /* "single-threaded" */
+#define hash_suppress_blocklists       1948693308ul /* "suppress-blocklists" */
+#define hash_toggle                        447966ul /* "toggle" */
+#define hash_trust_info_url             430331967ul /* "trust-info-url" */
+#define hash_trustfile                   56494766ul /* "trustfile" */
+#define hash_usermanual                1416668518ul /* "user-manual" */
+#define hash_activity_animation        1817904738ul /* "activity-animation" */
+#define hash_close_button_minimizes    3651284693ul /* "close-button-minimizes" */
+#define hash_hide_console              2048809870ul /* "hide-console" */
+#define hash_log_buffer_size           2918070425ul /* "log-buffer-size" */
+#define hash_log_font_name             2866730124ul /* "log-font-name" */
+#define hash_log_font_size             2866731014ul /* "log-font-size" */
+#define hash_log_highlight_messages    4032101240ul /* "log-highlight-messages" */
+#define hash_log_max_lines             2868344173ul /* "log-max-lines" */
+#define hash_log_messages              2291744899ul /* "log-messages" */
+#define hash_show_on_task_bar           215410365ul /* "show-on-task-bar" */
+
+
+static void savearg(char *command, char *argument, struct configuration_spec * config);
 
-const char *referrer    = NULL;
-const char *uagent      = NULL;
-const char *from        = NULL;
+/*********************************************************************
+ *
+ * Function    :  unload_configfile
+ *
+ * Description :  Free the config structure and all components.
+ *
+ * Parameters  :
+ *          1  :  data: struct configuration_spec to unload
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void unload_configfile (void * data)
+{
+   struct configuration_spec * config = (struct configuration_spec *)data;
+   struct forward_spec *cur_fwd = config->forward;
+#ifdef FEATURE_ACL
+   struct access_control_list *cur_acl = config->acl;
+   int i;
 
-#ifndef SPLIT_PROXY_ARGS
-const char *suppress_message = NULL;
-#endif /* ndef SPLIT_PROXY_ARGS */
+   while (cur_acl != NULL)
+   {
+      struct access_control_list * next_acl = cur_acl->next;
+      free(cur_acl);
+      cur_acl = next_acl;
+   }
+   config->acl = NULL;
+#endif /* def FEATURE_ACL */
 
-int suppress_vanilla_wafer = 0;
-int add_forwarded       = 0;
+   while (cur_fwd != NULL)
+   {
+      struct forward_spec * next_fwd = cur_fwd->next;
+      free_url_spec(cur_fwd->url);
 
-struct list wafer_list[1];
-struct list xtra_list[1];
+      freez(cur_fwd->gateway_host);
+      freez(cur_fwd->forward_host);
+      free(cur_fwd);
+      cur_fwd = next_fwd;
+   }
+   config->forward = NULL;
 
-#ifdef TRUST_FILES
-struct list trust_info[1];
-struct url_spec *trust_list[64];
-#endif /* def TRUST_FILES */
+#ifdef FEATURE_COOKIE_JAR
+   if ( NULL != config->jar )
+   {
+      fclose( config->jar );
+      config->jar = NULL;
+   }
+#endif /* def FEATURE_COOKIE_JAR */
 
-/*
- * Port and IP to bind to.
- * Defaults to HADDR_DEFAULT:HADDR_PORT == 127.0.0.1:8000
- */
-const char *haddr = NULL;
-int         hport = 0;
+   freez(config->confdir);
+   freez(config->logdir);
 
-#ifndef SPLIT_PROXY_ARGS
-int suppress_blocklists = 0;  /* suppress listing sblock and simage */
-#endif /* ndef SPLIT_PROXY_ARGS */
+   freez(config->haddr);
+   freez(config->logfile);
 
-struct proxy_args proxy_args[1];
+   for (i = 0; i < MAX_ACTION_FILES; i++)
+   {
+      freez(config->actions_file_short[i]);
+      freez(config->actions_file[i]);
+   }
 
-int configret = 0;
-int config_changed = 0;
+   freez(config->admin_address);
+   freez(config->proxy_info_url);
+   freez(config->proxy_args);
+   freez(config->usermanual);
 
+#ifdef FEATURE_COOKIE_JAR
+   freez(config->jarfile);
+#endif /* def FEATURE_COOKIE_JAR */
 
-/*
- * The load_config function is now going to call `init_proxy_args',
- * so it will need argc and argv.  Since load_config will also be
- * a signal handler, we need to have these globally available.
- */
-int Argc = 0;
-const char **Argv = NULL;
+   freez(config->re_filterfile);
 
+}
 
-/*
- * This takes the "cryptic" hash of each keyword and aliases them to
- * something a little more readable.  This also makes changing the
- * hash values easier if they should change or the hash algorthm changes.
- * Use the included "hash" program to find out what the hash will be
- * for any string supplied on the command line.
- */
 
-#define hash_trustfile                 56494766ul
-#define hash_trust_info_url            449869467ul
-#define hash_debug                     78263ul
-#define hash_tinygif                   2227702ul
-#define hash_add_forwarded_header      3191044770ul
-#define hash_single_threaded           4250084780ul
-#define hash_suppress_vanilla_wafer    3121233547ul
-#define hash_wafer                     89669ul
-#define hash_add_header                237434619ul
-#define hash_cookiefile                247469766ul
-#define hash_logfile                   2114766ul
-#define hash_blockfile                 48845391ul
-#define hash_imagefile                 51447891ul
-#define hash_jarfile                   2046641ul
-#define hash_listen_address            1255650842ul
-#define hash_forwardfile               1268669141ul
-#define hash_aclfile                   1908516ul
-#define hash_popupfile                 54623516ul
-#define hash_kill_all_popups           2311539906ul
-#define hash_re_filterfile             3877522444ul
-#define hash_re_filter_all             3877521376ul
-#define hash_user_agent                283326691ul
-#define hash_referrer                  10883969ul
-#define hash_referer                   2176719ul
-#define hash_from                      16264ul
-#define hash_hide_console              2048809870ul
-#define hash_include_stats             2174146548ul
-#define hash_suppress_blocklists       1948693308ul
-#define hash_toggle                    447966ul
-
-#define hash_activity_animation        1817904738ul
-#define hash_log_messages              2291744899ul
-#define hash_log_highlight_messages    4032101240ul
-#define hash_log_buffer_size           2918070425ul
-#define hash_log_max_lines             2868344173ul
-#define hash_log_font_name             2866730124ul
-#define hash_log_font_size             2866731014ul
-#define hash_show_on_task_bar          215410365ul
-#define hash_close_button_minimizes    3651284693ul
+#ifdef FEATURE_GRACEFUL_TERMINATION
+/*********************************************************************
+ *
+ * Function    :  unload_current_config_file
+ *
+ * Description :  Unloads current config file - reset to state at
+ *                beginning of program.
+ *
+ * Parameters  :  None
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void unload_current_config_file(void)
+{
+   if (current_configfile)
+   {
+      current_configfile->unloader = unload_configfile;
+      current_configfile = NULL;
+   }
+}
+#endif
 
 
 /*********************************************************************
@@ -257,608 +538,1053 @@ const char **Argv = NULL;
  *
  * Description :  Load the config file and all parameters.
  *
- * Parameters  :
- *          1  :  signum : this can be the signal SIGHUP or 0 (if from main).
- *                In any case, we just ignore this and reload the config file.
+ * Parameters  :  None
  *
- * Returns     :  configret : 0 => Ok, everything else is an error.
- *                Note: we use configret since a signal handler cannot
- *                return a value, and this function does double duty.
- *                Ie. Is is called from main and from signal( SIGHUP );
+ * Returns     :  The configuration_spec, or NULL on error.
  *
  *********************************************************************/
-void load_config( int signum )
+struct configuration_spec * load_config(void)
 {
-   char buf[BUFSIZ];
+   char buf[BUFFER_SIZE];
    char *p, *q;
    FILE *configfp = NULL;
+   struct configuration_spec * config = NULL;
+   struct client_state * fake_csp;
+   struct file_list *fs;
+   unsigned long linenum = 0;
+   int i;
 
-   configret = 0;
-   config_changed = 1;
+   if ( !check_file_changed(current_configfile, configfile, &fs))
+   {
+      /* No need to load */
+      return ((struct configuration_spec *)current_configfile->f);
+   }
+   if (!fs)
+   {
+      log_error(LOG_LEVEL_FATAL, "can't check configuration file '%s':  %E",
+                configfile);
+   }
 
    log_error(LOG_LEVEL_INFO, "loading configuration file '%s':", configfile);
 
-   init_proxy_args(Argc, Argv);
+#ifdef FEATURE_TOGGLE
+   g_bToggleIJB      = 1;
+#endif /* def FEATURE_TOGGLE */
 
+   fs->f = config = (struct configuration_spec *)zalloc(sizeof(*config));
 
-   /* (Waste of memory [not quite a "leak"] here.  The 
-    * last blockfile/popupfile/... etc will not be 
-    * unloaded until we load a new one.  If the 
-    * block/popup/... feature has been disabled in 
-    * the new config file, then we're wasting some 
-    * memory we could otherwise reclaim.
-    */
+   if (config==NULL)
+   {
+      freez(fs->filename);
+      freez(fs);
+      log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
+      /* Never get here - LOG_LEVEL_FATAL causes program exit */
+   }
 
-   /* Disable all loaders. */
-   remove_all_loaders();
+   /*
+    * This is backwards from how it's usually done.
+    * Following the usual pattern, "fs" would be stored in a member
+    * variable in "csp", and then we'd access "config" from "fs->f",
+    * using a cast.  However, "config" is used so often that a
+    * cast each time would be very ugly, and the extra indirection
+    * would waste CPU cycles.  Therefore we store "config" in
+    * "csp->config", and "fs" in "csp->config->config_file_list".
+    */
+   config->config_file_list = fs;
 
    /*
-    * Reset to as close to startup state as we can.
-    * But leave changing the logfile until after we're done loading.
+    * Set to defaults
     */
+   config->multi_threaded    = 1;
+   config->hport             = HADDR_PORT;
+   config->buffer_limit      = 4096 * 1024;
+   config->usermanual        = strdup(USER_MANUAL_URL);
+   config->proxy_args        = strdup("");
 
-   #ifdef JAR_FILES
-   if ( NULL != jar )
+   if ((configfp = fopen(configfile, "r")) == NULL)
    {
-      fclose( jar );
-      jar = NULL;
+      log_error(LOG_LEVEL_FATAL, "can't open configuration file '%s':  %E",
+              configfile);
+      /* Never get here - LOG_LEVEL_FATAL causes program exit */
    }
-   #endif /* def JAR_FILES */
 
-   debug             = 0;
-   multi_threaded    = 1;
+   while (read_config_line(buf, sizeof(buf), configfp, &linenum) != NULL)
+   {
+      char cmd[BUFFER_SIZE];
+      char arg[BUFFER_SIZE];
+      char tmp[BUFFER_SIZE];
+#ifdef FEATURE_ACL
+      struct access_control_list *cur_acl;
+#endif /* def FEATURE_ACL */
+      struct forward_spec *cur_fwd;
+      int vec_count;
+      char *vec[3];
+
+      strcpy(tmp, buf);
+
+      /* Copy command (i.e. up to space or tab) into cmd */
+      p = buf;
+      q = cmd;
+      while (*p && (*p != ' ') && (*p != '\t'))
+      {
+         *q++ = *p++;
+      }
+      *q = '\0';
 
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
-   tinygif           = 0;\r
-   freez((char *)tinygifurl);
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
+      /* Skip over the whitespace in buf */
+      while (*p && ((*p == ' ') || (*p == '\t')))
+      {
+         p++;
+      }
 
-   suppress_vanilla_wafer = 0;
-   add_forwarded     = 0;
-   hport             = HADDR_PORT;
+      /* Copy the argument into arg */
+      strcpy(arg, p);
 
-#ifdef _WIN_CONSOLE
-   hideConsole       = 0;
-#endif /*def _WIN_CONSOLE*/
+      /* Should never happen, but check this anyway */
+      if (*cmd == '\0')
+      {
+         continue;
+      }
 
-#ifdef PCRS
-   re_filter_all     = 0;
-#endif /* def PCRS */
+      /* Make sure the command field is lower case */
+      for (p=cmd; *p; p++)
+      {
+         if (ijb_isupper(*p))
+         {
+            *p = ijb_tolower(*p);
+         }
+      }
 
-#ifdef KILLPOPUPS
-   kill_all_popups   = 0;
-#endif /* def KILLPOPUPS */
+      /* Save the argument for show-proxy-args */
+      savearg(cmd, arg, config);
 
-#ifdef TOGGLE
-   g_bToggleIJB      = 1;
-#endif
 
-#ifdef STATISTICS
-   urls_read         = 0;
-   urls_rejected     = 0;
-#endif /* def STATISTICS */
+      switch( hash_string( cmd ) )
+      {
+/* *************************************************************************
+ * actionsfile actions-file-name
+ * In confdir by default
+ * *************************************************************************/
+         case hash_actions_file :
+            i = 0;
+            while ((i < MAX_ACTION_FILES) && (NULL != config->actions_file[i]))
+            {
+               i++;
+            }
 
-#ifndef SPLIT_PROXY_ARGS
-   suppress_blocklists = 0;
-#endif /* ndef SPLIT_PROXY_ARGS */
+            if (i >= MAX_ACTION_FILES)
+            {
+               log_error(LOG_LEVEL_FATAL, "Too many 'actionsfile' directives in config file - limit is %d.\n"
+                  "(You can increase this limit by changing MAX_ACTION_FILES in project.h and recompiling).",
+                  MAX_ACTION_FILES);
+            }
+            config->actions_file_short[i] = strdup(arg);
+            p = malloc(strlen(arg) + sizeof(".action"));
+            if (p == NULL)
+            {
+               log_error(LOG_LEVEL_FATAL, "Out of memory");
+            }
+            strcpy(p, arg);
+            strcat(p, ".action");
+            config->actions_file[i] = make_path(config->confdir, p);
+            free(p);
+            continue;
 
-   freez((char *)from);
-   freez((char *)haddr);
-   freez((char *)uagent);
-   freez((char *)referrer);
-   freez((char *)logfile);
+/* *************************************************************************
+ * admin-address email-address
+ * *************************************************************************/
+         case hash_admin_address :
+            freez(config->admin_address);
+            config->admin_address = strdup(arg);
+            continue;
 
+/* *************************************************************************
+ * buffer-limit n
+ * *************************************************************************/
+         case hash_buffer_limit :
+            config->buffer_limit = (size_t) 1024 * atoi(arg);
+            continue;
 
-   freez((char *)blockfile);
-   freez((char *)cookiefile);
-   freez((char *)forwardfile);
+/* *************************************************************************
+ * confdir directory-name
+ * *************************************************************************/
+         case hash_confdir :
+            freez(config->confdir);
+            config->confdir = make_path( NULL, arg);
+            continue;
 
-#ifdef ACL_FILES
-   freez((char *)aclfile);
-#endif /* def ACL_FILES */
+/* *************************************************************************
+ * debug n
+ * Specifies debug level, multiple values are ORed together.
+ * *************************************************************************/
+         case hash_debug :
+            config->debug |= atoi(arg);
+            continue;
 
-#ifdef USE_IMAGE_LIST
-   freez((char *)imagefile);
-#endif /* def USE_IMAGE_LIST */
+/* *************************************************************************
+ * deny-access source-ip[/significant-bits] [dest-ip[/significant-bits]]
+ * *************************************************************************/
+#ifdef FEATURE_ACL
+         case hash_deny_access:
+            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
 
-#ifdef JAR_FILES
-   freez((char *)jarfile);
-#endif /* def JAR_FILES */
+            if ((vec_count != 1) && (vec_count != 2))
+            {
+               log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
+                     "deny-access directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Wrong number of parameters for "
+                  "deny-access directive in configuration file.<br><br>\n");
+               continue;
+            }
 
-#ifdef KILLPOPUPS
-   freez((char *)popupfile);
-#endif /* def KILLPOPUPS */
+            /* allocate a new node */
+            cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
 
-#ifndef SPLIT_PROXY_ARGS
-   freez((char *)suppress_message);
-#endif /* ndef SPLIT_PROXY_ARGS */
+            if (cur_acl == NULL)
+            {
+               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
+               /* Never get here - LOG_LEVEL_FATAL causes program exit */
+               continue;
+            }
+            cur_acl->action = ACL_DENY;
 
-#ifdef TRUST_FILES
-   freez((char *)trustfile);
-#endif /* def TRUST_FILES */
+            if (acl_addr(vec[0], cur_acl->src) < 0)
+            {
+               log_error(LOG_LEVEL_ERROR, "Invalid source IP for deny-access "
+                     "directive in configuration file: \"%s\"", vec[0]);
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Invalid source IP for deny-access directive"
+                  " in configuration file: \"");
+               string_append(&config->proxy_args,
+                  vec[0]);
+               string_append(&config->proxy_args,
+                  "\"<br><br>\n");
+               freez(cur_acl);
+               continue;
+            }
+            if (vec_count == 2)
+            {
+               if (acl_addr(vec[1], cur_acl->dst) < 0)
+               {
+                  log_error(LOG_LEVEL_ERROR, "Invalid destination IP for deny-access "
+                        "directive in configuration file: \"%s\"", vec[0]);
+                  string_append(&config->proxy_args,
+                     "<br>\nWARNING: Invalid destination IP for deny-access directive"
+                     " in configuration file: \"");
+                  string_append(&config->proxy_args,
+                     vec[0]);
+                  string_append(&config->proxy_args,
+                     "\"<br><br>\n");
+                  freez(cur_acl);
+                  continue;
+               }
+            }
 
-#ifdef PCRS
-   freez((char *)re_filterfile);
-#endif /* def PCRS */
+            /*
+             * Add it to the list.  Note we reverse the list to get the
+             * behaviour the user expects.  With both the ACL and
+             * actions file, the last match wins.  However, the internal
+             * implementations are different:  The actions file is stored
+             * in the same order as the file, and scanned completely.
+             * With the ACL, we reverse the order as we load it, then
+             * when we scan it we stop as soon as we get a match.
+             */
+            cur_acl->next  = config->acl;
+            config->acl = cur_acl;
 
-   if (NULL != configfile)
-   {
-      if ((configfp = fopen(configfile, "r")) == NULL)
-      {
-         log_error(LOG_LEVEL_ERROR, "can't open configuration file '%s':  %E",
-                 configfile);
-         configret = 1;
-         return;
-      }
-   }
+            continue;
+#endif /* def FEATURE_ACL */
+
+/* *************************************************************************
+ * enable-edit-actions 0|1
+ * *************************************************************************/
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+         case hash_enable_edit_actions:
+            if ((*arg != '\0') && (0 != atoi(arg)))
+            {
+               config->feature_flags |= RUNTIME_FEATURE_CGI_EDIT_ACTIONS;
+            }
+            else
+            {
+               config->feature_flags &= ~RUNTIME_FEATURE_CGI_EDIT_ACTIONS;
+            }
+            continue;
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
+
+/* *************************************************************************
+ * enable-remote-toggle 0|1
+ * *************************************************************************/
+#ifdef FEATURE_CGI_EDIT_ACTIONS
+         case hash_enable_remote_toggle:
+            if ((*arg != '\0') && (0 != atoi(arg)))
+            {
+               config->feature_flags |= RUNTIME_FEATURE_CGI_TOGGLE;
+            }
+            else
+            {
+               config->feature_flags &= ~RUNTIME_FEATURE_CGI_TOGGLE;
+            }
+            continue;
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
 
-   if (NULL != configfp)
-   {
-      memset (buf, 'j', sizeof(buf));
-      while (read_config_line(buf, sizeof(buf), configfp, NULL) != NULL)
-      {
-         char cmd[BUFSIZ];
-         char arg[BUFSIZ];
-         char tmp[BUFSIZ];
+/* *************************************************************************
+ * forward url-pattern (.|http-proxy-host[:port])
+ * *************************************************************************/
+         case hash_forward:
+            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
 
-         strcpy(tmp, buf);
+            if (vec_count != 2)
+            {
+               log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for forward "
+                     "directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Wrong number of parameters for "
+                  "forward directive in configuration file.");
+               continue;
+            }
 
-         /* Copy command (i.e. up to space or tab) into cmd */
-         p = buf;
-         q = cmd;
-         while (*p && (*p != ' ') && (*p != '\t'))
-         {
-            *q++ = *p++;
-         }
-         *q = '\0';
+            /* allocate a new node */
+            cur_fwd = zalloc(sizeof(*cur_fwd));
+            if (cur_fwd == NULL)
+            {
+               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
+               /* Never get here - LOG_LEVEL_FATAL causes program exit */
+               continue;
+            }
 
-         /* Skip over the whitespace in buf */
-         while (*p && ((*p == ' ') || (*p == '\t')))
-         {
-            p++;
-         }
+            cur_fwd->type = SOCKS_NONE;
 
-         /* Copy the argument into arg */
-         strcpy(arg, p);
+            /* Save the URL pattern */
+            if (create_url_spec(cur_fwd->url, vec[0]))
+            {
+               log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward "
+                     "directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Bad URL specifier for "
+                  "forward directive in configuration file.");
+               continue;
+            }
 
-         /* Should never happen, but check this anyway */
-         if (*cmd == '\0')
-         {
-            continue;
-         }
+            /* Parse the parent HTTP proxy host:port */
+            p = vec[1];
 
-         /* Make sure the command field is lower case */
-         for (p=cmd; *p; p++)
-         {
-            if (ijb_isupper(*p))
+            if (strcmp(p, ".") != 0)
             {
-               *p = ijb_tolower(*p);
-            }
-         }
+               cur_fwd->forward_host = strdup(p);
 
-         /* Save the argument for show-proxy-args */
-         savearg(cmd, arg);
+               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
+               {
+                  *p++ = '\0';
+                  cur_fwd->forward_port = atoi(p);
+               }
 
+               if (cur_fwd->forward_port <= 0)
+               {
+                  cur_fwd->forward_port = 8000;
+               }
+            }
 
-         switch( hash_string( cmd ) )
-         {
-#ifdef TRUST_FILES
-            case hash_trustfile :\r
-               freez((char *)trustfile);
-               trustfile = strdup(arg);
-               continue;
+            /* Add to list. */
+            cur_fwd->next = config->forward;
+            config->forward = cur_fwd;
 
-            case hash_trust_info_url :
-               enlist(trust_info, arg);
-               continue;
-#endif /* def TRUST_FILES */
+            continue;
 
-            case hash_debug :
-               debug |= atoi(arg);
-               continue;
+/* *************************************************************************
+ * forward-socks4 url-pattern socks-proxy[:port] (.|http-proxy[:port])
+ * *************************************************************************/
+         case hash_forward_socks4:
+            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
 
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
-            case hash_tinygif :\r
-               freez((char *)tinygifurl);
-               tinygif = atoi(arg);
-               if(3 == tinygif)\r
-               {\r
-                  p = arg;\r
-                  while((*p >= '0') && (*p <= '9'))\r
-                  {\r
-                     p++;\r
-                  }\r
-                  while((*p == ' ') || (*p == '\t'))\r
-                  {\r
-                     p++;\r
-                  }\r
-                  if (*p)\r
-                  {\r
-                     q = malloc(strlen(p) + 5);\r
-                     if (q)\r
-                     {\r
-                        strcpy(q, p);\r
-                        strcat(q, "\r\n\r\n");\r
-                        tinygifurl = q;\r
-                     }\r
-                  }\r
-               }\r
-               if ((tinygif != 1) && \r
-                   (tinygif != 2) && \r
-                   ((tinygif != 3) || (tinygifurl==NULL)) )\r
-               {\r
-                  log_error(LOG_LEVEL_ERROR, "tinygif setting invalid.");\r
-               }\r
+            if (vec_count != 3)
+            {
+               log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
+                     "forward-socks4 directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Wrong number of parameters for "
+                  "forward-socks4 directive in configuration file.");
                continue;
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
+            }
 
-            case hash_add_forwarded_header :
-               add_forwarded = 1;
+            /* allocate a new node */
+            cur_fwd = zalloc(sizeof(*cur_fwd));
+            if (cur_fwd == NULL)
+            {
+               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
+               /* Never get here - LOG_LEVEL_FATAL causes program exit */
                continue;
+            }
 
-            case hash_single_threaded :
-               multi_threaded = 0;
-               continue;
+            cur_fwd->type = SOCKS_4;
 
-            case hash_suppress_vanilla_wafer :
-               suppress_vanilla_wafer = 1;
+            /* Save the URL pattern */
+            if (create_url_spec(cur_fwd->url, vec[0]))
+            {
+               log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4 "
+                     "directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Bad URL specifier for "
+                  "forward-socks4 directive in configuration file.");
                continue;
+            }
 
-            case hash_wafer :
-               enlist(wafer_list, arg);
-               continue;
+            /* Parse the SOCKS proxy host[:port] */
+            p = vec[1];
 
-            case hash_add_header :
-               enlist(xtra_list, arg);
-               continue;
+            if (strcmp(p, ".") != 0)
+            {
+               cur_fwd->gateway_host = strdup(p);
 
-            case hash_cookiefile :\r
-               freez((char *)cookiefile);
-               cookiefile = strdup(arg);
-               continue;
+               if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
+               {
+                  *p++ = '\0';
+                  cur_fwd->gateway_port = atoi(p);
+               }
+               if (cur_fwd->gateway_port <= 0)
+               {
+                  cur_fwd->gateway_port = 1080;
+               }
+            }
 
-            case hash_logfile :\r
-               freez((char *)logfile);
-               logfile = strdup(arg);
-               continue;
+            /* Parse the parent HTTP proxy host[:port] */
+            p = vec[2];
 
-            case hash_blockfile :\r
-               freez((char *)blockfile);
-               blockfile = strdup(arg);
-               continue;
+            if (strcmp(p, ".") != 0)
+            {
+               cur_fwd->forward_host = strdup(p);
 
-#ifdef USE_IMAGE_LIST
-            case hash_imagefile :\r
-               freez((char *)imagefile);
-               imagefile = strdup(arg);
-               continue;
-#endif /* def USE_IMAGE_LIST */
+               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
+               {
+                  *p++ = '\0';
+                  cur_fwd->forward_port = atoi(p);
+               }
 
-#ifdef JAR_FILES
-            case hash_jarfile :\r
-               freez((char *)jarfile);
-               jarfile = strdup(arg);
-               continue;
-#endif /* def JAR_FILES */
+               if (cur_fwd->forward_port <= 0)
+               {
+                  cur_fwd->forward_port = 8000;
+               }
+            }
 
-            case hash_listen_address :\r
-               freez((char *)haddr);
-               haddr = strdup(arg);
-               continue;
+            /* Add to list. */
+            cur_fwd->next = config->forward;
+            config->forward = cur_fwd;
 
-            case hash_forwardfile :\r
-               freez((char *)forwardfile);
-               forwardfile = strdup(arg);
-               continue;
+            continue;
 
-#ifdef ACL_FILES
-            case hash_aclfile :\r
-               freez((char *)aclfile);
-               aclfile = strdup(arg);
-               continue;
-#endif /* def ACL_FILES */
+/* *************************************************************************
+ * forward-socks4a url-pattern socks-proxy[:port] (.|http-proxy[:port])
+ * *************************************************************************/
+         case hash_forward_socks4a:
+            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
 
-#ifdef KILLPOPUPS
-            case hash_popupfile :\r
-               freez((char *)popupfile);
-               popupfile = strdup(arg);
+            if (vec_count != 3)
+            {
+               log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
+                     "forward-socks4a directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Wrong number of parameters for "
+                  "forward-socks4a directive in configuration file.");
                continue;
+            }
 
-            case hash_kill_all_popups :
-               kill_all_popups = 1;
+            /* allocate a new node */
+            cur_fwd = zalloc(sizeof(*cur_fwd));
+            if (cur_fwd == NULL)
+            {
+               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
+               /* Never get here - LOG_LEVEL_FATAL causes program exit */
                continue;
-#endif /* def KILLPOPUPS */
+            }
 
-#ifdef PCRS
-            case hash_re_filterfile :\r
-               freez((char *)re_filterfile);
-               re_filterfile = strdup(arg);
-               continue;
+            cur_fwd->type = SOCKS_4A;
 
-            case hash_re_filter_all :
-               re_filter_all = 1;
-               log_error(LOG_LEVEL_REF, "re_filter policy is %s.",
-                          re_filter_all ? "RADICAL" : "SEMI-SMART");
+            /* Save the URL pattern */
+            if (create_url_spec(cur_fwd->url, vec[0]))
+            {
+               log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4a "
+                     "directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Bad URL specifier for "
+                  "forward-socks4a directive in configuration file.");
                continue;
-#endif /* def PCRS */
+            }
 
-            case hash_user_agent :\r
-               freez((char *)uagent);
-               uagent = strdup(arg);
-               continue;
+            /* Parse the SOCKS proxy host[:port] */
+            p = vec[1];
 
-               /*
-                * Offer choice of correct spelling according to dictionary,
-                * or the misspelling used in the HTTP spec.
-                */
-            case hash_referrer :
-            case hash_referer :\r
-               freez((char *)referrer);
-               referrer = strdup(arg);
-               continue;
+            cur_fwd->gateway_host = strdup(p);
 
-            case hash_from :\r
-               freez((char *)from);
-               from = strdup(arg);
-               continue;
+            if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
+            {
+               *p++ = '\0';
+               cur_fwd->gateway_port = atoi(p);
+            }
+            if (cur_fwd->gateway_port <= 0)
+            {
+               cur_fwd->gateway_port = 1080;
+            }
 
-#ifdef _WIN_CONSOLE
-            case hash_hide_console :
-               hideConsole = 1;
-               continue;
-#endif /*def _WIN_CONSOLE*/
+            /* Parse the parent HTTP proxy host[:port] */
+            p = vec[2];
+
+            if (strcmp(p, ".") != 0)
+            {
+               cur_fwd->forward_host = strdup(p);
 
-#ifndef SPLIT_PROXY_ARGS
-            case hash_suppress_blocklists :
-               if (arg[0] != '\0')
+               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
                {
-                  suppress_message = strdup(arg);
+                  *p++ = '\0';
+                  cur_fwd->forward_port = atoi(p);
                }
-               else
+
+               if (cur_fwd->forward_port <= 0)
                {
-                  /* There will be NO reference in proxy-args. */
-                  suppress_message = NULL;
+                  cur_fwd->forward_port = 8000;
                }
+            }
 
-               suppress_blocklists = 1;
-               continue;
-#endif /* ndef SPLIT_PROXY_ARGS */
+            /* Add to list. */
+            cur_fwd->next = config->forward;
+            config->forward = cur_fwd;
 
-#ifdef TOGGLE
-            case hash_toggle :
-               g_bToggleIJB = atoi(arg);
-               continue;
-#endif /* def TOGGLE */
+            continue;
 
-#if defined(_WIN32) && ! defined(_WIN_CONSOLE)
-            case hash_activity_animation :
-               g_bShowActivityAnimation = atoi(arg);
-               continue;
+/* *************************************************************************
+ * jarfile jar-file-name
+ * In logdir by default
+ * *************************************************************************/
+#ifdef FEATURE_COOKIE_JAR
+         case hash_jarfile :
+            freez(config->jarfile);
+            config->jarfile = make_path(config->logdir, arg);
+            continue;
+#endif /* def FEATURE_COOKIE_JAR */
+
+/* *************************************************************************
+ * listen-address [ip][:port]
+ * *************************************************************************/
+         case hash_listen_address :
+            freez(config->haddr);
+            config->haddr = strdup(arg);
+            continue;
 
-            case hash_log_messages :
-               g_bLogMessages = atoi(arg);
-               continue;
+/* *************************************************************************
+ * logdir directory-name
+ * *************************************************************************/
+         case hash_logdir :
+            freez(config->logdir);
+            config->logdir = make_path(NULL, arg);
+            continue;
 
-            case hash_log_highlight_messages :
-               g_bHighlightMessages = atoi(arg);
-               continue;
+/* *************************************************************************
+ * logfile log-file-name
+ * In logdir by default
+ * *************************************************************************/
+         case hash_logfile :
+            freez(config->logfile);
+            config->logfile = no_daemon ? NULL : make_path(config->logdir, arg);
+            continue;
 
-            case hash_log_buffer_size :
-               g_bLimitBufferSize = atoi(arg);
-               continue;
+/* *************************************************************************
+ * permit-access source-ip[/significant-bits] [dest-ip[/significant-bits]]
+ * *************************************************************************/
+#ifdef FEATURE_ACL
+         case hash_permit_access:
+            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
 
-            case hash_log_max_lines :
-               g_nMaxBufferLines = atoi(arg);
-               continue;
+            if ((vec_count != 1) && (vec_count != 2))
+            {
+               log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
+                     "permit-access directive in configuration file.");
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Wrong number of parameters for "
+                  "permit-access directive in configuration file.<br><br>\n");
 
-            case hash_log_font_name :
-               strcpy( g_szFontFaceName, arg );
                continue;
+            }
 
-            case hash_log_font_size :
-               g_nFontSize = atoi(arg);
-               continue;
+            /* allocate a new node */
+            cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
 
-            case hash_show_on_task_bar :
-               g_bShowOnTaskBar = atoi(arg);
+            if (cur_acl == NULL)
+            {
+               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
+               /* Never get here - LOG_LEVEL_FATAL causes program exit */
                continue;
+            }
+            cur_acl->action = ACL_PERMIT;
 
-            case hash_close_button_minimizes :
-               g_bCloseHidesWindow = atoi(arg);
+            if (acl_addr(vec[0], cur_acl->src) < 0)
+            {
+               log_error(LOG_LEVEL_ERROR, "Invalid source IP for permit-access "
+                     "directive in configuration file: \"%s\"", vec[0]);
+               string_append(&config->proxy_args,
+                  "<br>\nWARNING: Invalid source IP for permit-access directive"
+                  " in configuration file: \"");
+               string_append(&config->proxy_args,
+                  vec[0]);
+               string_append(&config->proxy_args,
+                  "\"<br><br>\n");
+               freez(cur_acl);
                continue;
+            }
+            if (vec_count == 2)
+            {
+               if (acl_addr(vec[1], cur_acl->dst) < 0)
+               {
+                  log_error(LOG_LEVEL_ERROR, "Invalid destination IP for "
+                        "permit-access directive in configuration file: \"%s\"",
+                        vec[0]);
+                  string_append(&config->proxy_args,
+                     "<br>\nWARNING: Invalid destination IP for permit-access directive"
+                     " in configuration file: \"");
+                  string_append(&config->proxy_args,
+                     vec[0]);
+                  string_append(&config->proxy_args,
+                     "\"<br><br>\n");
+                  freez(cur_acl);
+                  continue;
+               }
+            }
+
+            /*
+             * Add it to the list.  Note we reverse the list to get the
+             * behaviour the user expects.  With both the ACL and
+             * actions file, the last match wins.  However, the internal
+             * implementations are different:  The actions file is stored
+             * in the same order as the file, and scanned completely.
+             * With the ACL, we reverse the order as we load it, then
+             * when we scan it we stop as soon as we get a match.
+             */
+            cur_acl->next  = config->acl;
+            config->acl = cur_acl;
+
+            continue;
+#endif /* def FEATURE_ACL */
+
+/* *************************************************************************
+ * proxy-info-url url
+ * *************************************************************************/
+         case hash_proxy_info_url :
+            freez(config->proxy_info_url);
+            config->proxy_info_url = strdup(arg);
+            continue;
+
+/* *************************************************************************
+ * re_filterfile file-name
+ * In confdir by default.
+ * *************************************************************************/
+         case hash_filterfile :
+            freez(config->re_filterfile);
+            config->re_filterfile = make_path(config->confdir, arg);
+            continue;
+
+/* *************************************************************************
+ * single-threaded
+ * *************************************************************************/
+         case hash_single_threaded :
+            config->multi_threaded = 0;
+            continue;
+
+/* *************************************************************************
+ * toggle (0|1)
+ * *************************************************************************/
+#ifdef FEATURE_TOGGLE
+         case hash_toggle :
+            g_bToggleIJB = atoi(arg);
+            continue;
+#endif /* def FEATURE_TOGGLE */
+
+/* *************************************************************************
+ * trust-info-url url
+ * *************************************************************************/
+#ifdef FEATURE_TRUST
+         case hash_trust_info_url :
+            enlist(config->trust_info, arg);
+            continue;
+#endif /* def FEATURE_TRUST */
+
+/* *************************************************************************
+ * trustfile filename
+ * (In confdir by default.)
+ * *************************************************************************/
+#ifdef FEATURE_TRUST
+         case hash_trustfile :
+            freez(config->trustfile);
+            config->trustfile = make_path(config->confdir, arg);
+            continue;
+#endif /* def FEATURE_TRUST */
+
+/* *************************************************************************
+ * usermanual url
+ * *************************************************************************/
+         case hash_usermanual :
+            freez(config->usermanual);
+            config->usermanual = strdup(arg);
+            continue;
+
+/* *************************************************************************
+ * Win32 Console options:
+ * *************************************************************************/
+
+/* *************************************************************************
+ * hide-console
+ * *************************************************************************/
+#ifdef _WIN_CONSOLE
+         case hash_hide_console :
+            hideConsole = 1;
+            continue;
+#endif /*def _WIN_CONSOLE*/
+
+
+/* *************************************************************************
+ * Win32 GUI options:
+ * *************************************************************************/
+
+#if defined(_WIN32) && ! defined(_WIN_CONSOLE)
+/* *************************************************************************
+ * activity-animation (0|1)
+ * *************************************************************************/
+         case hash_activity_animation :
+            g_bShowActivityAnimation = atoi(arg);
+            continue;
+
+/* *************************************************************************
+ *  close-button-minimizes (0|1)
+ * *************************************************************************/
+         case hash_close_button_minimizes :
+            g_bCloseHidesWindow = atoi(arg);
+            continue;
+
+/* *************************************************************************
+ * log-buffer-size (0|1)
+ * *************************************************************************/
+         case hash_log_buffer_size :
+            g_bLimitBufferSize = atoi(arg);
+            continue;
+
+/* *************************************************************************
+ * log-font-name fontnane
+ * *************************************************************************/
+         case hash_log_font_name :
+            strcpy( g_szFontFaceName, arg );
+            continue;
+
+/* *************************************************************************
+ * log-font-size n
+ * *************************************************************************/
+         case hash_log_font_size :
+            g_nFontSize = atoi(arg);
+            continue;
+
+/* *************************************************************************
+ * log-highlight-messages (0|1)
+ * *************************************************************************/
+         case hash_log_highlight_messages :
+            g_bHighlightMessages = atoi(arg);
+            continue;
+
+/* *************************************************************************
+ * log-max-lines n
+ * *************************************************************************/
+         case hash_log_max_lines :
+            g_nMaxBufferLines = atoi(arg);
+            continue;
+
+/* *************************************************************************
+ * log-messages (0|1)
+ * *************************************************************************/
+         case hash_log_messages :
+            g_bLogMessages = atoi(arg);
+            continue;
+
+/* *************************************************************************
+ * show-on-task-bar (0|1)
+ * *************************************************************************/
+         case hash_show_on_task_bar :
+            g_bShowOnTaskBar = atoi(arg);
+            continue;
+
 #endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */
 
-            /* Warnings about unsupported features */
-
-#ifndef TRUST_FILES
-            case hash_trustfile :
-            case hash_trust_info_url :
-#endif /* ndef TRUST_FILES */
-#ifndef USE_IMAGE_LIST
-            case hash_imagefile :
-#endif /* ndef USE_IMAGE_LIST */
-#ifndef PCRS
-            case hash_re_filterfile :
-            case hash_re_filter_all :
-#endif /* ndef PCRS */
-#ifndef TOGGLE
-            case hash_toggle :
-#endif /* ndef TOGGLE */
-#if defined(_WIN_CONSOLE) || ! defined(_WIN32)
-            case hash_activity_animation :
-            case hash_log_messages :
-            case hash_log_highlight_messages :
-            case hash_log_buffer_size :
-            case hash_log_max_lines :
-            case hash_log_font_name :
-            case hash_log_font_size :
-            case hash_show_on_task_bar :
-            case hash_close_button_minimizes :
-#endif /* defined(_WIN_CONSOLE) || ! defined(_WIN32) */
+
+/* *************************************************************************
+ * Warnings about unsupported features
+ * *************************************************************************/
+#ifndef FEATURE_ACL
+         case hash_deny_access:
+#endif /* ndef FEATURE_ACL */
+#ifndef FEATURE_CGI_EDIT_ACTIONS
+         case hash_enable_edit_actions:
+         case hash_enable_remote_toggle:
+#endif /* def FEATURE_CGI_EDIT_ACTIONS */
+#ifndef FEATURE_COOKIE_JAR
+         case hash_jarfile :
+#endif /* ndef FEATURE_COOKIE_JAR */
+#ifndef FEATURE_ACL
+         case hash_permit_access:
+#endif /* ndef FEATURE_ACL */
+#ifndef FEATURE_TOGGLE
+         case hash_toggle :
+#endif /* ndef FEATURE_TOGGLE */
+#ifndef FEATURE_TRUST
+         case hash_trustfile :
+         case hash_trust_info_url :
+#endif /* ndef FEATURE_TRUST */
+
 #ifndef _WIN_CONSOLE
-            case hash_hide_console :
+         case hash_hide_console :
 #endif /* ndef _WIN_CONSOLE */
-#if !defined(DETECT_MSIE_IMAGES) && !defined(USE_IMAGE_LIST)
-            case hash_tinygif :
-#endif /* !defined(DETECT_MSIE_IMAGES) && !defined(USE_IMAGE_LIST) */
-#ifndef KILLPOPUPS
-            case hash_popupfile :
-            case hash_kill_all_popups :
-#endif /* ndef KILLPOPUPS */
-#ifndef JAR_FILES
-            case hash_jarfile :
-#endif /* ndef JAR_FILES */
-#ifndef ACL_FILES
-            case hash_aclfile :
-#endif /* ndef ACL_FILES */
-
-#ifdef SPLIT_PROXY_ARGS
-            case hash_suppress_blocklists :
-#endif /* def SPLIT_PROXY_ARGS */
-               log_error(LOG_LEVEL_INFO, "Unsupported directive \"%s\" ignored.", cmd);
-               continue;
 
-            default :
-               log_error(LOG_LEVEL_ERROR, "Unrecognized directive (%lulu) in "
-                     "configuration file: \"%s\"", hash_string( cmd ), buf);
-               p = malloc( BUFSIZ );
-               if (p != NULL)
-               {
-                  sprintf( p, "<br>\nWARNING: unrecognized directive : %s<br><br>\n", buf );
-                  proxy_args->invocation = strsav( proxy_args->invocation, p );
-                  freez( p );
-               }
-               /*
-                * I decided that I liked this better as a warning than an
-                * error.
-                */
-
-               /*
-                * configret = 1;
-                * return;
-                */
-               continue;
-         }
-      }
-      fclose(configfp);
-   }
-
-   init_error_log(Argv[0], logfile, debug);
+#if defined(_WIN_CONSOLE) || ! defined(_WIN32)
+         case hash_activity_animation :
+         case hash_close_button_minimizes :
+         case hash_log_buffer_size :
+         case hash_log_font_name :
+         case hash_log_font_size :
+         case hash_log_highlight_messages :
+         case hash_log_max_lines :
+         case hash_log_messages :
+         case hash_show_on_task_bar :
+#endif /* defined(_WIN_CONSOLE) || ! defined(_WIN32) */
+            /* These warnings are annoying - so hide them. -- Jon */
+            /* log_error(LOG_LEVEL_INFO, "Unsupported directive \"%s\" ignored.", cmd); */
+            continue;
 
-   if (cookiefile)
-   {
-      add_loader(load_cookiefile);
-   }
+/* *************************************************************************/
+         default :
+/* *************************************************************************/
+            /*
+             * I decided that I liked this better as a warning than an
+             * error.  To change back to an error, just change log level
+             * to LOG_LEVEL_FATAL.
+             */
+            log_error(LOG_LEVEL_ERROR, "Unrecognized directive '%s' (%luul) in line %lu in "
+                  "configuration file (%s).",  buf, hash_string(cmd), linenum, configfile);
+            string_append(&config->proxy_args, "<br>\nWARNING: unrecognized directive : ");
+            string_append(&config->proxy_args, buf);
+            string_append(&config->proxy_args, "<br><br>\n");
+            continue;
 
-   if (blockfile)
-   {
-      add_loader(load_blockfile);
-   }
+/* *************************************************************************/
+      } /* end switch( hash_string(cmd) ) */
+   } /* end while ( read_config_line(...) ) */
 
-#ifdef USE_IMAGE_LIST
-   if (imagefile)
-   {
-      add_loader(load_imagefile);
-   }
-#endif /* def USE_IMAGE_LIST */
+   fclose(configfp);
 
-#ifdef TRUST_FILES
-   if (trustfile)
+   if (NULL == config->proxy_args)
    {
-      add_loader(load_trustfile);
+      log_error(LOG_LEVEL_FATAL, "Out of memory loading config - insufficient memory for config->proxy_args");
    }
-#endif /* def TRUST_FILES */
 
-   if (forwardfile)
-   {
-      add_loader(load_forwardfile);
-   }
+   init_error_log(Argv[0], config->logfile, config->debug);
 
-#ifdef ACL_FILES
-   if (aclfile)
+   if (config->actions_file[0])
    {
-      add_loader(load_aclfile);
+      add_loader(load_actions_file, config);
    }
-#endif /* def ACL_FILES */
 
-#ifdef KILLPOPUPS
-   if (popupfile)
+   if (config->re_filterfile)
    {
-      add_loader(load_popupfile);
+      add_loader(load_re_filterfile, config);
    }
-#endif /* def KILLPOPUPS */
 
-#ifdef PCRS
-   if (re_filterfile)
+#ifdef FEATURE_TRUST
+   if (config->trustfile)
    {
-      add_loader(load_re_filterfile);
+      add_loader(load_trustfile, config);
    }
-#endif /* def PCRS */
+#endif /* def FEATURE_TRUST */
 
-#ifdef JAR_FILES
-   if ( NULL != jarfile )
+#ifdef FEATURE_COOKIE_JAR
+   if ( NULL != config->jarfile )
    {
-      if ( NULL == (jar = fopen(jarfile, "a")) )
+      if ( NULL == (config->jar = fopen(config->jarfile, "a")) )
       {
-         log_error(LOG_LEVEL_ERROR, "can't open jarfile '%s': %E", jarfile);
-         configret = 1;
-         return;
+         log_error(LOG_LEVEL_FATAL, "can't open jarfile '%s': %E", config->jarfile);
+         /* Never get here - LOG_LEVEL_FATAL causes program exit */
       }
-      setbuf(jar, NULL);
+      setbuf(config->jar, NULL);
    }
-#endif /* def JAR_FILES */
+#endif /* def FEATURE_COOKIE_JAR */
 
-   if ( NULL == haddr )
+   if ( NULL == config->haddr )
    {
-      haddr = strdup( HADDR_DEFAULT );
+      config->haddr = strdup( HADDR_DEFAULT );
    }
 
-   if ( NULL != haddr )
+   if ( NULL != config->haddr )
    {
-      if ((p = strchr(haddr, ':')))
+      if (NULL != (p = strchr(config->haddr, ':')))
       {
          *p++ = '\0';
          if (*p)
          {
-            hport = atoi(p);
+            config->hport = atoi(p);
          }
       }
 
-      if (hport <= 0)
+      if (config->hport <= 0)
       {
          *--p = ':';
-         log_error(LOG_LEVEL_ERROR, "invalid bind port spec %s", haddr);
-         configret = 1;
-         return;
+         log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
+         /* Never get here - LOG_LEVEL_FATAL causes program exit */
       }
-      if (*haddr == '\0')
+      if (*config->haddr == '\0')
       {
-         haddr = NULL;
+         config->haddr = NULL;
       }
    }
 
-   if (run_loader(NULL))
+   /*
+    * Want to run all the loaders once now.
+    *
+    * Need to set up a fake csp, so they can get to the config.
+    */
+   fake_csp = (struct client_state *) zalloc (sizeof(*fake_csp));
+   fake_csp->config = config;
+
+   if (run_loader(fake_csp))
    {
-      configret = 1;
-      return;
+      freez(fake_csp);
+      log_error(LOG_LEVEL_FATAL, "A loader failed while loading config file. Exiting.");
+      /* Never get here - LOG_LEVEL_FATAL causes program exit */
+   }
+   freez(fake_csp);
+
+/* FIXME: this is a kludge for win32 */
+#if defined(_WIN32) && !defined (_WIN_CONSOLE)
+
+   g_actions_file     = config->actions_file[0]; /* FIXME only works for first action file */
+   g_re_filterfile    = config->re_filterfile;
+
+#ifdef FEATURE_TRUST
+   g_trustfile        = config->trustfile;
+#endif /* def FEATURE_TRUST */
+
+
+#endif /* defined(_WIN32) && !defined (_WIN_CONSOLE) */
+/* FIXME: end kludge */
+
+
+   config->need_bind = 1;
+
+   if (current_configfile)
+   {
+      struct configuration_spec * oldcfg = (struct configuration_spec *)
+                                           current_configfile->f;
+      /*
+       * Check if config->haddr,hport == oldcfg->haddr,hport
+       *
+       * The following could be written more compactly as a single,
+       * (unreadably long) if statement.
+       */
+      config->need_bind = 0;
+      if (config->hport != oldcfg->hport)
+      {
+         config->need_bind = 1;
+      }
+      else if (config->haddr == NULL)
+      {
+         if (oldcfg->haddr != NULL)
+         {
+            config->need_bind = 1;
+         }
+      }
+      else if (oldcfg->haddr == NULL)
+      {
+         config->need_bind = 1;
+      }
+      else if (0 != strcmp(config->haddr, oldcfg->haddr))
+      {
+         config->need_bind = 1;
+      }
+
+      current_configfile->unloader = unload_configfile;
    }
 
-#ifdef JAR_FILES
+   fs->next = files->next;
+   files->next = fs;
+
+   current_configfile = fs;
+
+   return (config);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  savearg
+ *
+ * Description :  Called from `load_config'.  It saves each non-empty
+ *                and non-comment line from config into
+ *                config->proxy_args.  This is used to create the
+ *                show-proxy-args page.  On error, frees
+ *                config->proxy_args and sets it to NULL
+ *
+ * Parameters  :
+ *          1  :  command = config setting that was found
+ *          2  :  argument = the setting's argument (if any)
+ *          3  :  config = Configuration to save into.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void savearg(char *command, char *argument, struct configuration_spec * config)
+{
+   char * buf;
+   char * s;
+
+   assert(command);
+   assert(*command);
+   assert(argument);
+
    /*
-    * If we're logging cookies in a cookie jar, and the user has not
-    * supplied any wafers, and the user has not told us to suppress the
-    * vanilla wafer, then send the vanilla wafer.
+    * Add config option name embedded in
+    * link to it's section in the user-manual
     */
-   if ((jarfile != NULL)
-       && (wafer_list->next == NULL)
-       && (suppress_vanilla_wafer == 0))
+   buf = strdup("<a href=\"");
+   string_append(&buf, config->usermanual);
+   string_append(&buf, CONFIG_HELP_PREFIX);
+   string_join  (&buf, string_toupper(command));
+   string_append(&buf, "\">");
+   string_append(&buf, command);
+   string_append(&buf, "</a> ");
+
+   if (NULL == buf)
    {
-      enlist(wafer_list, VANILLA_WAFER);
+      freez(config->proxy_args);
+      return;
+   }
+
+   if ( (NULL != argument) && ('\0' != *argument) )
+   {
+      s = html_encode(argument);
+      if (NULL == s)
+      {
+         freez(buf);
+         freez(config->proxy_args);
+         return;
+      }
+
+      if (strncmpic(argument, "http://", 7) == 0)
+      {
+         string_append(&buf, "<a href=\"");
+         string_append(&buf, s);
+         string_append(&buf, "\">");
+         string_join  (&buf, s);
+         string_append(&buf, "</a>");
+      }
+      else
+      {
+         string_join  (&buf, s);
+      }
    }
-#endif /* def JAR_FILES */
 
-   end_proxy_args();
+   string_append(&buf, "<br>\n");
 
+   string_join(&config->proxy_args, buf);
 }
 
 
index e567b7e..3e71b75 100644 (file)
--- a/loadcfg.h
+++ b/loadcfg.h
@@ -1,9 +1,9 @@
-#ifndef _LOADCFG_H
-#define _LOADCFG_H
-#define LOADCFG_H_VERSION "$Id: loadcfg.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef LOADCFG_H_INCLUDED
+#define LOADCFG_H_INCLUDED
+#define LOADCFG_H_VERSION "$Id: loadcfg.h,v 1.10 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/loadcfg.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.h,v $
  *
  * Purpose     :  Loads settings from the configuration file into
  *                global variables.  This file contains both the 
@@ -11,7 +11,7 @@
  *                variables it writes to.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: loadcfg.h,v $
+ *    Revision 1.10  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.9  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.8  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.7  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.6  2001/07/29 18:58:15  jongfoster
+ *    Removing nested #includes, adding forward declarations for needed
+ *    structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
+ *
+ *    Revision 1.5  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.4  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.3  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.2  2001/05/17 23:01:01  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:58  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
-/* Declare struct FILE for vars and funcs. */
-#include <stdio.h>
-
-/* All of our project's data types. */
-#include "project.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* Don't need project.h, only this: */
+struct configuration_spec;
+
 /* Global variables */
 
-#ifdef TOGGLE
+#ifdef FEATURE_TOGGLE
 /* indicates if ijb is enabled */
 extern int g_bToggleIJB;
-#endif
-
-extern int debug;
-extern int multi_threaded;
-
-#if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
-extern int tinygif;
-extern const char *tinygifurl;\r
-#endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
-
-extern const char *logfile;
+#endif /* def FEATURE_TOGGLE */
 
 extern const char *configfile;
 
-#ifdef ACL_FILES
-extern const char *aclfile;
-#endif /* def ACL_FILES */
-
-extern const char *blockfile;
-extern const char *cookiefile;
-extern const char *forwardfile;
-
-#ifdef USE_IMAGE_LIST
-extern const char *imagefile;
-#endif /* def USE_IMAGE_LIST */
-
-#ifdef KILLPOPUPS
-extern const char *popupfile;
-#endif /* def KILLPOPUPS */
-
-#ifdef TRUST_FILES
-extern const char *trustfile;
-#endif /* def TRUST_FILES */
-
-#ifdef PCRS
-extern const char *re_filterfile;
-#endif /* def PCRS */
-
-#ifdef PCRS
-extern int re_filter_all;
-#endif /* def PCRS */
-
-#ifdef KILLPOPUPS
-extern int kill_all_popups;     /* Not recommended really .. */
-#endif /* def KILLPOPUPS */
-
-#ifdef JAR_FILES
-extern const char *jarfile;
-extern FILE *jar;
-#endif /* def JAR_FILES */
-
-extern const char *referrer;
-extern const char *uagent;
-extern const char *from;
-
-#ifndef SPLIT_PROXY_ARGS
-extern const char *suppress_message;
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-extern int suppress_vanilla_wafer;
-extern int add_forwarded;
-
-extern struct list wafer_list[];
-extern struct list xtra_list[];
-
-#ifdef TRUST_FILES
-extern struct list trust_info[];
-extern struct url_spec *trust_list[];
-#endif /* def TRUST_FILES */
-
-extern const char *haddr;
-extern int   hport;
-
-#ifndef SPLIT_PROXY_ARGS
-extern int suppress_blocklists;  /* suppress listing sblock and simage */
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-extern struct proxy_args proxy_args[1];
-
-extern int configret;
-extern int config_changed;
-
 
 /* The load_config function is now going to call:
  * init_proxy_args, so it will need argc and argv.
@@ -146,10 +163,14 @@ extern int config_changed;
  */
 extern int Argc;
 extern const char **Argv;
+extern short int MustReload;
 
 
-extern void load_config( int );
+extern struct configuration_spec * load_config(void);
 
+#ifdef FEATURE_GRACEFUL_TERMINATION
+void unload_current_config_file(void);
+#endif
 
 /* Revision control strings from this header and associated .c file */
 extern const char loadcfg_rcs[];
@@ -159,7 +180,7 @@ extern const char loadcfg_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _JCC_H */
+#endif /* ndef LOADCFG_H_INCLUDED */
 
 /*
   Local Variables:
index 71ff3fa..8ebfa70 100644 (file)
--- a/loaders.c
+++ b/loaders.c
@@ -1,21 +1,21 @@
-const char loaders_rcs[] = "$Id: loaders.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char loaders_rcs[] = "$Id: loaders.c,v 1.49 2002/04/19 16:53:25 jongfoster Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/loaders.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/loaders.c,v $
  *
  * Purpose     :  Functions to load and unload the various
  *                configuration files.  Also contains code to manage
- *                the list of active loaders, and to automatically 
+ *                the list of active loaders, and to automatically
  *                unload files that are no longer in use.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -35,6 +35,232 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.1 2001/05/13 21:57:06 administrat
  *
  * Revisions   :
  *    $Log: loaders.c,v $
+ *    Revision 1.49  2002/04/19 16:53:25  jongfoster
+ *    Optimize away a function call by using an equivalent macro
+ *
+ *    Revision 1.48  2002/04/05 00:56:09  gliptak
+ *    Correcting typo to clean up on realloc failure
+ *
+ *    Revision 1.47  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.46  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.45  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.44  2002/03/16 21:51:00  jongfoster
+ *    Fixing free(NULL).
+ *
+ *    Revision 1.43  2002/03/16 20:28:34  oes
+ *    Added descriptions to the filters so users will know what they select in the cgi editor
+ *
+ *    Revision 1.42  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.41  2002/03/12 01:42:50  oes
+ *    Introduced modular filters
+ *
+ *    Revision 1.40  2002/03/08 17:46:04  jongfoster
+ *    Fixing int/size_t warnings
+ *
+ *    Revision 1.39  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.38  2002/03/06 22:54:35  jongfoster
+ *    Automated function-comment nitpicking.
+ *
+ *    Revision 1.37  2002/03/03 15:07:49  oes
+ *    Re-enabled automatic config reloading
+ *
+ *    Revision 1.36  2002/01/22 23:46:18  jongfoster
+ *    Moving edit_read_line() and simple_read_line() to loaders.c, and
+ *    extending them to support reading MS-DOS, Mac and UNIX style files
+ *    on all platforms.
+ *
+ *    Modifying read_config_line() (without changing it's prototype) to
+ *    be a trivial wrapper for edit_read_line().  This means that we have
+ *    one function to read a line and handle comments, which is common
+ *    between the initialization code and the edit interface.
+ *
+ *    Revision 1.35  2002/01/17 21:03:08  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Renaming free_url to free_url_spec, since it frees a struct url_spec.
+ *
+ *    Revision 1.34  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.33  2001/11/13 00:16:38  jongfoster
+ *    Replacing references to malloc.h with the standard stdlib.h
+ *    (See ANSI or K&R 2nd Ed)
+ *
+ *    Revision 1.32  2001/11/07 00:02:13  steudten
+ *    Add line number in error output for lineparsing for
+ *    actionsfile and configfile.
+ *    Special handling for CLF added.
+ *
+ *    Revision 1.31  2001/10/26 17:39:01  oes
+ *    Removed csp->referrer
+ *    Moved ijb_isspace and ijb_tolower to project.h
+ *
+ *    Revision 1.30  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.29  2001/10/23 21:38:53  jongfoster
+ *    Adding error-checking to create_url_spec()
+ *
+ *    Revision 1.28  2001/10/07 15:40:39  oes
+ *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
+ *
+ *    Revision 1.27  2001/09/22 16:36:59  jongfoster
+ *    Removing unused parameter fs from read_config_line()
+ *
+ *    Revision 1.26  2001/09/22 14:05:22  jongfoster
+ *    Bugfix: Multiple escaped "#" characters in a configuration
+ *    file are now permitted.
+ *    Also removing 3 unused headers.
+ *
+ *    Revision 1.25  2001/09/13 22:44:03  jongfoster
+ *    Adding {} to an if statement
+ *
+ *    Revision 1.24  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.23  2001/07/20 15:51:54  oes
+ *    Fixed indentation of prepocessor commands
+ *
+ *    Revision 1.22  2001/07/20 15:16:17  haroon
+ *    - per Guy's suggestion, added a while loop in sweep() to catch not just
+ *      the last inactive CSP but all other consecutive inactive CSPs after that
+ *      as well
+ *
+ *    Revision 1.21  2001/07/18 17:26:24  oes
+ *    Changed to conform to new pcrs interface
+ *
+ *    Revision 1.20  2001/07/17 13:07:01  oes
+ *    Fixed segv when last line in config files
+ *     lacked a terminating (\r)\n
+ *
+ *    Revision 1.19  2001/07/13 14:01:54  oes
+ *    Removed all #ifdef PCRS
+ *
+ *    Revision 1.18  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.17  2001/06/29 13:31:51  oes
+ *    Various adaptions
+ *
+ *    Revision 1.16  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.15  2001/06/07 23:14:14  jongfoster
+ *    Removing ACL and forward file loaders - these
+ *    files have been merged into the config file.
+ *    Cosmetic: Moving unloader funcs next to their
+ *    respective loader funcs
+ *
+ *    Revision 1.14  2001/06/01 03:27:04  oes
+ *    Fixed line continuation problem
+ *
+ *    Revision 1.13  2001/05/31 21:28:49  jongfoster
+ *    Removed all permissionsfile code - it's now called the actions
+ *    file, and (almost) all the code is in actions.c
+ *
+ *    Revision 1.12  2001/05/31 17:32:31  oes
+ *
+ *     - Enhanced domain part globbing with infix and prefix asterisk
+ *       matching and optional unanchored operation
+ *
+ *    Revision 1.11  2001/05/29 23:25:24  oes
+ *
+ *     - load_config_line() and load_permissions_file() now use chomp()
+ *
+ *    Revision 1.10  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.9  2001/05/26 17:12:07  jongfoster
+ *    Fatal errors loading configuration files now give better error messages.
+ *
+ *    Revision 1.8  2001/05/26 00:55:20  jongfoster
+ *    Removing duplicated code.  load_forwardfile() now uses create_url_spec()
+ *
+ *    Revision 1.7  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.6  2001/05/23 12:27:33  oes
+ *
+ *    Fixed ugly indentation of my last changes
+ *
+ *    Revision 1.5  2001/05/23 10:39:05  oes
+ *    - Added support for escaping the comment character
+ *      in config files by a backslash
+ *    - Added support for line continuation in config
+ *      files
+ *    - Fixed a buffer overflow bug with long config lines
+ *
+ *    Revision 1.4  2001/05/22 18:56:28  oes
+ *    CRLF -> LF
+ *
+ *    Revision 1.3  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.2  2001/05/17 23:01:01  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:59  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -45,74 +271,39 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.1 2001/05/13 21:57:06 administrat
 #include <stdlib.h>
 #include <sys/types.h>
 #include <string.h>
-#include <malloc.h>
 #include <errno.h>
 #include <sys/stat.h>
 #include <ctype.h>
+#include <assert.h>
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__OS2__)
 #include <unistd.h>
 #endif
 
 #include "project.h"
+#include "list.h"
 #include "loaders.h"
-#include "encode.h"
 #include "filters.h"
 #include "parsers.h"
 #include "jcc.h"
-#include "ssplit.h"
 #include "miscutil.h"
 #include "errlog.h"
-#include "gateway.h"
-
-#ifndef SPLIT_PROXY_ARGS
-/* For strsav */
-#include "showargs.h"
-#endif /* ndef SPLIT_PROXY_ARGS */
+#include "actions.h"
+#include "urlmatch.h"
 
 const char loaders_h_rcs[] = LOADERS_H_VERSION;
 
-/* Fix a problem with Solaris.  There should be no effect on other
- * platforms.
- * Solaris's isspace() is a macro which uses it's argument directly
- * as an array index.  Therefore we need to make sure that high-bit
- * characters generate +ve values, and ideally we also want to make
- * the argument match the declared parameter type of "int".
- */
-#define ijb_isspace(__X) isspace((int)(unsigned char)(__X))
-
-
-#define NLOADERS 8
-static int (*loaders[NLOADERS])(struct client_state *);
-
-
 /*
  * Currently active files.
  * These are also entered in the main linked list of files.
  */
-static struct file_list *current_blockfile      = NULL;
-static struct file_list *current_cookiefile     = NULL;
-static struct file_list *current_forwardfile    = NULL;
-
-#ifdef ACL_FILES
-static struct file_list *current_aclfile        = NULL;
-#endif /* def ACL_FILES */
 
-#ifdef USE_IMAGE_LIST
-static struct file_list *current_imagefile      = NULL;
-#endif /* def USE_IMAGE_LIST */
-
-#ifdef KILLPOPUPS
-static struct file_list * current_popupfile     = NULL;
-#endif /* def KILLPOPUPS */
-
-#ifdef TRUST_FILES
+#ifdef FEATURE_TRUST
 static struct file_list *current_trustfile      = NULL;
-#endif /* def TRUST_FILES */
+#endif /* def FEATURE_TRUST */
 
-#ifdef PCRS
 static struct file_list *current_re_filterfile  = NULL;
-#endif /* def PCRS */
+
 
 
 /*********************************************************************
@@ -143,6 +334,7 @@ void sweep(void)
 {
    struct file_list *fl, *nfl;
    struct client_state *csp, *ncsp;
+   int i;
 
    /* clear all of the file's active flags */
    for ( fl = files->next; NULL != fl; fl = fl->next )
@@ -150,93 +342,82 @@ void sweep(void)
       fl->active = 0;
    }
 
-   for (csp = clients; csp && (ncsp = csp->next) ; csp = csp->next)
+   for (csp = clients; csp && (NULL != (ncsp = csp->next)) ; csp = csp->next)
    {
-      if (ncsp->active)
+      if (ncsp->flags & CSP_FLAG_ACTIVE)
       {
          /* mark this client's files as active */
 
-         if (ncsp->blist)     /* block files */
-         {
-            ncsp->blist->active = 1;
-         }
-
-         if (ncsp->clist)     /* cookie files */
-         {
-            ncsp->clist->active = 1;
-         }
-
-         /* FIXME: These were left out of the "10" release.  Should they be here? */
-         if (ncsp->flist)     /* forward files */
-         {
-            ncsp->flist->active = 1;
-         }
-
-#ifdef ACL_FILES
-         if (ncsp->alist)     /* acl files */
-         {
-            ncsp->alist->active = 1;
-         }
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-         if (ncsp->ilist)     /* image files */
-         {
-            ncsp->ilist->active = 1;
-         }
-#endif /* def USE_IMAGE_LIST */
+         /*
+          * Always have a configuration file.
+          * (Also note the slightly non-standard extra
+          * indirection here.)
+          */
+         ncsp->config->config_file_list->active = 1;
 
-#ifdef KILLPOPUPS
-         if (ncsp->plist)     /* killpopup files */
+         for (i = 0; i < MAX_ACTION_FILES; i++)
          {
-            ncsp->plist->active = 1;
+            if (ncsp->actions_list[i])     /* actions files */
+            {
+               ncsp->actions_list[i]->active = 1;
+            }
          }
-#endif /* def KILLPOPUPS */
 
-#ifdef PCRS
-         if (ncsp->rlist)     /* perl re files */
+         if (ncsp->rlist)     /* pcrsjob files */
          {
             ncsp->rlist->active = 1;
          }
-#endif /* def PCRS */
 
-#ifdef TRUST_FILES
+#ifdef FEATURE_TRUST
          if (ncsp->tlist)     /* trust files */
          {
             ncsp->tlist->active = 1;
          }
-#endif /* def TRUST_FILES */
+#endif /* def FEATURE_TRUST */
 
       }
       else
+      /*
+       * this client is not active, release its resources
+       * and the ones of all inactive clients that might
+       * follow it
+       */
       {
-         /* this client one is not active, release its resources */
-         csp->next = ncsp->next;
+         while (!(ncsp->flags & CSP_FLAG_ACTIVE))
+         {
+            csp->next = ncsp->next;
 
-         freez(ncsp->ip_addr_str);
-         freez(ncsp->referrer);
-         freez(ncsp->x_forwarded);
-         freez(ncsp->ip_addr_str);
-         freez(ncsp->iob->buf);
+            freez(ncsp->ip_addr_str);
+            freez(ncsp->my_ip_addr_str);
+            freez(ncsp->my_hostname);
+            freez(ncsp->x_forwarded);
+            freez(ncsp->iob->buf);
 
-         free_http_request(ncsp->http);
+            free_http_request(ncsp->http);
 
-         destroy_list(ncsp->headers);
-         destroy_list(ncsp->cookie_list);
+            destroy_list(ncsp->headers);
+            destroy_list(ncsp->cookie_list);
 
-#ifdef STATISTICS
-         urls_read++;
-         if (ncsp->rejected)
-         {
-            urls_rejected++;
-         }
-#endif /* def STATISTICS */
+            free_current_action(ncsp->action);
+
+#ifdef FEATURE_STATISTICS
+            urls_read++;
+            if (ncsp->flags & CSP_FLAG_REJECTED)
+            {
+               urls_rejected++;
+            }
+#endif /* def FEATURE_STATISTICS */
 
-         freez(ncsp);
+            freez(ncsp);
+
+            /* are there any more in sequence after it? */
+            if( (ncsp = csp->next) == NULL)
+               break;
+         }
       }
    }
 
-   for (fl = files; fl && (nfl = fl->next) ; fl = fl->next)
+   for (fl = files; fl && ((nfl = fl->next) != NULL) ; fl = fl->next)
    {
       if ( ( 0 == nfl->active ) && ( NULL != nfl->unloader ) )
       {
@@ -244,10 +425,6 @@ void sweep(void)
 
          (nfl->unloader)(nfl->f);
 
-#ifndef SPLIT_PROXY_ARGS
-         freez(nfl->proxy_args);
-#endif /* ndef SPLIT_PROXY_ARGS */
-
          freez(nfl->filename);
 
          freez(nfl);
@@ -257,289 +434,18 @@ void sweep(void)
 }
 
 
-/*********************************************************************
- *
- * Function    :  unload_url
- *
- * Description :  Called from the "unloaders".  Freez the url
- *                structure elements.
- *
- * Parameters  :
- *          1  :  url = pointer to a url_spec structure.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_url(struct url_spec *url)
-{
-   if (url == NULL) return;
-
-   freez(url->spec);
-   freez(url->domain);
-   freez(url->dbuf);
-   freez(url->dvec);
-   freez(url->path);
-#ifdef REGEX
-   if (url->preg)
-   {
-      regfree(url->preg);
-      freez(url->preg);
-   }
-#endif
-
-}
-
-
-#ifdef ACL_FILES
-/*********************************************************************
- *
- * Function    :  unload_aclfile
- *
- * Description :  Unloads an aclfile.
- *
- * Parameters  :
- *          1  :  f = the data structure associated with the aclfile.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_aclfile(void *f)
-{
-   struct access_control_list *b = (struct access_control_list *)f;
-   if (b == NULL) return;
-
-   unload_aclfile(b->next);
-
-   freez(b);
-
-}
-#endif /* def ACL_FILES */
-
-/*********************************************************************
- *
- * Function    :  unload_blockfile
- *
- * Description :  Unloads a blockfile.
- *
- * Parameters  :
- *          1  :  f = the data structure associated with the blockfile.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_blockfile(void *f)
-{
-   struct block_spec *b = (struct block_spec *)f;
-   if (b == NULL) return;
-
-   unload_blockfile(b->next);
-
-   unload_url(b->url);
-
-   freez(b);
-
-}
-
-
-#ifdef USE_IMAGE_LIST
-/*********************************************************************
- *
- * Function    :  unload_imagefile
- *
- * Description :  Unloads an imagefile.
- *
- * Parameters  :
- *          1  :  f = the data structure associated with the imagefile.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_imagefile(void *f)
-{
-   struct block_spec *b = (struct block_spec *)f;
-   if (b == NULL) return;
-
-   unload_imagefile(b->next);
-
-   unload_url(b->url);
-
-   freez(b);
-
-}
-#endif /* def USE_IMAGE_LIST */
-
-
-/*********************************************************************
- *
- * Function    :  unload_cookiefile
- *
- * Description :  Unloads a cookiefile.
- *
- * Parameters  :
- *          1  :  f = the data structure associated with the cookiefile.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_cookiefile(void *f)
-{
-   struct cookie_spec *b = (struct cookie_spec *)f;
-   if (b == NULL) return;
-
-   unload_cookiefile(b->next);
-
-   unload_url(b->url);
-
-   freez(b);
-
-}
-
-
-#ifdef TRUST_FILES
-/*********************************************************************
- *
- * Function    :  unload_trustfile
- *
- * Description :  Unloads a trustfile.
- *
- * Parameters  :
- *          1  :  f = the data structure associated with the trustfile.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_trustfile(void *f)
-{
-   struct block_spec *b = (struct block_spec *)f;
-   if (b == NULL) return;
-
-   unload_trustfile(b->next);
-
-   unload_url(b->url);
-
-   freez(b);
-
-}
-#endif /* def TRUST_FILES */
-
-
-/*********************************************************************
- *
- * Function    :  unload_forwardfile
- *
- * Description :  Unloads a forwardfile.
- *
- * Parameters  :
- *          1  :  f = the data structure associated with the forwardfile.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_forwardfile(void *f)
-{
-   struct forward_spec *b = (struct forward_spec *)f;
-   if (b == NULL) return;
-
-   unload_forwardfile(b->next);
-
-   unload_url(b->url);
-
-   freez(b->gw->gateway_host);
-   freez(b->gw->forward_host);
-
-   freez(b);
-
-}
-
-
-#ifdef PCRS
-/*********************************************************************
- *
- * Function    :  unload_re_filterfile
- *
- * Description :  Unload the re_filter list.
- *
- * Parameters  :
- *          1  :  f = the data structure associated with the filterfile.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_re_filterfile(void *f)
-{
-   pcrs_job *joblist;
-   struct re_filterfile_spec *b = (struct re_filterfile_spec *)f;
-
-   if (b == NULL) return;
-
-   destroy_list(b->patterns);
-
-   joblist = b->joblist;
-   while ( NULL != (joblist = pcrs_free_job(joblist)) ) {}
-
-   freez(b);
-
-}
-#endif /* def PCRS */
-
-
-#ifdef KILLPOPUPS
-/*********************************************************************
- *
- * Function    :  unload_popupfile
- *
- * Description :  Free the lists of blocked, and allowed popup sites.
- *
- * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void unload_popupfile(void * b)
-{
-   struct popup_settings * data = (struct popup_settings *) b;
-   struct popup_blocklist * cur = NULL;
-   struct popup_blocklist * temp= NULL;
-
-   /* Free the blocked list. */
-   cur = data->blocked;
-   while (cur != NULL)
-   {
-      temp = cur->next;
-      freez (cur->host_name);
-      free  (cur);
-      cur  = temp;
-   }
-   data->blocked = NULL;
-
-   /* Free the allowed list. */
-   cur = data->allowed;
-   while (cur != NULL)
-   {
-      temp = cur->next;
-      freez (cur->host_name);
-      free  (cur);
-      cur  = temp;
-   }
-   data->allowed = NULL;
-
-}
-#endif /* def KILLPOPUPS */
-
-
 /*********************************************************************
  *
  * Function    :  check_file_changed
  *
  * Description :  Helper function to check if a file needs reloading.
  *                If "current" is still current, return it.  Otherwise
- *                allocates a new (zeroed) "struct file_list", fills 
+ *                allocates a new (zeroed) "struct file_list", fills
  *                in the disk file name and timestamp, and returns it.
  *
  * Parameters  :
  *          1  :  current = The file_list currently being used - will
- *                          be checked to see if it is out of date. 
+ *                          be checked to see if it is out of date.
  *                          May be NULL (which is treated as out of
  *                          date).
  *          2  :  filename = Name of file to check.
@@ -547,19 +453,16 @@ static void unload_popupfile(void * b)
  *                           This will be set to NULL, OR a struct
  *                           file_list newly allocated on the
  *                           heap, with the filename and lastmodified
- *                           fields filled, standard header giving file
- *                           name in proxy_args, and all others zeroed.
- *                           (proxy_args is only filled in if
- *                           SPLIT_PROXY_ARGS and !suppress_blocklists).
+ *                           fields filled, and all others zeroed.
  *
  * Returns     :  If file unchanged: 0 (and sets newfl == NULL)
  *                If file changed: 1 and sets newfl != NULL
  *                On error: 1 and sets newfl == NULL
  *
  *********************************************************************/
-static int check_file_changed(const struct file_list * current,
-                              const char * filename,
-                              struct file_list ** newfl)
+int check_file_changed(const struct file_list * current,
+                       const char * filename,
+                       struct file_list ** newfl)
 {
    struct file_list *fs;
    struct stat statbuf[1];
@@ -580,7 +483,6 @@ static int check_file_changed(const struct file_list * current,
    }
 
    fs = (struct file_list *)zalloc(sizeof(struct file_list));
-
    if (fs == NULL)
    {
       /* Out of memory error */
@@ -596,23 +498,6 @@ static int check_file_changed(const struct file_list * current,
       freez (fs);
       return 1;
    }
-
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      char * p = html_encode(filename);
-      if (p)
-      {
-         fs->proxy_args = strsav(fs->proxy_args, "<h2>The file `");\r
-         fs->proxy_args = strsav(fs->proxy_args, p);\r
-         fs->proxy_args = strsav(fs->proxy_args, \r
-            "' contains the following patterns</h2>\n");\r
-         freez(p);\r
-      }
-      fs->proxy_args = strsav(fs->proxy_args, "<pre>");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
-
    *newfl = fs;
    return 1;
 }
@@ -620,1060 +505,520 @@ static int check_file_changed(const struct file_list * current,
 
 /*********************************************************************
  *
- * Function    :  read_config_line
+ * Function    :  simple_read_line
  *
- * Description :  Read a single non-empty line from a file and return
- *                it.  Trims comments, leading and trailing whitespace.
- *                Also wites the file to fs->proxy_args.
+ * Description :  Read a single line from a file and return it.
+ *                This is basically a version of fgets() that malloc()s
+ *                it's own line buffer.  Note that the buffer will
+ *                always be a multiple of BUFFER_SIZE bytes long.
+ *                Therefore if you are going to keep the string for
+ *                an extended period of time, you should probably
+ *                strdup() it and free() the original, to save memory.
  *
- * Parameters  :
- *          1  :  buf = Buffer to use.
- *          2  :  buflen = Size of buffer in bytes.
- *          3  :  fp = File to read from
- *          4  :  fs = File will be written to fs->proxy_args.  May
- *                be NULL to disable this feature.
  *
- * Returns     :  NULL on EOF or error
- *                Otherwise, returns buf.
+ * Parameters  :
+ *          1  :  dest = destination for newly malloc'd pointer to
+ *                line data.  Will be set to NULL on error.
+ *          2  :  fp = File to read from
+ *          3  :  newline = Standard for newlines in the file.
+ *                Will be unchanged if it's value on input is not
+ *                NEWLINE_UNKNOWN.
+ *                On output, may be changed from NEWLINE_UNKNOWN to
+ *                actual convention in file.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_FILE   on EOF.
  *
  *********************************************************************/
-char *read_config_line(char *buf, int buflen, FILE *fp, struct file_list *fs)
+jb_err simple_read_line(FILE *fp, char **dest, int *newline)
 {
-   char *p, *q;
-   char linebuf[BUFSIZ];
+   size_t len = 0;
+   size_t buflen = BUFFER_SIZE;
+   char * buf;
+   char * p;
+   int ch;
+   int realnewline = NEWLINE_UNKNOWN;
 
-   while (fgets(linebuf, sizeof(linebuf), fp))
+   if (NULL == (buf = malloc(buflen)))
    {
-#ifndef SPLIT_PROXY_ARGS
-      if (fs && !suppress_blocklists)
-      {
-         char *html_line = html_encode(linebuf);
-         if (html_line != NULL)
-         {
-            fs->proxy_args = strsav(fs->proxy_args, html_line);
-            freez(html_line);
-         }
-         fs->proxy_args = strsav(fs->proxy_args, "<br>");
-      }
-#endif /* ndef SPLIT_PROXY_ARGS */
+      return JB_ERR_MEMORY;
+   }
 
-      /* Trim off newline and any comment */
-      if ((p = strpbrk(linebuf, "\r\n#")) != NULL)
-      {
-         *p = '\0';
-      }
-      
-      /* Trim leading whitespace */
-      p = linebuf;
-      while (*p && ijb_isspace(*p))
+   p = buf;
+
+/*
+ * Character codes.  If you have a wierd compiler and the following are
+ * incorrect, you also need to fix NEWLINE() in loaders.h
+ */
+#define CHAR_CR '\r' /* ASCII 13 */
+#define CHAR_LF '\n' /* ASCII 10 */
+
+   for (;;)
+   {
+      ch = getc(fp);
+      if (ch == EOF)
       {
-         *p++;
+         if (len > 0)
+         {
+            *p = '\0';
+            *dest = buf;
+            return JB_ERR_OK;
+         }
+         else
+         {
+            free(buf);
+            *dest = NULL;
+            return JB_ERR_FILE;
+         }
       }
-
-      if (*p)
+      else if (ch == CHAR_CR)
       {
-         /* There is something other than whitespace on the line. */
-
-         /* Move the data to the start of buf */
-         if (p != linebuf)
+         ch = getc(fp);
+         if (ch == CHAR_LF)
          {
-            /* strcpy that can cope with overlap. */
-            q = linebuf;
-            while ((*q++ = *p++) != '\0')
+            if (*newline == NEWLINE_UNKNOWN)
             {
-               /* Do nothing */
+               *newline = NEWLINE_DOS;
             }
          }
-
-         /* Trim trailing whitespace */
-         p = linebuf + strlen(linebuf) - 1;
-
-         /*
-          * Note: the (p >= retval) below is paranoia, it's not really needed.
-          * When p == retval then ijb_isspace(*p) will be false and we'll drop
-          * out of the loop.
-          */
-         while ((p >= linebuf) && ijb_isspace(*p))
+         else
+         {
+            if (ch != EOF)
+            {
+               ungetc(ch, fp);
+            }
+            if (*newline == NEWLINE_UNKNOWN)
+            {
+               *newline = NEWLINE_MAC;
+            }
+         }
+         *p = '\0';
+         *dest = buf;
+         if (*newline == NEWLINE_UNKNOWN)
+         {
+            *newline = realnewline;
+         }
+         return JB_ERR_OK;
+      }
+      else if (ch == CHAR_LF)
+      {
+         *p = '\0';
+         *dest = buf;
+         if (*newline == NEWLINE_UNKNOWN)
          {
-            p--;
+            *newline = NEWLINE_UNIX;
          }
-         p[1] = '\0';
+         return JB_ERR_OK;
+      }
+      else if (ch == 0)
+      {
+         *p = '\0';
+         *dest = buf;
+         return JB_ERR_OK;
+      }
 
-         /* More paranoia.  This if statement is always true. */
-         if (*linebuf)
+      *p++ = ch;
+
+      if (++len >= buflen)
+      {
+         buflen += BUFFER_SIZE;
+         if (NULL == (p = realloc(buf, buflen)))
          {
-            strcpy(buf, linebuf);
-            return buf;
+            free(buf);
+            return JB_ERR_MEMORY;
          }
+         buf = p;
+         p = buf + len;
       }
    }
-
-   /* EOF */
-   return NULL;
 }
 
 
-#ifdef ACL_FILES
 /*********************************************************************
  *
- * Function    :  load_aclfile
+ * Function    :  edit_read_line
  *
- * Description :  Read and parse an aclfile and add to files list.
+ * Description :  Read a single non-empty line from a file and return
+ *                it.  Trims comments, leading and trailing whitespace
+ *                and respects escaping of newline and comment char.
+ *                Provides the line in 2 alternative forms: raw and
+ *                preprocessed.
+ *                - raw is the raw data read from the file.  If the
+ *                  line is not modified, then this should be written
+ *                  to the new file.
+ *                - prefix is any comments and blank lines that were
+ *                  read from the file.  If the line is modified, then
+ *                  this should be written out to the file followed
+ *                  by the modified data.  (If this string is non-empty
+ *                  then it will have a newline at the end).
+ *                - data is the actual data that will be parsed
+ *                  further by appropriate routines.
+ *                On EOF, the 3 strings will all be set to NULL and
+ *                0 will be returned.
  *
  * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
- *
- * Returns     :  0 => Ok, everything else is an error.
+ *          1  :  fp = File to read from
+ *          2  :  raw_out = destination for newly malloc'd pointer to
+ *                raw line data.  May be NULL if you don't want it.
+ *          3  :  prefix_out = destination for newly malloc'd pointer to
+ *                comments.  May be NULL if you don't want it.
+ *          4  :  data_out = destination for newly malloc'd pointer to
+ *                line data with comments and leading/trailing spaces
+ *                removed, and line continuation performed.  May be
+ *                NULL if you don't want it.
+ *          5  :  newline = Standard for newlines in the file.
+ *                On input, set to value to use or NEWLINE_UNKNOWN.
+ *                On output, may be changed from NEWLINE_UNKNOWN to
+ *                actual convention in file.  May be NULL if you
+ *                don't want it.
+ *          6  :  line_number = Line number in file.  In "lines" as
+ *                reported by a text editor, not lines containing data.
+ *
+ * Returns     :  JB_ERR_OK     on success
+ *                JB_ERR_MEMORY on out-of-memory
+ *                JB_ERR_FILE   on EOF.
  *
  *********************************************************************/
-int load_aclfile(struct client_state *csp)
+jb_err edit_read_line(FILE *fp,
+                      char **raw_out,
+                      char **prefix_out,
+                      char **data_out,
+                      int *newline,
+                      unsigned long *line_number)
 {
-   FILE *fp;
-   char buf[BUFSIZ], *v[3], *p;
-   int i;
-   struct access_control_list *a, *bl;
-   struct file_list *fs;
-
-   if (!check_file_changed(current_aclfile, aclfile, &fs))
-   {
-      /* No need to load */
-      if (csp)
-      {
-         csp->alist = current_aclfile;
-      }
-      return(0);
-   }
-   if (!fs)
-   {
-      goto load_aclfile_error;
-   }
-
-   fs->f = bl = (struct access_control_list *)zalloc(sizeof(*bl));
-   if (bl == NULL)
-   {
-      freez(fs->filename);
-      freez(fs);
-      goto load_aclfile_error;
-   }
-
-   fp = fopen(aclfile, "r");
+   char *p;          /* Temporary pointer   */
+   char *linebuf;    /* Line read from file */
+   char *linestart;  /* Start of linebuf, usually first non-whitespace char */
+   int contflag = 0; /* Nonzero for line continuation - i.e. line ends '\' */
+   int is_empty = 1; /* Flag if not got any data yet */
+   char *raw    = NULL; /* String to be stored in raw_out    */
+   char *prefix = NULL; /* String to be stored in prefix_out */
+   char *data   = NULL; /* String to be stored in data_out   */
+   int scrapnewline;    /* Used for (*newline) if newline==NULL */
+   jb_err rval = JB_ERR_OK;
 
-   if (fp == NULL)
-   {
-      goto load_aclfile_error;
-   }
+   assert(fp);
+   assert(raw_out || data_out);
+   assert(newline == NULL
+       || *newline == NEWLINE_UNKNOWN
+       || *newline == NEWLINE_UNIX
+       || *newline == NEWLINE_DOS
+       || *newline == NEWLINE_MAC);
 
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
+   if (newline == NULL)
    {
-      i = ssplit(buf, " \t", v, SZ(v), 1, 1);
-
-      /* allocate a new node */
-      a = (struct access_control_list *) zalloc(sizeof(*a));
-
-      if (a == NULL)
-      {
-         fclose(fp);
-         freez(fs->f);
-         freez(fs->filename);
-         freez(fs);
-         goto load_aclfile_error;
-      }
-
-      /* add it to the list */
-      a->next  = bl->next;
-      bl->next = a;
-
-      switch (i)
-      {
-         case 3:
-            if (acl_addr(v[2], a->dst) < 0)
-            {
-               goto load_aclfile_error;
-            }
-            /* no break */
-
-         case 2:
-            if (acl_addr(v[1], a->src) < 0)
-            {
-               goto load_aclfile_error;
-            }
-
-            p = v[0];
-            if (strcmpic(p, "permit") == 0)
-            {
-               a->action = ACL_PERMIT;
-               break;
-            }
-
-            if (strcmpic(p, "deny") == 0)
-            {
-               a->action = ACL_DENY;
-               break;
-            }
-            /* no break */
-
-         default:
-            goto load_aclfile_error;
-      }
+      scrapnewline = NEWLINE_UNKNOWN;
+      newline = &scrapnewline;
    }
 
-   fclose(fp);
-
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
+   /* Set output parameters to NULL */
+   if (raw_out)
    {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
+      *raw_out    = NULL;
    }
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-   if (current_aclfile)
+   if (prefix_out)
    {
-      current_aclfile->unloader = unload_aclfile;
+      *prefix_out = NULL;
    }
-
-   fs->next = files->next;
-   files->next = fs;
-   current_aclfile = fs;
-
-   if (csp)
+   if (data_out)
    {
-      csp->alist = fs;
+      *data_out   = NULL;
    }
 
-   return(0);
-
-load_aclfile_error:
-   log_error(LOG_LEVEL_ERROR, "can't load access control list %s: %E", aclfile);
-   return(-1);
-
-}
-#endif /* def ACL_FILES */
-
-
-/*********************************************************************
- *
- * Function    :  load_blockfile
- *
- * Description :  Read and parse a blockfile and add to files list.
- *
- * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
- *
- * Returns     :  0 => Ok, everything else is an error.
- *
- *********************************************************************/
-int load_blockfile(struct client_state *csp)
-{
-   FILE *fp;
-
-   struct block_spec *b, *bl;
-   char  buf[BUFSIZ], *p, *q;
-   int port, reject;
-   struct file_list *fs;
-   struct url_spec url[1];
+   /* Set string variables to new, empty strings. */
 
-   if (!check_file_changed(current_blockfile, blockfile, &fs))
+   if (raw_out)
    {
-      /* No need to load */
-      if (csp)
+      if ((raw = malloc(1)) == NULL)
       {
-         csp->blist = current_blockfile;
+         return JB_ERR_MEMORY;
       }
-      return(0);
+      *raw = '\0';
    }
-   if (!fs)
+   if (prefix_out)
    {
-      goto load_blockfile_error;
+      if ((prefix = malloc(1)) == NULL)
+      {
+         freez(raw);
+         return JB_ERR_MEMORY;
+      }
+      *prefix = '\0';
    }
-
-   fs->f = bl = (struct block_spec *) zalloc(sizeof(*bl));
-   if (bl == NULL)
+   if (data_out)
    {
-      goto load_blockfile_error;
+      if ((data = malloc(1)) == NULL)
+      {
+         freez(raw);
+         freez(prefix);
+         return JB_ERR_MEMORY;
+      }
+      *data = '\0';
    }
 
-   if ((fp = fopen(blockfile, "r")) == NULL)
-   {
-      goto load_blockfile_error;
-   }
+   /* Main loop.  Loop while we need more data & it's not EOF. */
 
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
+   while ( (contflag || is_empty)
+        && (JB_ERR_OK == (rval = simple_read_line(fp, &linebuf, newline))))
    {
-      reject = 1;
-
-      if (*buf == '~')
+      if (line_number)
       {
-         reject = 0;
-         p = buf;
-         q = p+1;
-         while ((*p++ = *q++))
+         (*line_number)++;
+      }
+      if (raw)
+      {
+         string_append(&raw,linebuf);
+         if (string_append(&raw,NEWLINE(*newline)))
          {
-            /* nop */
+            freez(prefix);
+            freez(data);
+            free(linebuf);
+            return JB_ERR_MEMORY;
          }
       }
 
-      /* skip lines containing only ~ */
-      if (*buf == '\0')
+      /* Line continuation? Trim escape and set flag. */
+      p = linebuf + strlen(linebuf) - 1;
+      contflag = ((*linebuf != '\0') && (*p == '\\'));
+      if (contflag)
       {
-         continue;
+         *p = '\0';
       }
 
-      /* allocate a new node */
-      if (((b = zalloc(sizeof(*b))) == NULL)
-#ifdef REGEX
-          || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
-#endif
-      )
+      /* Trim leading spaces if we're at the start of the line */
+      linestart = linebuf;
+      if (*data == '\0')
       {
-         fclose(fp);
-         goto load_blockfile_error;
+         /* Trim leading spaces */
+         while (*linestart && isspace((int)(unsigned char)*linestart))
+         {
+            linestart++;
+         }
       }
 
-      /* add it to the list */
-      b->next  = bl->next;
-      bl->next = b;
-
-      /* save a copy of the orignal specification */
-      if ((b->url->spec = strdup(buf)) == NULL)
+      /* Handle comment characters. */
+      p = linestart;
+      while ((p = strchr(p, '#')) != NULL)
       {
-         fclose(fp);
-         goto load_blockfile_error;
-      }
+         /* Found a comment char.. */
+         if ((p != linebuf) && (*(p-1) == '\\'))
+         {
+            /* ..and it's escaped, left-shift the line over the escape. */
+            char *q = p - 1;
+            while ((*q = *(q + 1)) != '\0')
+            {
+               q++;
+            }
+            /* Now scan from just after the "#". */
+         }
+         else
+         {
+            /* Real comment.  Save it... */
+            if (p == linestart)
+            {
+               /* Special case:  Line only contains a comment, so all the
+                * previous whitespace is considered part of the comment.
+                * Undo the whitespace skipping, if any.
+                */
+               linestart = linebuf;
+               p = linestart;
+            }
+            if (prefix)
+            {
+               string_append(&prefix,p);
+               if (string_append(&prefix, NEWLINE(*newline)))
+               {
+                  freez(raw);
+                  freez(data);
+                  free(linebuf);
+                  return JB_ERR_MEMORY;
+               }
+            }
 
-      b->reject = reject;
+            /* ... and chop off the rest of the line */
+            *p = '\0';
+         }
+      } /* END while (there's a # character) */
 
-      if ((p = strchr(buf, '/')))
-      {
-         b->url->path    = strdup(p);
-         b->url->pathlen = strlen(b->url->path);
-         *p = '\0';
-      }
-      else
+      /* Write to the buffer */
+      if (*linestart)
       {
-         b->url->path    = NULL;
-         b->url->pathlen = 0;
+         is_empty = 0;
+         if (data)
+         {
+            if (string_append(&data, linestart))
+            {
+               freez(raw);
+               freez(prefix);
+               free(linebuf);
+               return JB_ERR_MEMORY;
+            }
+         }
       }
-#ifdef REGEX
-      if (b->url->path)
-      {
-         int errcode;
-         char rebuf[BUFSIZ];
 
-         sprintf(rebuf, "^(%s)", b->url->path);
+      free(linebuf);
+   } /* END while(we need more data) */
 
-         errcode = regcomp(b->url->preg, rebuf,
-               (REG_EXTENDED|REG_NOSUB|REG_ICASE));
+   /* Handle simple_read_line() errors - ignore EOF */
+   if ((rval != JB_ERR_OK) && (rval != JB_ERR_FILE))
+   {
+      freez(raw);
+      freez(prefix);
+      freez(data);
+      return rval;
+   }
 
-         if (errcode)
-         {
-            size_t errlen =
-               regerror(errcode,
-                  b->url->preg, buf, sizeof(buf));
+   if (raw ? (*raw == '\0') : is_empty)
+   {
+      /* EOF and no data there.  (Definition of "data" depends on whether
+       * the caller cares about "raw" or just "data").
+       */
 
-            buf[errlen] = '\0';
+      freez(raw);
+      freez(prefix);
+      freez(data);
 
-            log_error(LOG_LEVEL_ERROR, "error compiling %s: %s\n",
-                    b->url->spec, buf);
-            fclose(fp);
-            goto load_blockfile_error;
-         }
+      return JB_ERR_FILE;
+   }
+   else
+   {
+      /* Got at least some data */
+
+      /* Remove trailing whitespace */
+      chomp(data);
+
+      if (raw_out)
+      {
+         *raw_out    = raw;
       }
       else
       {
-         freez(b->url->preg);
+         freez(raw);
       }
-#endif
-      if ((p = strchr(buf, ':')) == NULL)
+      if (prefix_out)
       {
-         port = 0;
+         *prefix_out = prefix;
       }
       else
       {
-         *p++ = '\0';
-         port = atoi(p);
+         freez(prefix);
       }
-
-      b->url->port = port;
-
-      if ((b->url->domain = strdup(buf)) == NULL)
+      if (data_out)
       {
-         fclose(fp);
-         goto load_blockfile_error;
+         *data_out   = data;
       }
-
-      /* split domain into components */
-      *url = dsplit(b->url->domain);
-      b->url->dbuf = url->dbuf;
-      b->url->dcnt = url->dcnt;
-      b->url->dvec = url->dvec;
+      else
+      {
+         freez(data);
+      }
+      return JB_ERR_OK;
    }
+}
 
-   fclose(fp);
-
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
 
-   /* the old one is now obsolete */
-   if (current_blockfile)
+/*********************************************************************
+ *
+ * Function    :  read_config_line
+ *
+ * Description :  Read a single non-empty line from a file and return
+ *                it.  Trims comments, leading and trailing whitespace
+ *                and respects escaping of newline and comment char.
+ *
+ * Parameters  :
+ *          1  :  buf = Buffer to use.
+ *          2  :  buflen = Size of buffer in bytes.
+ *          3  :  fp = File to read from
+ *          4  :  linenum = linenumber in file
+ *
+ * Returns     :  NULL on EOF or error
+ *                Otherwise, returns buf.
+ *
+ *********************************************************************/
+char *read_config_line(char *buf, size_t buflen, FILE *fp, unsigned long *linenum)
+{
+   jb_err err;
+   char *buf2 = NULL;
+   err = edit_read_line(fp, NULL, NULL, &buf2, NULL, linenum);
+   if (err)
    {
-      current_blockfile->unloader = unload_blockfile;
+      if (err == JB_ERR_MEMORY)
+      {
+         log_error(LOG_LEVEL_FATAL, "Out of memory loading a config file");
+      }
+      return NULL;
    }
-
-   fs->next    = files->next;
-   files->next = fs;
-   current_blockfile = fs;
-
-   if (csp)
+   else
    {
-      csp->blist = fs;
+      assert(buf2);
+      assert(strlen(buf2) + 1U < buflen);
+      strncpy(buf, buf2, buflen - 1);
+      free(buf2);
+      buf[buflen - 1] = '\0';
+      return buf;
    }
-
-   return(0);
-
-load_blockfile_error:
-   log_error(LOG_LEVEL_ERROR, "can't load blockfile '%s': %E", blockfile);
-   return(-1);
-
 }
 
 
-#ifdef USE_IMAGE_LIST
+#ifdef FEATURE_TRUST
 /*********************************************************************
  *
- * Function    :  load_imagefile
+ * Function    :  unload_trustfile
  *
- * Description :  Read and parse an imagefile and add to files list.
+ * Description :  Unloads a trustfile.
  *
  * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  f = the data structure associated with the trustfile.
  *
- * Returns     :  0 => Ok, everything else is an error.
+ * Returns     :  N/A
  *
  *********************************************************************/
-int load_imagefile(struct client_state *csp)
+static void unload_trustfile(void *f)
 {
-   FILE *fp;
-
-   struct block_spec *b, *bl;
-   char  buf[BUFSIZ], *p, *q;
-   int port, reject;
-   struct file_list *fs;
-   struct url_spec url[1];
+   struct block_spec *cur = (struct block_spec *)f;
+   struct block_spec *next;
 
-   if (!check_file_changed(current_imagefile, imagefile, &fs))
-   {
-      /* No need to load */
-      if (csp)
-      {
-         csp->ilist = current_imagefile;
-      }
-      return(0);
-   }
-   if (!fs)
+   while (cur != NULL)
    {
-      goto load_imagefile_error;
-   }
+      next = cur->next;
 
-   fs->f = bl = (struct block_spec *)zalloc(sizeof(*bl));
-   if (bl == NULL)
-   {
-      goto load_imagefile_error;
-   }
+      free_url_spec(cur->url);
+      free(cur);
 
-   if ((fp = fopen(imagefile, "r")) == NULL)
-   {
-      goto load_imagefile_error;
+      cur = next;
    }
 
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
-   {
-      reject = 1;
+}
 
-      if (*buf == '~')
-      {
-         reject = 0;
-         p = buf;
-         q = p+1;
-         while ((*p++ = *q++))
-         {
-            /* nop */
-         }
-      }
-
-      /* skip lines containing only ~ */
-      if (*buf == '\0')
-      {
-         continue;
-      }
-
-      /* allocate a new node */
-      if (((b = zalloc(sizeof(*b))) == NULL)
-#ifdef REGEX
-      || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
-#endif
-      )
-      {
-         fclose(fp);
-         goto load_imagefile_error;
-      }
-
-      /* add it to the list */
-      b->next  = bl->next;
-      bl->next = b;
-
-      /* save a copy of the orignal specification */
-      if ((b->url->spec = strdup(buf)) == NULL)
-      {
-         fclose(fp);
-         goto load_imagefile_error;
-      }
-
-      b->reject = reject;
-
-      if ((p = strchr(buf, '/')))
-      {
-         b->url->path    = strdup(p);
-         b->url->pathlen = strlen(b->url->path);
-         *p = '\0';
-      }
-      else
-      {
-         b->url->path    = NULL;
-         b->url->pathlen = 0;
-      }
-#ifdef REGEX
-      if (b->url->path)
-      {
-         int errcode;
-         char rebuf[BUFSIZ];
-
-         sprintf(rebuf, "^(%s)", b->url->path);
-
-         errcode = regcomp(b->url->preg, rebuf,
-               (REG_EXTENDED|REG_NOSUB|REG_ICASE));
-
-         if (errcode)
-         {
-            size_t errlen =
-               regerror(errcode,
-                  b->url->preg, buf, sizeof(buf));
-
-            buf[errlen] = '\0';
-
-            log_error(LOG_LEVEL_ERROR, "error compiling %s: %s",
-                    b->url->spec, buf);
-            fclose(fp);
-            goto load_imagefile_error;
-         }
-      }
-      else
-      {
-         freez(b->url->preg);
-      }
-#endif
-      if ((p = strchr(buf, ':')) == NULL)
-      {
-         port = 0;
-      }
-      else
-      {
-         *p++ = '\0';
-         port = atoi(p);
-      }
-
-      b->url->port = port;
-
-      if ((b->url->domain = strdup(buf)) == NULL)
-      {
-         fclose(fp);
-         goto load_imagefile_error;
-      }
-
-      /* split domain into components */
-      *url = dsplit(b->url->domain);
-      b->url->dbuf = url->dbuf;
-      b->url->dcnt = url->dcnt;
-      b->url->dvec = url->dvec;
-   }
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-   fclose(fp);
-
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-   /* the old one is now obsolete */
-   if (current_imagefile)
-   {
-      current_imagefile->unloader = unload_imagefile;
-   }
-
-   fs->next    = files->next;
-   files->next = fs;
-   current_imagefile = fs;
-
-   if (csp)
-   {
-      csp->ilist = fs;
-   }
-
-   return(0);
-
-load_imagefile_error:
-   log_error(LOG_LEVEL_ERROR, "can't load imagefile '%s': %E", imagefile);
-   return(-1);
-
-}
-#endif /* def USE_IMAGE_LIST */
-
-
-/*********************************************************************
- *
- * Function    :  load_cookiefile
- *
- * Description :  Read and parse a cookiefile and add to files list.
- *
- * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
- *
- * Returns     :  0 => Ok, everything else is an error.
- *
- *********************************************************************/
-int load_cookiefile(struct client_state *csp)
-{
-   FILE *fp;
-
-   struct cookie_spec *b, *bl;
-   char  buf[BUFSIZ], *p, *q;
-   int port, user_cookie, server_cookie;
-   struct file_list *fs;
-   struct url_spec url[1];
-
-   if (!check_file_changed(current_cookiefile, cookiefile, &fs))
-   {
-      /* No need to load */
-      if (csp)
-      {
-         csp->clist = current_cookiefile;
-      }
-      return(0);
-   }
-   if (!fs)
-   {
-      goto load_cookie_error;
-   }
-
-   fs->f = bl = (struct cookie_spec   *)zalloc(sizeof(*bl));
-   if (bl == NULL)
-   {
-      goto load_cookie_error;
-   }
-
-   if ((fp = fopen(cookiefile, "r")) == NULL)
-   {
-      goto load_cookie_error;
-   }
-
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
-   {
-      p = buf;
-
-      switch ((int)*p)
-      {
-         case '>':
-            server_cookie = 0;
-            user_cookie   = 1;
-            p++;
-            break;
-
-         case '<':
-            server_cookie = 1;
-            user_cookie   = 0;
-            p++;
-            break;
-
-         case '~':
-            server_cookie = 0;
-            user_cookie   = 0;
-            p++;
-            break;
-
-         default:
-            server_cookie = 1;
-            user_cookie   = 1;
-            break;
-      }
-
-      /*
-       * Elide any of the "special" chars from the
-       * front of the pattern
-       */
-      q = buf;
-      if (p > q) while ((*q++ = *p++))
-      {
-         /* nop */
-      }
-
-      /* skip lines containing only "special" chars */
-      if (*buf == '\0')
-      {
-         continue;
-      }
-
-      /* allocate a new node */
-      if (((b = zalloc(sizeof(*b))) == NULL)
-#ifdef REGEX
-      || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
-#endif
-      )
-      {
-         fclose(fp);
-         goto load_cookie_error;
-      }
-
-      /* add it to the list */
-      b->next  = bl->next;
-      bl->next = b;
-
-      /* save a copy of the orignal specification */
-      if ((b->url->spec = strdup(buf)) == NULL)
-      {
-         fclose(fp);
-         goto load_cookie_error;
-      }
-
-      b->send_user_cookie     = user_cookie;
-      b->accept_server_cookie = server_cookie;
-
-      if ((p = strchr(buf, '/')))
-      {
-         b->url->path    = strdup(p);
-         b->url->pathlen = strlen(b->url->path);
-         *p = '\0';
-      }
-      else
-      {
-         b->url->path    = NULL;
-         b->url->pathlen = 0;
-      }
-#ifdef REGEX
-      if (b->url->path)
-      {
-         int errcode;
-         char rebuf[BUFSIZ];
-
-         sprintf(rebuf, "^(%s)", b->url->path);
-
-         errcode = regcomp(b->url->preg, rebuf,
-               (REG_EXTENDED|REG_NOSUB|REG_ICASE));
-         if (errcode)
-         {
-            size_t errlen =
-               regerror(errcode,
-                  b->url->preg, buf, sizeof(buf));
-
-            buf[errlen] = '\0';
-
-            log_error(LOG_LEVEL_ERROR, "error compiling %s: %s",
-                    b->url->spec, buf);
-            fclose(fp);
-            goto load_cookie_error;
-         }
-      }
-      else
-      {
-         freez(b->url->preg);
-      }
-#endif
-      if ((p = strchr(buf, ':')) == NULL)
-      {
-         port = 0;
-      }
-      else
-      {
-         *p++ = '\0';
-         port = atoi(p);
-      }
-
-      b->url->port = port;
-
-      if ((b->url->domain = strdup(buf)) == NULL)
-      {
-         fclose(fp);
-         goto load_cookie_error;
-      }
-
-      /* split domain into components */
-
-      *url = dsplit(b->url->domain);
-      b->url->dbuf = url->dbuf;
-      b->url->dcnt = url->dcnt;
-      b->url->dvec = url->dvec;
-   }
-
-   fclose(fp);
-
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-   /* the old one is now obsolete */
-   if (current_cookiefile)
-   {
-      current_cookiefile->unloader = unload_cookiefile;
-   }
-
-   fs->next    = files->next;
-   files->next = fs;
-   current_cookiefile = fs;
-
-   if (csp)
-   {
-      csp->clist = fs;
-   }
-
-   return(0);
-
-load_cookie_error:
-   log_error(LOG_LEVEL_ERROR, "can't load cookiefile '%s': %E", cookiefile);
-   return(-1);
-
-}
 
-
-#ifdef TRUST_FILES
+#ifdef FEATURE_GRACEFUL_TERMINATION
 /*********************************************************************
  *
- * Function    :  load_trustfile
+ * Function    :  unload_current_trust_file
  *
- * Description :  Read and parse a trustfile and add to files list.
+ * Description :  Unloads current trust file - reset to state at
+ *                beginning of program.
  *
- * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
+ * Parameters  :  None
  *
- * Returns     :  0 => Ok, everything else is an error.
+ * Returns     :  N/A
  *
- *********************************************************************/
-int load_trustfile(struct client_state *csp)
-{
-   FILE *fp;
-
-   struct block_spec *b, *bl;
-   struct url_spec **tl;
-
-   char  buf[BUFSIZ], *p, *q;
-   int port, reject, trusted;
-   struct file_list *fs;
-   struct url_spec url[1];
-
-   if (!check_file_changed(current_trustfile, trustfile, &fs))
-   {
-      /* No need to load */
-      if (csp)
-      {
-         csp->tlist = current_trustfile;
-      }
-      return(0);
-   }
-   if (!fs)
-   {
-      goto load_trustfile_error;
-   }
-
-   fs->f = bl = (struct block_spec *)zalloc(sizeof(*bl));
-   if (bl == NULL)
-   {
-      goto load_trustfile_error;
-   }
-
-   if ((fp = fopen(trustfile, "r")) == NULL)
-   {
-      goto load_trustfile_error;
-   }
-
-   tl = trust_list;
-
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
-   {
-      trusted = 0;
-      reject  = 1;
-
-      if (*buf == '+')
-      {
-         trusted = 1;
-         *buf = '~';
-      }
-
-      if (*buf == '~')
-      {
-         reject = 0;
-         p = buf;
-         q = p+1;
-         while ((*p++ = *q++))
-         {
-            /* nop */
-         }
-      }
-
-      /* skip blank lines */
-      if (*buf == '\0')
-      {
-         continue;
-      }
-
-      /* allocate a new node */
-      if (((b = zalloc(sizeof(*b))) == NULL)
-#ifdef REGEX
-      || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
-#endif
-      )
-      {
-         fclose(fp);
-         goto load_trustfile_error;
-      }
-
-      /* add it to the list */
-      b->next  = bl->next;
-      bl->next = b;
-
-      /* save a copy of the orignal specification */
-      if ((b->url->spec = strdup(buf)) == NULL)
-      {
-         fclose(fp);
-         goto load_trustfile_error;
-      }
-
-      b->reject = reject;
-
-      if ((p = strchr(buf, '/')))
-      {
-         b->url->path    = strdup(p);
-         b->url->pathlen = strlen(b->url->path);
-         *p = '\0';
-      }
-      else
-      {
-         b->url->path    = NULL;
-         b->url->pathlen = 0;
-      }
-#ifdef REGEX
-      if (b->url->path)
-      {
-         int errcode;
-         char rebuf[BUFSIZ];
-
-         sprintf(rebuf, "^(%s)", b->url->path);
-
-         errcode = regcomp(b->url->preg, rebuf,
-               (REG_EXTENDED|REG_NOSUB|REG_ICASE));
-
-         if (errcode)
-         {
-            size_t errlen =
-               regerror(errcode,
-                  b->url->preg, buf, sizeof(buf));
-
-            buf[errlen] = '\0';
-
-            log_error(LOG_LEVEL_ERROR, "error compiling %s: %s",
-                    b->url->spec, buf);
-            fclose(fp);
-            goto load_trustfile_error;
-         }
-      }
-      else
-      {
-         freez(b->url->preg);
-      }
-#endif
-      if ((p = strchr(buf, ':')) == NULL)
-      {
-         port = 0;
-      }
-      else
-      {
-         *p++ = '\0';
-         port = atoi(p);
-      }
-
-      b->url->port = port;
-
-      if ((b->url->domain = strdup(buf)) == NULL)
-      {
-         fclose(fp);
-         goto load_trustfile_error;
-      }
-
-      /* split domain into components */
-      *url = dsplit(b->url->domain);
-      b->url->dbuf = url->dbuf;
-      b->url->dcnt = url->dcnt;
-      b->url->dvec = url->dvec;
-
-      /*
-       * save a pointer to URL's spec in the list of trusted URL's, too
-       */
-      if (trusted)
-      {
-         *tl++ = b->url;
-      }
-   }
-
-   *tl = NULL;
-
-   fclose(fp);
-
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-   /* the old one is now obsolete */
+ *********************************************************************/
+void unload_current_trust_file(void)
+{
    if (current_trustfile)
    {
       current_trustfile->unloader = unload_trustfile;
+      current_trustfile = NULL;
    }
-
-   fs->next    = files->next;
-   files->next = fs;
-   current_trustfile = fs;
-
-   if (csp)
-   {
-      csp->tlist = fs;
-   }
-
-   return(0);
-
-load_trustfile_error:
-   log_error(LOG_LEVEL_ERROR, "can't load trustfile '%s': %E", trustfile);
-   return(-1);
-
 }
-#endif /* def TRUST_FILES */
+#endif /* FEATURE_GRACEFUL_TERMINATION */
 
 
 /*********************************************************************
  *
- * Function    :  load_forwardfile
+ * Function    :  load_trustfile
  *
- * Description :  Read and parse a forwardfile and add to files list.
+ * Description :  Read and parse a trustfile and add to files list.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
@@ -1681,490 +1026,350 @@ load_trustfile_error:
  * Returns     :  0 => Ok, everything else is an error.
  *
  *********************************************************************/
-int load_forwardfile(struct client_state *csp)
+int load_trustfile(struct client_state *csp)
 {
    FILE *fp;
 
-   struct forward_spec *b, *bl;
-   char  buf[BUFSIZ], *p, *q, *tmp;
-   char  *vec[4];
-   int port, n, reject;
+   struct block_spec *b, *bl;
+   struct url_spec **tl;
+
+   char  buf[BUFFER_SIZE], *p, *q;
+   int reject, trusted;
    struct file_list *fs;
-   const struct gateway *gw;
-   struct url_spec url[1];
+   unsigned long linenum = 0;
 
-   if (!check_file_changed(current_forwardfile, forwardfile, &fs))
+   if (!check_file_changed(current_trustfile, csp->config->trustfile, &fs))
    {
       /* No need to load */
       if (csp)
       {
-         csp->flist = current_forwardfile;
+         csp->tlist = current_trustfile;
       }
       return(0);
    }
    if (!fs)
    {
-      goto load_forwardfile_error;
+      goto load_trustfile_error;
    }
 
-   fs->f = bl = (struct forward_spec  *)zalloc(sizeof(*bl));
-
-   if ((fs == NULL) || (bl == NULL))
+   fs->f = bl = (struct block_spec *)zalloc(sizeof(*bl));
+   if (bl == NULL)
    {
-      goto load_forwardfile_error;
+      goto load_trustfile_error;
    }
 
-   if ((fp = fopen(forwardfile, "r")) == NULL)
+   if ((fp = fopen(csp->config->trustfile, "r")) == NULL)
    {
-      goto load_forwardfile_error;
+      goto load_trustfile_error;
    }
 
-   tmp = NULL;
+   tl = csp->config->trust_list;
 
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
+   while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
    {
-      freez(tmp);
-
-      tmp = strdup(buf);
-
-      n = ssplit(tmp, " \t", vec, SZ(vec), 1, 1);
+      trusted = 0;
+      reject  = 1;
 
-      if (n != 4)
+      if (*buf == '+')
       {
-         log_error(LOG_LEVEL_ERROR, "error in forwardfile: %s", buf);
-         continue;
+         trusted = 1;
+         *buf = '~';
       }
 
-      strcpy(buf, vec[0]);
-
-      reject = 1;
-
       if (*buf == '~')
       {
          reject = 0;
          p = buf;
          q = p+1;
-         while ((*p++ = *q++))
+         while ((*p++ = *q++) != '\0')
          {
             /* nop */
          }
       }
 
-      /* skip lines containing only ~ */
+      /* skip blank lines */
       if (*buf == '\0')
       {
          continue;
       }
 
       /* allocate a new node */
-      if (((b = zalloc(sizeof(*b))) == NULL)
-#ifdef REGEX
-      || ((b->url->preg = zalloc(sizeof(*b->url->preg))) == NULL)
-#endif
-      )
+      if ((b = zalloc(sizeof(*b))) == NULL)
       {
          fclose(fp);
-         goto load_forwardfile_error;
+         goto load_trustfile_error;
       }
 
       /* add it to the list */
       b->next  = bl->next;
       bl->next = b;
 
-      /* save a copy of the orignal specification */
-      if ((b->url->spec = strdup(buf)) == NULL)
-      {
-         fclose(fp);
-         goto load_forwardfile_error;
-      }
-
       b->reject = reject;
 
-      if ((p = strchr(buf, '/')))
-      {
-         b->url->path    = strdup(p);
-         b->url->pathlen = strlen(b->url->path);
-         *p = '\0';
-      }
-      else
-      {
-         b->url->path    = NULL;
-         b->url->pathlen = 0;
-      }
-#ifdef REGEX
-      if (b->url->path)
-      {
-         int errcode;
-         char rebuf[BUFSIZ];
-
-         sprintf(rebuf, "^(%s)", b->url->path);
-
-         errcode = regcomp(b->url->preg, rebuf,
-               (REG_EXTENDED|REG_NOSUB|REG_ICASE));
-
-         if (errcode)
-         {
-            size_t errlen = regerror(errcode, b->url->preg, buf, sizeof(buf));
-
-            buf[errlen] = '\0';
-
-            log_error(LOG_LEVEL_ERROR, "error compiling %s: %s",
-                    b->url->spec, buf);
-            fclose(fp);
-            goto load_forwardfile_error;
-         }
-      }
-      else
-      {
-         freez(b->url->preg);
-      }
-#endif
-      if ((p = strchr(buf, ':')) == NULL)
-      {
-         port = 0;
-      }
-      else
-      {
-         *p++ = '\0';
-         port = atoi(p);
-      }
-
-      b->url->port = port;
-
-      if ((b->url->domain = strdup(buf)) == NULL)
+      /* Save the URL pattern */
+      if (create_url_spec(b->url, buf))
       {
          fclose(fp);
-         goto load_forwardfile_error;
-      }
-
-      /* split domain into components */
-      *url = dsplit(b->url->domain);
-      b->url->dbuf = url->dbuf;
-      b->url->dcnt = url->dcnt;
-      b->url->dvec = url->dvec;
-
-      /* now parse the gateway specs */
-
-      p = vec[2];
-
-      for (gw = gateways; gw->name; gw++)
-      {
-         if (strcmp(gw->name, p) == 0)
-         {
-            break;
-         }
-      }
-
-      if (gw->name == NULL)
-      {
-         goto load_forwardfile_error;
-      }
-
-      /* save this as the gateway type */
-      *b->gw = *gw;
-
-      /* now parse the gateway host[:port] spec */
-      p = vec[3];
-
-      if (strcmp(p, ".") != 0)
-      {
-         b->gw->gateway_host = strdup(p);
-
-         if ((p = strchr(b->gw->gateway_host, ':')))
-         {
-            *p++ = '\0';
-            b->gw->gateway_port = atoi(p);
-         }
-
-         if (b->gw->gateway_port <= 0)
-         {
-            goto load_forwardfile_error;
-         }
+         goto load_trustfile_error;
       }
 
-      /* now parse the forwarding spec */
-      p = vec[1];
-
-      if (strcmp(p, ".") != 0)
+      /*
+       * save a pointer to URL's spec in the list of trusted URL's, too
+       */
+      if (trusted)
       {
-         b->gw->forward_host = strdup(p);
-
-         if ((p = strchr(b->gw->forward_host, ':')))
-         {
-            *p++ = '\0';
-            b->gw->forward_port = atoi(p);
-         }
-
-         if (b->gw->forward_port <= 0)
-         {
-            b->gw->forward_port = 8000;
-         }
+         *tl++ = b->url;
+         /* FIXME BUFFER OVERFLOW if >=64 entries */
       }
    }
 
-   freez(tmp);
+   *tl = NULL;
 
    fclose(fp);
 
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
-
    /* the old one is now obsolete */
-   if (current_forwardfile)
+   if (current_trustfile)
    {
-      current_forwardfile->unloader = unload_forwardfile;
+      current_trustfile->unloader = unload_trustfile;
    }
 
    fs->next    = files->next;
    files->next = fs;
-   current_forwardfile = fs;
+   current_trustfile = fs;
 
    if (csp)
    {
-      csp->flist = fs;
+      csp->tlist = fs;
    }
 
    return(0);
 
-load_forwardfile_error:
-   log_error(LOG_LEVEL_ERROR, "can't load forwardfile '%s': %E", forwardfile);
+load_trustfile_error:
+   log_error(LOG_LEVEL_FATAL, "can't load trustfile '%s': %E",
+             csp->config->trustfile);
    return(-1);
 
 }
+#endif /* def FEATURE_TRUST */
 
 
-#ifdef PCRS
 /*********************************************************************
  *
- * Function    :  load_re_filterfile
+ * Function    :  unload_re_filterfile
  *
- * Description :  Load the re_filterfile. Each non-comment, non-empty
- *                line is instantly added to the joblist, which is
- *                a chained list of pcrs_job structs.
+ * Description :  Unload the re_filter list by freeing all chained
+ *                re_filterfile specs and their data.
  *
  * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  f = the data structure associated with the filterfile.
  *
- * Returns     :  0 => Ok, everything else is an error.
+ * Returns     :  N/A
  *
  *********************************************************************/
-int load_re_filterfile(struct client_state *csp)
+static void unload_re_filterfile(void *f)
 {
-   FILE *fp;
-
-   struct re_filterfile_spec *bl;
-   struct file_list *fs;
+   struct re_filterfile_spec *a, *b = (struct re_filterfile_spec *)f;
 
-   char  buf[BUFSIZ];
-   int error;
-   pcrs_job *dummy;
-
-#ifndef SPLIT_PROXY_ARGS
-   char *p;
-#endif /* ndef SPLIT_PROXY_ARGS */
-   if (!check_file_changed(current_re_filterfile, re_filterfile, &fs))
-   {
-      /* No need to load */
-      if (csp)
-      {
-         csp->rlist = current_re_filterfile;
-      }
-      return(0);
-   }
-   if (!fs)
-   {
-      goto load_re_filterfile_error;
-   }
-
-   fs->f = bl = (struct re_filterfile_spec  *)zalloc(sizeof(*bl));
-   if (bl == NULL)
-   {
-      goto load_re_filterfile_error;
-   }
-
-   /* Open the file or fail */
-   if ((fp = fopen(re_filterfile, "r")) == NULL)
+   while (b != NULL)
    {
-      goto load_re_filterfile_error;
-   }
+      a = b->next;
 
-   /* Read line by line */
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
-   {
-      enlist( bl->patterns, buf );
+      destroy_list(b->patterns);
+      pcrs_free_joblist(b->joblist);
+      freez(b->name);
+      freez(b->description);
+      freez(b);
 
-      /* We have a meaningful line -> make it a job */
-      if ((dummy = pcrs_make_job(buf, &error)) == NULL)
-      {
-         log_error(LOG_LEVEL_REF, 
-               "Adding re_filter job %s failed with error %d.", buf, error);
-         continue;
-      }
-      else
-      {
-         dummy->next = bl->joblist;
-         bl->joblist = dummy;
-         log_error(LOG_LEVEL_REF, "Adding re_filter job %s succeeded.", buf);
-      }
+      b = a;
    }
 
-   fclose(fp);
+   return;
+}
 
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
 
-   /* the old one is now obsolete */
-   if ( NULL != current_re_filterfile )
+#ifdef FEATURE_GRACEFUL_TERMINATION
+/*********************************************************************
+ *
+ * Function    :  unload_current_re_filterfile
+ *
+ * Description :  Unloads current re_filter file - reset to state at
+ *                beginning of program.
+ *
+ * Parameters  :  None
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void unload_current_re_filterfile(void)
+{
+   if (current_re_filterfile)
    {
       current_re_filterfile->unloader = unload_re_filterfile;
+      current_re_filterfile = NULL;
    }
-
-   fs->next    = files->next;
-   files->next = fs;
-   current_re_filterfile = fs;
-
-   if (csp)
-   {
-      csp->rlist = fs;
-   }
-
-   return( 0 );
-
-load_re_filterfile_error:
-   log_error(LOG_LEVEL_ERROR, "can't load re_filterfile '%s': %E", re_filterfile);
-   return(-1);
-
 }
-#endif /* def PCRS */
+#endif
 
 
-#ifdef KILLPOPUPS
 /*********************************************************************
  *
- * Function    :  load_popupfile
+ * Function    :  load_re_filterfile
  *
- * Description :  Load, and parse the popup blocklist.
+ * Description :  Load the re_filterfile. 
+ *                Generate a chained list of re_filterfile_spec's from
+ *                the "FILTER: " blocks, compiling all their substitutions
+ *                into chained lists of pcrs_job structs.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  0 => success, else there was an error.
+ * Returns     :  0 => Ok, everything else is an error.
  *
  *********************************************************************/
-int load_popupfile(struct client_state *csp)
+int load_re_filterfile(struct client_state *csp)
 {
    FILE *fp;
-   char  buf[BUFSIZ], *p, *q;
-   struct popup_blocklist *entry = NULL;
-   struct popup_settings * data;
+
+   struct re_filterfile_spec *new_bl, *bl = NULL;
    struct file_list *fs;
-   p = buf;
-   q = buf;
 
-   if (!check_file_changed(current_popupfile, popupfile, &fs))
+   char  buf[BUFFER_SIZE];
+   int error;
+   unsigned long linenum = 0;
+   pcrs_job *dummy;
+
+   /*
+    * No need to reload if unchanged
+    */
+   if (!check_file_changed(current_re_filterfile, csp->config->re_filterfile, &fs))
    {
-      /* No need to load */
       if (csp)
       {
-         csp->plist = current_popupfile;
+         csp->rlist = current_re_filterfile;
       }
       return(0);
    }
    if (!fs)
    {
-      goto load_popupfile_error;
-   }
-
-   fs->f = data = (struct popup_settings  *)zalloc(sizeof(*data));
-   if (data == NULL)
-   {
-      goto load_popupfile_error;
+      goto load_re_filterfile_error;
    }
 
-   if ((fp = fopen(popupfile, "r")) == NULL)
+   /* 
+    * Open the file or fail
+    */
+   if ((fp = fopen(csp->config->re_filterfile, "r")) == NULL)
    {
-      goto load_popupfile_error;
+      goto load_re_filterfile_error;
    }
 
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
+   /* 
+    * Read line by line
+    */
+   while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
    {
-      entry = (struct popup_blocklist*)zalloc(sizeof(struct popup_blocklist));
-      if (!entry)
+      /*
+       * If this is the head of a new filter block, make it a
+       * re_filterfile spec of its own and chain it to the list:
+       */
+      if (strncmp(buf, "FILTER:", 7) == 0)
       {
-         fclose( fp );
-         goto load_popupfile_error;
-      }
+         new_bl = (struct re_filterfile_spec  *)zalloc(sizeof(*bl));
+         if (new_bl == NULL)
+         {
+            goto load_re_filterfile_error;
+         }
 
-      /* Handle allowed hosts. */
-      if ( *buf == '~' )
-      {
-         /* Rememeber: skip the tilde */
-         entry->host_name = strdup( buf + 1 );
-         if (!entry->host_name)
+         new_bl->name = chomp(buf + 7);
+
+         if (NULL != (new_bl->description = strchr(new_bl->name, ' ')))
          {
-            fclose( fp );
-            goto load_popupfile_error;
+            *new_bl->description++ = '\0';
+            new_bl->description = strdup(chomp(new_bl->description));
+         }
+         else
+         {
+            new_bl->description = strdup("No description available for this filter");
          }
 
-         entry->next = data->allowed;
-         data->allowed = entry;
-      }
-      else
-      {
-         /* Blocked host */
-         entry->host_name = strdup( buf );
-         if (!entry->host_name)
+         new_bl->name = strdup(chomp(new_bl->name));
+         
+         /*
+          * If this is the first filter block, chain it
+          * to the file_list rather than its (nonexistant)
+          * predecessor
+          */
+         if (fs->f == NULL)
+         {
+            fs->f = new_bl;
+         }
+         else
          {
-            fclose( fp );
-            goto load_popupfile_error;
+            bl->next = new_bl;
          }
+         bl = new_bl;
+
+         log_error(LOG_LEVEL_RE_FILTER, "Reading in filter \"%s\" (\"%s\")", bl->name, bl->description);
 
-         entry->next = data->blocked;
-         data->blocked = entry;
+         continue;
       }
-   }
 
-   fclose( fp );
+      /* 
+       * Else, save the expression, make it a pcrs_job
+       * and chain it into the current filter's joblist 
+       */
+      if (bl != NULL)
+      {
+         enlist(bl->patterns, buf);
 
-#ifndef SPLIT_PROXY_ARGS
-   if (!suppress_blocklists)
-   {
-      fs->proxy_args = strsav(fs->proxy_args, "</pre>");
+         if ((dummy = pcrs_compile_command(buf, &error)) == NULL)
+         {
+            log_error(LOG_LEVEL_RE_FILTER,
+                      "Adding re_filter job %s to filter %s failed with error %d.", buf, bl->name, error);
+            continue;
+         }
+         else
+         {
+            dummy->next = bl->joblist;
+            bl->joblist = dummy;
+            log_error(LOG_LEVEL_RE_FILTER, "Adding re_filter job %s to filter %s succeeded.", buf, bl->name);
+         }
+      }
+      else
+      {
+         log_error(LOG_LEVEL_ERROR, "Ignoring job %s outside filter block in %s, line %d", buf, csp->config->re_filterfile, linenum);
+      }
    }
-#endif /* ndef SPLIT_PROXY_ARGS */
 
-   /* the old one is now obsolete */
-   if ( NULL != current_popupfile )
+   fclose(fp);
+
+   /* 
+    * Schedule the now-obsolete old data for unloading
+    */
+   if ( NULL != current_re_filterfile )
    {
-      current_popupfile->unloader = unload_popupfile;
+      current_re_filterfile->unloader = unload_re_filterfile;
    }
 
+   /*
+    * Chain this file into the global list of loaded files
+    */
    fs->next    = files->next;
    files->next = fs;
-   current_popupfile = fs;
+   current_re_filterfile = fs;
 
    if (csp)
    {
-      csp->plist = fs;
+      csp->rlist = fs;
    }
 
    return( 0 );
 
-load_popupfile_error:
-   log_error(LOG_LEVEL_ERROR, "can't load popupfile '%s': %E", popupfile);
+load_re_filterfile_error:
+   log_error(LOG_LEVEL_FATAL, "can't load re_filterfile '%s': %E",
+             csp->config->re_filterfile);
    return(-1);
 
 }
-#endif /* def KILLPOPUPS */
-
 
 
 /*********************************************************************
@@ -2177,19 +1382,21 @@ load_popupfile_error:
  * Parameters  :
  *          1  :  loader = pointer to a function that can parse and load
  *                the appropriate config file.
+ *          2  :  config = The configuration_spec to add the loader to.
  *
  * Returns     :  N/A
  *
  *********************************************************************/
-void add_loader(int (*loader)(struct client_state *))
+void add_loader(int (*loader)(struct client_state *),
+                struct configuration_spec * config)
 {
    int i;
 
    for (i=0; i < NLOADERS; i++)
    {
-      if (loaders[i] == NULL)
+      if (config->loaders[i] == NULL)
       {
-         loaders[i] = loader;
+         config->loaders[i] = loader;
          break;
       }
    }
@@ -2208,6 +1415,8 @@ void add_loader(int (*loader)(struct client_state *))
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
+ *                      Must be non-null.  Reads: "csp->config"
+ *                      Writes: various data members.
  *
  * Returns     :  0 => Ok, everything else is an error.
  *
@@ -2219,34 +1428,17 @@ int run_loader(struct client_state *csp)
 
    for (i=0; i < NLOADERS; i++)
    {
-      if (loaders[i] == NULL)
+      if (csp->config->loaders[i] == NULL)
       {
          break;
       }
-      ret |= (loaders[i])(csp);
+      ret |= (csp->config->loaders[i])(csp);
    }
    return(ret);
 
 }
 
 
-/*********************************************************************
- *
- * Function    :  remove_all_loaders
- *
- * Description :  Remove all loaders from the list.
- *
- * Parameters  :  N/A
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-void remove_all_loaders(void)
-{
-   memset( loaders, 0, sizeof( loaders ) );
-}
-
-
 /*
   Local Variables:
   tab-width: 3
index 0551a6e..216c352 100644 (file)
--- a/loaders.h
+++ b/loaders.h
@@ -1,9 +1,9 @@
-#ifndef _LOADERS_H
-#define _LOADERS_H
-#define LOADERS_H_VERSION "$Id: loaders.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef LOADERS_H_INCLUDED
+#define LOADERS_H_INCLUDED
+#define LOADERS_H_VERSION "$Id: loaders.h,v 1.18 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/loaders.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/loaders.h,v $
  *
  * Purpose     :  Functions to load and unload the various
  *                configuration files.  Also contains code to manage
@@ -11,7 +11,7 @@
  *                unload files that are no longer in use.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: loaders.h,v $
+ *    Revision 1.18  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.17  2002/03/16 23:54:06  jongfoster
+ *    Adding graceful termination feature, to help look for memory leaks.
+ *    If you enable this (which, by design, has to be done by hand
+ *    editing config.h) and then go to http://i.j.b/die, then the program
+ *    will exit cleanly after the *next* request.  It should free all the
+ *    memory that was used.
+ *
+ *    Revision 1.16  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.15  2002/01/22 23:46:18  jongfoster
+ *    Moving edit_read_line() and simple_read_line() to loaders.c, and
+ *    extending them to support reading MS-DOS, Mac and UNIX style files
+ *    on all platforms.
+ *
+ *    Modifying read_config_line() (without changing it's prototype) to
+ *    be a trivial wrapper for edit_read_line().  This means that we have
+ *    one function to read a line and handle comments, which is common
+ *    between the initialization code and the edit interface.
+ *
+ *    Revision 1.14  2002/01/17 21:03:08  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Renaming free_url to free_url_spec, since it frees a struct url_spec.
+ *
+ *    Revision 1.13  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.12  2001/11/07 00:02:13  steudten
+ *    Add line number in error output for lineparsing for
+ *    actionsfile and configfile.
+ *    Special handling for CLF added.
+ *
+ *    Revision 1.11  2001/10/23 21:38:53  jongfoster
+ *    Adding error-checking to create_url_spec()
+ *
+ *    Revision 1.10  2001/09/22 16:36:59  jongfoster
+ *    Removing unused parameter fs from read_config_line()
+ *
+ *    Revision 1.9  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.8  2001/07/29 18:58:15  jongfoster
+ *    Removing nested #includes, adding forward declarations for needed
+ *    structures, and changing the #define _FILENAME_H to FILENAME_H_INCLUDED.
+ *
+ *    Revision 1.7  2001/07/13 14:01:54  oes
+ *    Removed all #ifdef PCRS
+ *
+ *    Revision 1.6  2001/06/07 23:14:38  jongfoster
+ *    Removing ACL and forward file loaders - these files have
+ *    been merged into the config file.
+ *
+ *    Revision 1.5  2001/05/31 21:28:49  jongfoster
+ *    Removed all permissionsfile code - it's now called the actions
+ *    file, and (almost) all the code is in actions.c
+ *
+ *    Revision 1.4  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.3  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:00  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
-#include "project.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* Structures taken from project.h */
+struct client_state;
+struct file_list;
+struct configuration_spec;
+struct url_spec;
+
 extern void sweep(void);
-extern char *read_config_line(char *buf, int buflen, FILE *fp, struct file_list *fs);
-
-extern int load_blockfile(struct client_state *csp);
-extern int load_cookiefile(struct client_state *csp);
-extern int load_forwardfile(struct client_state *csp);
-  
-#ifdef ACL_FILES
-extern int load_aclfile(struct client_state *csp);
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-extern int load_imagefile(struct client_state *csp);
-#endif /* def USE_IMAGE_LIST */
-#ifdef KILLPOPUPS
-extern int load_popupfile(struct client_state *csp);
-#endif /* def KILLPOPUPS */
-
-#ifdef TRUST_FILES
-extern int load_trustfile(struct client_state *csp);
-#endif /* def TRUST_FILES */
+extern char *read_config_line(char *buf, size_t buflen, FILE *fp, unsigned long *linenum);
+extern int check_file_changed(const struct file_list * current,
+                              const char * filename,
+                              struct file_list ** newfl);
 
-#ifdef PCRS
-extern int load_re_filterfile(struct client_state *csp);
-#endif /* def PCRS */
+extern jb_err edit_read_line(FILE *fp,
+                             char **raw_out,
+                             char **prefix_out,
+                             char **data_out,
+                             int *newline,
+                             unsigned long *line_number);
 
-extern void add_loader(int (*loader)(struct client_state *));
-extern int run_loader(struct client_state *csp);
-extern void remove_all_loaders(void);
+extern jb_err simple_read_line(FILE *fp, char **dest, int *newline);
+
+/*
+ * Various types of newlines that a file may contain.
+ */
+#define NEWLINE_UNKNOWN 0  /* Newline convention in file is unknown */
+#define NEWLINE_UNIX    1  /* Newline convention in file is '\n'   (ASCII 10) */
+#define NEWLINE_DOS     2  /* Newline convention in file is '\r\n' (ASCII 13,10) */
+#define NEWLINE_MAC     3  /* Newline convention in file is '\r'   (ASCII 13) */
 
-#ifdef PCRS
+/*
+ * Types of newlines that a file may contain, as strings.  If you have an
+ * extremely wierd compiler that does not have '\r' == CR == ASCII 13 and
+ * '\n' == LF == ASCII 10), then fix CHAR_CR and CHAR_LF in loaders.c as
+ * well as these definitions.
+ */
+#define NEWLINE(style) ((style)==NEWLINE_DOS ? "\r\n" : \
+                        ((style)==NEWLINE_MAC ? "\r" : "\n"))
+
+
+extern short int MustReload;
+extern int load_actions_file(struct client_state *csp);
 extern int load_re_filterfile(struct client_state *csp);
-#endif /* def PCRS */
 
-#ifdef KILLPOPUPS
-extern int load_popupfile(struct client_state *csp);
-#endif /* def KILLPOPUPS */
+#ifdef FEATURE_TRUST
+extern int load_trustfile(struct client_state *csp);
+#endif /* def FEATURE_TRUST */
+
+#ifdef FEATURE_GRACEFUL_TERMINATION
+#ifdef FEATURE_TRUST
+void unload_current_trust_file(void);
+#endif
+void unload_current_re_filterfile(void);
+#endif /* FEATURE_GRACEFUL_TERMINATION */
+
+
+extern void add_loader(int (*loader)(struct client_state *), 
+                       struct configuration_spec * config);
+extern int run_loader(struct client_state *csp);
 
 /* Revision control strings from this header and associated .c file */
 extern const char loaders_rcs[];
@@ -94,7 +226,7 @@ extern const char loaders_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _LOADERS_H */
+#endif /* ndef LOADERS_H_INCLUDED */
 
 /*
   Local Variables:
index 1257a99..065cd5f 100644 (file)
@@ -1,15 +1,16 @@
-const char miscutil_rcs[] = "$Id: miscutil.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char miscutil_rcs[] = "$Id: miscutil.c,v 1.36 2002/04/26 12:55:38 oes Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/miscutil.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/miscutil.c,v $
  *
  * Purpose     :  zalloc, hash_string, safe_strerror, strcmpic,
- *                strncmpic, and MinGW32 strdup functions.  These are
- *                each too small to deserve their own file but don't 
- *                really fit in any other file.
+ *                strncmpic, chomp, and MinGW32 strdup
+ *                functions. 
+ *                These are each too small to deserve their own file
+ *                but don't really fit in any other file.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
@@ -35,6 +36,166 @@ const char miscutil_rcs[] = "$Id: miscutil.c,v 1.1 2001/05/13 21:57:06 administr
  *
  * Revisions   :
  *    $Log: miscutil.c,v $
+ *    Revision 1.36  2002/04/26 12:55:38  oes
+ *    New function string_toupper
+ *
+ *    Revision 1.35  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.34  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.33  2002/03/07 03:46:53  oes
+ *    Fixed compiler warnings etc
+ *
+ *    Revision 1.32  2002/03/06 23:02:57  jongfoster
+ *    Removing tabs
+ *
+ *    Revision 1.31  2002/03/05 04:52:42  oes
+ *    Deleted non-errlog debugging code
+ *
+ *    Revision 1.30  2002/03/04 18:27:42  oes
+ *    - Deleted deletePidFile
+ *    - Made write_pid_file use the --pidfile option value
+ *      (or no PID file, if the option was absent)
+ *    - Played styleguide police
+ *
+ *    Revision 1.29  2002/03/04 02:08:02  david__schmidt
+ *    Enable web editing of actions file on OS/2 (it had been broken all this time!)
+ *
+ *    Revision 1.28  2002/03/03 09:18:03  joergs
+ *    Made jumbjuster work on AmigaOS again.
+ *
+ *    Revision 1.27  2002/01/21 00:52:32  jongfoster
+ *    Adding string_join()
+ *
+ *    Revision 1.26  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.25  2001/11/13 00:16:38  jongfoster
+ *    Replacing references to malloc.h with the standard stdlib.h
+ *    (See ANSI or K&R 2nd Ed)
+ *
+ *    Revision 1.24  2001/11/05 21:41:43  steudten
+ *    Add changes to be a real daemon just for unix os.
+ *    (change cwd to /, detach from controlling tty, set
+ *    process group and session leader to the own process.
+ *    Add DBG() Macro.
+ *    Add some fatal-error log message for failed malloc().
+ *    Add '-d' if compiled with 'configure --with-debug' to
+ *    enable debug output.
+ *
+ *    Revision 1.23  2001/10/29 03:48:10  david__schmidt
+ *    OS/2 native needed a snprintf() routine.  Added one to miscutil, brackedted
+ *    by and __OS2__ ifdef.
+ *
+ *    Revision 1.22  2001/10/26 17:39:38  oes
+ *    Moved ijb_isspace and ijb_tolower to project.h
+ *
+ *    Revision 1.21  2001/10/23 21:27:50  jongfoster
+ *    Standardising error codes in string_append
+ *    make_path() no longer adds '\\' if the dir already ends in '\\' (this
+ *    is just copying a UNIX-specific fix to the Windows-specific part)
+ *
+ *    Revision 1.20  2001/10/22 15:33:56  david__schmidt
+ *    Special-cased OS/2 out of the Netscape-abort-on-404-in-js problem in
+ *    filters.c.  Added a FIXME in front of the offending code.  I'll gladly
+ *    put in a better/more robust fix for all parties if one is presented...
+ *    It seems that just returning 200 instead of 404 would pretty much fix
+ *    it for everyone, but I don't know all the history of the problem.
+ *
+ *    Revision 1.19  2001/10/14 22:02:57  jongfoster
+ *    New function string_append() which is like strsav(), but running
+ *    out of memory isn't automatically FATAL.
+ *
+ *    Revision 1.18  2001/09/20 13:33:43  steudten
+ *
+ *    change long to int as return value in hash_string(). Remember the wraparound
+ *    for int = long = sizeof(4) - thats maybe not what we want.
+ *
+ *    Revision 1.17  2001/09/13 20:51:29  jongfoster
+ *    Fixing potential problems with characters >=128 in simplematch()
+ *    This was also a compiler warning.
+ *
+ *    Revision 1.16  2001/09/10 10:56:59  oes
+ *    Silenced compiler warnings
+ *
+ *    Revision 1.15  2001/07/13 14:02:24  oes
+ *    Removed vim-settings
+ *
+ *    Revision 1.14  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.13  2001/06/29 13:32:14  oes
+ *    Removed logentry from cancelled commit
+ *
+ *    Revision 1.12  2001/06/09 10:55:28  jongfoster
+ *    Changing BUFSIZ ==> BUFFER_SIZE
+ *
+ *    Revision 1.11  2001/06/07 23:09:19  jongfoster
+ *    Cosmetic indentation changes.
+ *
+ *    Revision 1.10  2001/06/07 14:51:38  joergs
+ *    make_path() no longer adds '/' if the dir already ends in '/'.
+ *
+ *    Revision 1.9  2001/06/07 14:43:17  swa
+ *    slight mistake in make_path, unix path style is /.
+ *
+ *    Revision 1.8  2001/06/05 22:32:01  jongfoster
+ *    New function make_path() to splice directory and file names together.
+ *
+ *    Revision 1.7  2001/06/03 19:12:30  oes
+ *    introduced bindup()
+ *
+ *    Revision 1.6  2001/06/01 18:14:49  jongfoster
+ *    Changing the calls to strerr() to check HAVE_STRERR (which is defined
+ *    in config.h if appropriate) rather than the NO_STRERR macro.
+ *
+ *    Revision 1.5  2001/06/01 10:31:51  oes
+ *    Added character class matching to trivimatch; renamed to simplematch
+ *
+ *    Revision 1.4  2001/05/31 17:32:31  oes
+ *
+ *     - Enhanced domain part globbing with infix and prefix asterisk
+ *       matching and optional unanchored operation
+ *
+ *    Revision 1.3  2001/05/29 23:10:09  oes
+ *
+ *
+ *     - Introduced chomp()
+ *     - Moved strsav() from showargs to miscutil
+ *
+ *    Revision 1.2  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:00  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -42,24 +203,22 @@ const char miscutil_rcs[] = "$Id: miscutil.c,v 1.1 2001/05/13 21:57:06 administr
 #include "config.h"
 
 #include <stdio.h>
+#include <sys/types.h>
 #include <stdlib.h>
+#if !defined(_WIN32) && !defined(__OS2__)
+#include <unistd.h>
+#endif /* #if !defined(_WIN32) && !defined(__OS2__) */
 #include <string.h>
-#include <malloc.h>
 #include <ctype.h>
+#include <assert.h>
 
+#include "project.h"
 #include "miscutil.h"
+#include "errlog.h"
+#include "jcc.h"
 
 const char miscutil_h_rcs[] = MISCUTIL_H_VERSION;
 
-/* Fix a problem with Solaris.  There should be no effect on other
- * platforms.
- * Solaris's isspace() is a macro which uses it's argument directly
- * as an array index.  Therefore we need to make sure that high-bit
- * characters generate +ve values, and ideally we also want to make
- * the argument match the declared parameter type of "int".
- */
-#define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
-
 /*********************************************************************
  *
  * Function    :  zalloc
@@ -73,7 +232,7 @@ const char miscutil_h_rcs[] = MISCUTIL_H_VERSION;
  * Returns     :  Pointer to newly malloc'd memory chunk.
  *
  *********************************************************************/
-void *zalloc(int size)
+void *zalloc(size_t size)
 {
    void * ret;
 
@@ -83,9 +242,47 @@ void *zalloc(int size)
    }
 
    return(ret);
+
 }
 
 
+#if defined(unix)
+/*********************************************************************
+ *
+ * Function    :  write_pid_file 
+ *
+ * Description :  Writes a pid file with the pid of the main process 
+ *
+ * Parameters  :  None
+ *
+ * Returns     :  N/A 
+ *
+ *********************************************************************/
+void write_pid_file(void)
+{
+   FILE   *fp;
+   
+   /*
+    * If no --pidfile option was given,
+    * we can live without one.
+    */
+   if (pidfile == NULL) return;
+
+   if ((fp = fopen(pidfile, "w")) == NULL)
+   {
+      log_error(LOG_LEVEL_INFO, "can't open pidfile '%s': %E", pidfile);
+   }
+   else
+   {
+      fprintf(fp, "%u\n", (unsigned int) getpid());
+      fclose (fp);
+   }
+   return;
+
+}
+#endif /* def unix */
+
+
 /*********************************************************************
  *
  * Function    :  hash_string
@@ -100,9 +297,9 @@ void *zalloc(int size)
  * Returns     :  an unsigned long variable with the hashed value.
  *
  *********************************************************************/
-unsigned long hash_string( const char* s )
+unsigned int hash_string( const char* s )
 {
-   unsigned long h = 0ul
+   unsigned int h = 0
 
    for ( ; *s; ++s )
    {
@@ -165,12 +362,12 @@ char *strdup( const char *s )
 char *safe_strerror(int err)
 {
    char *s = NULL;
-   char buf[BUFSIZ];
+   char buf[BUFFER_SIZE];
 
 
-#ifndef NOSTRERROR
+#ifdef HAVE_STRERROR
    s = strerror(err);
-#endif /* NOSTRERROR */
+#endif /* HAVE_STRERROR */
 
    if (s == NULL)
    {
@@ -196,7 +393,7 @@ char *safe_strerror(int err)
  * Returns     :  0 if s1==s2, Negative if s1<s2, Positive if s1>s2
  *
  *********************************************************************/
-int strcmpic(char *s1, char *s2)
+int strcmpic(const char *s1, const char *s2)
 {
    while (*s1 && *s2)
    {
@@ -225,7 +422,7 @@ int strcmpic(char *s1, char *s2)
  * Returns     :  0 if s1==s2, Negative if s1<s2, Positive if s1>s2
  *
  *********************************************************************/
-int strncmpic(char *s1, char *s2, size_t n)
+int strncmpic(const char *s1, const char *s2, size_t n)
 {
    if (n <= 0) return(0);
 
@@ -245,6 +442,1316 @@ int strncmpic(char *s1, char *s2, size_t n)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  chomp
+ *
+ * Description :  In-situ-eliminate all leading and trailing whitespace
+ *                from a string.
+ *
+ * Parameters  :
+ *          1  :  s : string to be chomped.
+ *
+ * Returns     :  chomped string
+ *
+ *********************************************************************/
+char *chomp(char *string)
+{
+   char *p, *q, *r;
+
+   /* 
+    * strip trailing whitespace
+    */
+   p = string + strlen(string);
+   while (p > string && ijb_isspace(*(p-1)))
+   {
+      p--;
+   }
+   *p = '\0';
+
+   /* 
+    * find end of leading whitespace 
+    */
+   q = r = string;
+   while (*q && ijb_isspace(*q))
+   {
+      q++;
+   }
+
+   /*
+    * if there was any, move the rest forwards
+    */
+   if (q != string)
+   {
+      while (q <= p)
+      {
+         *r++ = *q++;
+      }
+   }
+
+   return(string);
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  strsav
+ *
+ * Description :  Reallocate "old" and append text to it.  This makes
+ *                it easier to append to malloc'd strings.
+ *                Running out of memory is a FATAL error.
+ *
+ * Parameters  :
+ *          1  :  old = Old text that is to be extended.  Will be
+ *                free()d by this routine.  May be NULL.
+ *          2  :  text_to_append = Text to be appended to old.
+ *                May be NULL.
+ *
+ * Returns     :  Pointer to newly malloc'ed appended string.
+ *                If there is no text to append, return old.  Caller
+ *                must free().
+ *
+ *********************************************************************/
+char *strsav(char *old, const char *text_to_append)
+{
+   size_t old_len, new_len = 0;
+   char *p;
+
+   if ((text_to_append == NULL) || (*text_to_append == '\0'))
+   {
+      return(old);
+   }
+
+   if (NULL == old)
+   {
+      if ((p = strdup(text_to_append)) == NULL)
+      {
+         log_error(LOG_LEVEL_FATAL, "strdup() failed!");
+         /* Never get here - LOG_LEVEL_FATAL causes program exit */
+      }
+      return p;
+   }
+
+   old_len = strlen(old);
+   new_len = old_len + strlen(text_to_append) + 1;
+
+   if ((p = realloc(old, new_len)) == NULL)
+   {
+      log_error(LOG_LEVEL_FATAL, "realloc(%d) bytes failed!", new_len);
+      /* Never get here - LOG_LEVEL_FATAL causes program exit */
+   }
+
+   strcpy(p + old_len, text_to_append);
+   return(p);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  string_append
+ *
+ * Description :  Reallocate target_string and append text to it.  
+ *                This makes it easier to append to malloc'd strings.
+ *                This is similar to the (removed) strsav(), but
+ *                running out of memory isn't catastrophic.
+ *
+ *                Programming style:
+ *
+ *                The following style provides sufficient error
+ *                checking for this routine, with minimal clutter
+ *                in the source code.  It is recommended if you
+ *                have many calls to this function:
+ *
+ *                char * s = strdup(...); // don't check for error
+ *                string_append(&s, ...);  // don't check for error
+ *                string_append(&s, ...);  // don't check for error
+ *                string_append(&s, ...);  // don't check for error
+ *                if (NULL == s) { ... handle error ... }
+ *
+ *                OR, equivalently:
+ *
+ *                char * s = strdup(...); // don't check for error
+ *                string_append(&s, ...);  // don't check for error
+ *                string_append(&s, ...);  // don't check for error
+ *                if (string_append(&s, ...)) {... handle error ...}
+ *
+ * Parameters  :
+ *          1  :  target_string = Pointer to old text that is to be
+ *                extended.  *target_string will be free()d by this
+ *                routine.  target_string must be non-NULL.
+ *                If *target_string is NULL, this routine will
+ *                do nothing and return with an error - this allows
+ *                you to make many calls to this routine and only
+ *                check for errors after the last one.
+ *          2  :  text_to_append = Text to be appended to old.
+ *                Must not be NULL.
+ *
+ * Returns     :  JB_ERR_OK on success, and sets *target_string
+ *                   to newly malloc'ed appended string.  Caller
+ *                   must free(*target_string).
+ *                JB_ERR_MEMORY on out-of-memory.  (And free()s
+ *                   *target_string and sets it to NULL).
+ *                JB_ERR_MEMORY if *target_string is NULL.
+ *
+ *********************************************************************/
+jb_err string_append(char **target_string, const char *text_to_append)
+{
+   size_t old_len;
+   char *new_string;
+
+   assert(target_string);
+   assert(text_to_append);
+
+   if (*target_string == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   if (*text_to_append == '\0')
+   {
+      return JB_ERR_OK;
+   }
+
+   old_len = strlen(*target_string);
+
+   if (NULL == (new_string = realloc(*target_string,
+          strlen(text_to_append) + old_len + 1)))
+   {
+      free(*target_string);
+
+      *target_string = NULL;
+      return JB_ERR_MEMORY;
+   }
+
+   strcpy(new_string + old_len, text_to_append);
+
+   *target_string = new_string;
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  string_join
+ *
+ * Description :  Join two strings together.  Frees BOTH the original
+ *                strings.  If either or both input strings are NULL,
+ *                fails as if it had run out of memory.
+ *
+ *                For comparison, string_append requires that the
+ *                second string is non-NULL, and doesn't free it.
+ *
+ *                Rationale: Too often, we want to do
+ *                string_append(s, html_encode(s2)).  That assert()s
+ *                if s2 is NULL or if html_encode() runs out of memory.
+ *                It also leaks memory.  Proper checking is cumbersome.
+ *                The solution: string_join(s, html_encode(s2)) is safe,
+ *                and will free the memory allocated by html_encode().
+ *
+ * Parameters  :
+ *          1  :  target_string = Pointer to old text that is to be
+ *                extended.  *target_string will be free()d by this
+ *                routine.  target_string must be non-NULL.
+ *          2  :  text_to_append = Text to be appended to old.
+ *
+ * Returns     :  JB_ERR_OK on success, and sets *target_string
+ *                   to newly malloc'ed appended string.  Caller
+ *                   must free(*target_string).
+ *                JB_ERR_MEMORY on out-of-memory, or if
+ *                   *target_string or text_to_append is NULL.  (In
+ *                   this case, frees *target_string and text_to_append,
+ *                   sets *target_string to NULL).
+ *
+ *********************************************************************/
+jb_err string_join(char **target_string, char *text_to_append)
+{
+   jb_err err;
+
+   assert(target_string);
+
+   if (text_to_append == NULL)
+   {
+      freez(*target_string);
+      return JB_ERR_MEMORY;
+   }
+
+   err = string_append(target_string, text_to_append);
+
+   free(text_to_append);
+
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  string_toupper
+ *
+ * Description :  Produce a copy of string with all convertible
+ *                characters converted to uppercase.
+ *
+ * Parameters  :
+ *          1  :  string = string to convert
+ *
+ * Returns     :  Uppercase copy of string if possible, 
+ *                NULL on out-of-memory or if string was NULL.
+ *
+ *********************************************************************/
+char *string_toupper(const char *string)
+{
+   char *result, *p;
+   const char *q;
+
+   if (!string || ((result = (char *) zalloc(strlen(string) + 1)) == NULL))
+   {
+      return NULL;
+   }
+   
+   q = string;
+   p = result;
+
+   while (*q != '\0')
+   {
+      *p++ = toupper(*q++);
+   }
+
+   return result;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  simplematch
+ *
+ * Description :  String matching, with a (greedy) '*' wildcard that
+ *                stands for zero or more arbitrary characters and
+ *                character classes in [], which take both enumerations
+ *                and ranges.
+ *
+ * Parameters  :
+ *          1  :  pattern = pattern for matching
+ *          2  :  text    = text to be matched
+ *
+ * Returns     :  0 if match, else nonzero
+ *
+ *********************************************************************/
+int simplematch(char *pattern, char *text)
+{
+   unsigned char *pat = (unsigned char *) pattern;
+   unsigned char *txt = (unsigned char *) text;
+   unsigned char *fallback = pat; 
+   int wildcard = 0;
+  
+   unsigned char lastchar = 'a';
+   unsigned i;
+   unsigned char charmap[32];
+  
+  
+   while (*txt)
+   {
+
+      /* EOF pattern but !EOF text? */
+      if (*pat == '\0')
+      {
+         return 1;
+      }
+
+      /* '*' in the pattern?  */
+      if (*pat == '*') 
+      {
+     
+         /* The pattern ends afterwards? Speed up the return. */
+         if (*++pat == '\0')
+         {
+            return 0;
+         }
+     
+         /* Else, set wildcard mode and remember position after '*' */
+         wildcard = 1;
+         fallback = pat;
+      }
+
+      /* Character range specification? */
+      if (*pat == '[')
+      {
+         memset(charmap, '\0', sizeof(charmap));
+
+         while (*++pat != ']')
+         {
+            if (!*pat)
+            { 
+               return 1;
+            }
+            else if (*pat == '-')
+            {
+               if ((*++pat == ']') || *pat == '\0')
+               {
+                  return(1);
+               }
+               for(i = lastchar; i <= *pat; i++)
+               {
+                  charmap[i / 8] |= (1 << (i % 8));
+               } 
+            }
+            else
+            {
+               charmap[*pat / 8] |= (1 << (*pat % 8));
+               lastchar = *pat;
+            }
+         }
+      } /* -END- if Character range specification */
+
+
+      /* Compare: Char match, or char range match*/
+      if ((*pat == *txt)  
+      || ((*pat == ']') && (charmap[*txt / 8] & (1 << (*txt % 8)))) )
+      {
+         /* Sucess, go ahead */
+         pat++;
+      }
+      else
+      {
+         /* In wildcard mode, just try again after failiure */
+         if(wildcard)
+         {
+            pat = fallback;
+         }
+
+         /* Else, bad luck */
+         else
+         {
+            return 1;
+         }
+      }
+      txt++;
+   }
+
+   /* Cut off extra '*'s */
+   if(*pat == '*')  pat++;
+
+   /* If this is the pattern's end, fine! */
+   return(*pat);
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  bindup
+ *
+ * Description :  Duplicate the first n characters of a string that may
+ *                contain '\0' characters.
+ *
+ * Parameters  :
+ *          1  :  string = string to be duplicated
+ *          2  :  len = number of bytes to duplicate
+ *
+ * Returns     :  pointer to copy, or NULL if failiure
+ *
+ *********************************************************************/
+char *bindup(const char *string, size_t len)
+{
+   char *duplicate;
+
+   if (NULL == (duplicate = (char *)malloc(len)))
+   {
+      return NULL;
+   }
+   else
+   {
+     memcpy(duplicate, string, len);
+   }
+
+   return duplicate;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  make_path
+ *
+ * Description :  Takes a directory name and a file name, returns 
+ *                the complete path.  Handles windows/unix differences.
+ *                If the file name is already an absolute path, or if
+ *                the directory name is NULL or empty, it returns 
+ *                the filename. 
+ *
+ * Parameters  :
+ *          1  :  dir: Name of directory or NULL for none.
+ *          2  :  file: Name of file.  Should not be NULL or empty.
+ *
+ * Returns     :  "dir/file" (Or on windows, "dir\file").
+ *                It allocates the string on the heap.  Caller frees.
+ *                Returns NULL in error (i.e. NULL file or out of
+ *                memory) 
+ *
+ *********************************************************************/
+char * make_path(const char * dir, const char * file)
+{
+#ifdef AMIGA
+   char path[512];
+
+   if(dir)
+   {
+      if(dir[0] == '.')
+      {
+         if(dir[1] == '/')
+         {
+            strncpy(path,dir+2,512);
+         }
+         else
+         {
+            strncpy(path,dir+1,512);
+         }
+      }
+      else
+      {
+         strncpy(path,dir,512);
+      }
+      path[511]=0;
+   } else {
+      path[0]=0;
+   }
+   if(AddPart(path,file,512))
+   {
+      return strdup(path);
+   } else {
+      return NULL;
+   }
+#else /* ndef AMIGA */
+
+   if ((file == NULL) || (*file == '\0'))
+   {
+      return NULL; /* Error */
+   }
+
+   if ((dir == NULL) || (*dir == '\0') /* No directory specified */
+#if defined(_WIN32) || defined(__OS2__)
+      || (*file == '\\') || (file[1] == ':') /* Absolute path (DOS) */
+#else /* ifndef _WIN32 || __OS2__ */
+      || (*file == '/') /* Absolute path (U*ix) */
+#endif /* ifndef _WIN32 || __OS2__  */
+      )
+   {
+      return strdup(file);
+   }
+   else
+   {
+      char * path;
+
+#if defined(unix)
+      if ( *dir != '/' && basedir && *basedir )
+      {
+         path = malloc( strlen( basedir ) + strlen(dir) + strlen(file) + 3);
+         if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
+         strcpy(path, basedir);
+         strcat(path, "/");
+         strcat(path, dir);
+      }
+      else
+      {
+         path = malloc(strlen(dir) + strlen(file) + 2);
+         if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
+         strcpy(path, dir);
+      }
+#else
+
+      path = malloc(strlen(dir) + strlen(file) + 2);
+      if (!path ) log_error(LOG_LEVEL_FATAL, "malloc failed!");
+      strcpy(path, dir);
+
+#endif /* defined unix */
+
+#if defined(_WIN32) || defined(__OS2__)
+      if(path[strlen(path)-1] != '\\')
+      {
+         strcat(path, "\\");
+      }
+#else /* ifndef _WIN32 || __OS2__ */
+      if(path[strlen(path)-1] != '/')
+      {
+         strcat(path, "/");
+      }
+#endif /* ifndef _WIN32 || __OS2__ */
+      strcat(path, file);
+
+      return path;
+   }
+#endif /* ndef AMIGA */
+}
+
+
+/*
+ * What follows is a portable snprintf routine, written by Mark Martinec.
+ * See: http://www.ijs.si/software/snprintf/
+ * Anyone who needs it can add a define for themselves... so far, only 
+ * OS/2 (native) lacks snprintf.
+
+                                  snprintf.c
+                   - a portable implementation of snprintf,
+       including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf
+                                       
+   snprintf is a routine to convert numeric and string arguments to
+   formatted strings. It is similar to sprintf(3) provided in a system's
+   C library, yet it requires an additional argument - the buffer size -
+   and it guarantees never to store anything beyond the given buffer,
+   regardless of the format or arguments to be formatted. Some newer
+   operating systems do provide snprintf in their C library, but many do
+   not or do provide an inadequate (slow or idiosyncratic) version, which
+   calls for a portable implementation of this routine.
+
+Author
+
+   Mark Martinec <mark.martinec@ijs.si>, April 1999, June 2000
+   Copyright Â© 1999, Mark Martinec
+
+ */
+
+#ifdef __OS2__
+
+#define PORTABLE_SNPRINTF_VERSION_MAJOR 2
+#define PORTABLE_SNPRINTF_VERSION_MINOR 2
+
+#if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF)
+# if defined(NEED_SNPRINTF_ONLY)
+# undef NEED_SNPRINTF_ONLY
+# endif
+# if !defined(PREFER_PORTABLE_SNPRINTF)
+# define PREFER_PORTABLE_SNPRINTF
+# endif
+#endif
+
+#if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE)
+#define SOLARIS_COMPATIBLE
+#endif
+
+#if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE)
+#define HPUX_COMPATIBLE
+#endif
+
+#if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE)
+#define DIGITAL_UNIX_COMPATIBLE
+#endif
+
+#if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE)
+#define PERL_COMPATIBLE
+#endif
+
+#if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE)
+#define LINUX_COMPATIBLE
+#endif
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <errno.h>
+
+#ifdef isdigit
+#undef isdigit
+#endif
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+
+/* For copying strings longer or equal to 'breakeven_point'
+ * it is more efficient to call memcpy() than to do it inline.
+ * The value depends mostly on the processor architecture,
+ * but also on the compiler and its optimization capabilities.
+ * The value is not critical, some small value greater than zero
+ * will be just fine if you don't care to squeeze every drop
+ * of performance out of the code.
+ *
+ * Small values favor memcpy, large values favor inline code.
+ */
+#if defined(__alpha__) || defined(__alpha)
+#  define breakeven_point   2    /* AXP (DEC Alpha)     - gcc or cc or egcs */
+#endif
+#if defined(__i386__)  || defined(__i386)
+#  define breakeven_point  12    /* Intel Pentium/Linux - gcc 2.96 */
+#endif
+#if defined(__hppa)
+#  define breakeven_point  10    /* HP-PA               - gcc */
+#endif
+#if defined(__sparc__) || defined(__sparc)
+#  define breakeven_point  33    /* Sun Sparc 5         - gcc 2.8.1 */
+#endif
+
+/* some other values of possible interest: */
+/* #define breakeven_point  8 */ /* VAX 4000          - vaxc */
+/* #define breakeven_point 19 */ /* VAX 4000          - gcc 2.7.0 */
+
+#ifndef breakeven_point
+#  define breakeven_point   6    /* some reasonable one-size-fits-all value */
+#endif
+
+#define fast_memcpy(d,s,n) \
+  { register size_t nn = (size_t)(n); \
+    if (nn >= breakeven_point) memcpy((d), (s), nn); \
+    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
+      register char *dd; register const char *ss; \
+      for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } }
+
+#define fast_memset(d,c,n) \
+  { register size_t nn = (size_t)(n); \
+    if (nn >= breakeven_point) memset((d), (int)(c), nn); \
+    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\
+      register char *dd; register const int cc=(int)(c); \
+      for (dd=(d); nn>0; nn--) *dd++ = cc; } }
+
+/* prototypes */
+
+#if defined(NEED_ASPRINTF)
+int asprintf   (char **ptr, const char *fmt, /*args*/ ...);
+#endif
+#if defined(NEED_VASPRINTF)
+int vasprintf  (char **ptr, const char *fmt, va_list ap);
+#endif
+#if defined(NEED_ASNPRINTF)
+int asnprintf  (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);
+#endif
+#if defined(NEED_VASNPRINTF)
+int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap);
+#endif
+
+#if defined(HAVE_SNPRINTF)
+/* declare our portable snprintf  routine under name portable_snprintf  */
+/* declare our portable vsnprintf routine under name portable_vsnprintf */
+#else
+/* declare our portable routines under names snprintf and vsnprintf */
+#define portable_snprintf snprintf
+#if !defined(NEED_SNPRINTF_ONLY)
+#define portable_vsnprintf vsnprintf
+#endif
+#endif
+
+#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);
+#if !defined(NEED_SNPRINTF_ONLY)
+int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);
+#endif
+#endif
+
+/* declarations */
+
+static char credits[] = "\n\
+@(#)snprintf.c, v2.2: Mark Martinec, <mark.martinec@ijs.si>\n\
+@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\
+@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n";
+
+#if defined(NEED_ASPRINTF)
+int asprintf(char **ptr, const char *fmt, /*args*/ ...) {
+  va_list ap;
+  size_t str_m;
+  int str_l;
+
+  *ptr = NULL;
+  va_start(ap, fmt);                            /* measure the required size */
+  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
+  va_end(ap);
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
+  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+  else {
+    int str_l2;
+    va_start(ap, fmt);
+    str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+    va_end(ap);
+    assert(str_l2 == str_l);
+  }
+  return str_l;
+}
+#endif
+
+#if defined(NEED_VASPRINTF)
+int vasprintf(char **ptr, const char *fmt, va_list ap) {
+  size_t str_m;
+  int str_l;
+
+  *ptr = NULL;
+  { va_list ap2;
+    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */
+    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
+    va_end(ap2);
+  }
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
+  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+  else {
+    int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+    assert(str_l2 == str_l);
+  }
+  return str_l;
+}
+#endif
+
+#if defined(NEED_ASNPRINTF)
+int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) {
+  va_list ap;
+  int str_l;
+
+  *ptr = NULL;
+  va_start(ap, fmt);                            /* measure the required size */
+  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
+  va_end(ap);
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */
+  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
+  if (str_m == 0) {  /* not interested in resulting string, just return size */
+  } else {
+    *ptr = (char *) malloc(str_m);
+    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+    else {
+      int str_l2;
+      va_start(ap, fmt);
+      str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+      va_end(ap);
+      assert(str_l2 == str_l);
+    }
+  }
+  return str_l;
+}
+#endif
+
+#if defined(NEED_VASNPRINTF)
+int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) {
+  int str_l;
+
+  *ptr = NULL;
+  { va_list ap2;
+    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */
+    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
+    va_end(ap2);
+  }
+  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
+  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */
+  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
+  if (str_m == 0) {  /* not interested in resulting string, just return size */
+  } else {
+    *ptr = (char *) malloc(str_m);
+    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }
+    else {
+      int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
+      assert(str_l2 == str_l);
+    }
+  }
+  return str_l;
+}
+#endif
+
+/*
+ * If the system does have snprintf and the portable routine is not
+ * specifically required, this module produces no code for snprintf/vsnprintf.
+ */
+#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
+
+#if !defined(NEED_SNPRINTF_ONLY)
+int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {
+  va_list ap;
+  int str_l;
+
+  va_start(ap, fmt);
+  str_l = portable_vsnprintf(str, str_m, fmt, ap);
+  va_end(ap);
+  return str_l;
+}
+#endif
+
+#if defined(NEED_SNPRINTF_ONLY)
+int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {
+#else
+int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) {
+#endif
+
+#if defined(NEED_SNPRINTF_ONLY)
+  va_list ap;
+#endif
+  size_t str_l = 0;
+  const char *p = fmt;
+
+/* In contrast with POSIX, the ISO C99 now says
+ * that str can be NULL and str_m can be 0.
+ * This is more useful than the old:  if (str_m < 1) return -1; */
+
+#if defined(NEED_SNPRINTF_ONLY)
+  va_start(ap, fmt);
+#endif
+  if (!p) p = "";
+  while (*p) {
+    if (*p != '%') {
+   /* if (str_l < str_m) str[str_l++] = *p++;    -- this would be sufficient */
+   /* but the following code achieves better performance for cases
+    * where format string is long and contains few conversions */
+      const char *q = strchr(p+1,'%');
+      size_t n = !q ? strlen(p) : (q-p);
+      if (str_l < str_m) {
+        size_t avail = str_m-str_l;
+        fast_memcpy(str+str_l, p, (n>avail?avail:n));
+      }
+      p += n; str_l += n;
+    } else {
+      const char *starting_p;
+      size_t min_field_width = 0, precision = 0;
+      int zero_padding = 0, precision_specified = 0, justify_left = 0;
+      int alternate_form = 0, force_sign = 0;
+      int space_for_positive = 1; /* If both the ' ' and '+' flags appear,
+                                     the ' ' flag should be ignored. */
+      char length_modifier = '\0';            /* allowed values: \0, h, l, L */
+      char tmp[32];/* temporary buffer for simple numeric->string conversion */
+
+      const char *str_arg;      /* string address in case of string argument */
+      size_t str_arg_l;         /* natural field width of arg without padding
+                                   and sign */
+      unsigned char uchar_arg;
+        /* unsigned char argument value - only defined for c conversion.
+           N.B. standard explicitly states the char argument for
+           the c conversion is unsigned */
+
+      size_t number_of_zeros_to_pad = 0;
+        /* number of zeros to be inserted for numeric conversions
+           as required by the precision or minimal field width */
+
+      size_t zero_padding_insertion_ind = 0;
+        /* index into tmp where zero padding is to be inserted */
+
+      char fmt_spec = '\0';
+        /* current conversion specifier character */
+
+      str_arg = credits;/* just to make compiler happy (defined but not used)*/
+      str_arg = NULL;
+      starting_p = p; p++;  /* skip '%' */
+   /* parse flags */
+      while (*p == '0' || *p == '-' || *p == '+' ||
+             *p == ' ' || *p == '#' || *p == '\'') {
+        switch (*p) {
+        case '0': zero_padding = 1; break;
+        case '-': justify_left = 1; break;
+        case '+': force_sign = 1; space_for_positive = 0; break;
+        case ' ': force_sign = 1;
+     /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */
+#ifdef PERL_COMPATIBLE
+     /* ... but in Perl the last of ' ' and '+' applies */
+                  space_for_positive = 1;
+#endif
+                  break;
+        case '#': alternate_form = 1; break;
+        case '\'': break;
+        }
+        p++;
+      }
+   /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */
+
+   /* parse field width */
+      if (*p == '*') {
+        int j;
+        p++; j = va_arg(ap, int);
+        if (j >= 0) min_field_width = j;
+        else { min_field_width = -j; justify_left = 1; }
+      } else if (isdigit((int)(*p))) {
+        /* size_t could be wider than unsigned int;
+           make sure we treat argument like common implementations do */
+        unsigned int uj = *p++ - '0';
+        while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');
+        min_field_width = uj;
+      }
+   /* parse precision */
+      if (*p == '.') {
+        p++; precision_specified = 1;
+        if (*p == '*') {
+          int j = va_arg(ap, int);
+          p++;
+          if (j >= 0) precision = j;
+          else {
+            precision_specified = 0; precision = 0;
+         /* NOTE:
+          *   Solaris 2.6 man page claims that in this case the precision
+          *   should be set to 0.  Digital Unix 4.0, HPUX 10 and BSD man page
+          *   claim that this case should be treated as unspecified precision,
+          *   which is what we do here.
+          */
+          }
+        } else if (isdigit((int)(*p))) {
+          /* size_t could be wider than unsigned int;
+             make sure we treat argument like common implementations do */
+          unsigned int uj = *p++ - '0';
+          while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');
+          precision = uj;
+        }
+      }
+   /* parse 'h', 'l' and 'll' length modifiers */
+      if (*p == 'h' || *p == 'l') {
+        length_modifier = *p; p++;
+        if (length_modifier == 'l' && *p == 'l') {   /* double l = long long */
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+          length_modifier = '2';                  /* double l encoded as '2' */
+#else
+          length_modifier = 'l';                 /* treat it as a single 'l' */
+#endif
+          p++;
+        }
+      }
+      fmt_spec = *p;
+   /* common synonyms: */
+      switch (fmt_spec) {
+      case 'i': fmt_spec = 'd'; break;
+      case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
+      case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
+      case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+      default: break;
+      }
+   /* get parameter value, do initial processing */
+      switch (fmt_spec) {
+      case '%': /* % behaves similar to 's' regarding flags and field widths */
+      case 'c': /* c behaves similar to 's' regarding flags and field widths */
+      case 's':
+        length_modifier = '\0';          /* wint_t and wchar_t not supported */
+     /* the result of zero padding flag with non-numeric conversion specifier*/
+     /* is undefined. Solaris and HPUX 10 does zero padding in this case,    */
+     /* Digital Unix and Linux does not. */
+#if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE)
+        zero_padding = 0;    /* turn zero padding off for string conversions */
+#endif
+        str_arg_l = 1;
+        switch (fmt_spec) {
+        case '%':
+          str_arg = p; break;
+        case 'c': {
+          int j = va_arg(ap, int);
+          uchar_arg = (unsigned char) j;   /* standard demands unsigned char */
+          str_arg = (const char *) &uchar_arg;
+          break;
+        }
+        case 's':
+          str_arg = va_arg(ap, const char *);
+          if (!str_arg) str_arg_l = 0;
+       /* make sure not to address string beyond the specified precision !!! */
+          else if (!precision_specified) str_arg_l = strlen(str_arg);
+       /* truncate string if necessary as requested by precision */
+          else if (precision == 0) str_arg_l = 0;
+          else {
+       /* memchr on HP does not like n > 2^31  !!! */
+            const char *q = memchr(str_arg, '\0',
+                             precision <= 0x7fffffff ? precision : 0x7fffffff);
+            str_arg_l = !q ? precision : (q-str_arg);
+          }
+          break;
+        default: break;
+        }
+        break;
+      case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': {
+        /* NOTE: the u, o, x, X and p conversion specifiers imply
+                 the value is unsigned;  d implies a signed value */
+
+        int arg_sign = 0;
+          /* 0 if numeric argument is zero (or if pointer is NULL for 'p'),
+            +1 if greater than zero (or nonzero for unsigned arguments),
+            -1 if negative (unsigned argument is never negative) */
+
+        int int_arg = 0;  unsigned int uint_arg = 0;
+          /* only defined for length modifier h, or for no length modifiers */
+
+        long int long_arg = 0;  unsigned long int ulong_arg = 0;
+          /* only defined for length modifier l */
+
+        void *ptr_arg = NULL;
+          /* pointer argument value -only defined for p conversion */
+
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+        long long int long_long_arg = 0;
+        unsigned long long int ulong_long_arg = 0;
+          /* only defined for length modifier ll */
+#endif
+        if (fmt_spec == 'p') {
+        /* HPUX 10: An l, h, ll or L before any other conversion character
+         *   (other than d, i, u, o, x, or X) is ignored.
+         * Digital Unix:
+         *   not specified, but seems to behave as HPUX does.
+         * Solaris: If an h, l, or L appears before any other conversion
+         *   specifier (other than d, i, u, o, x, or X), the behavior
+         *   is undefined. (Actually %hp converts only 16-bits of address
+         *   and %llp treats address as 64-bit data which is incompatible
+         *   with (void *) argument on a 32-bit system).
+         */
+#ifdef SOLARIS_COMPATIBLE
+#  ifdef SOLARIS_BUG_COMPATIBLE
+          /* keep length modifiers even if it represents 'll' */
+#  else
+          if (length_modifier == '2') length_modifier = '\0';
+#  endif
+#else
+          length_modifier = '\0';
+#endif
+          ptr_arg = va_arg(ap, void *);
+          if (ptr_arg != NULL) arg_sign = 1;
+        } else if (fmt_spec == 'd') {  /* signed */
+          switch (length_modifier) {
+          case '\0':
+          case 'h':
+         /* It is non-portable to specify a second argument of char or short
+          * to va_arg, because arguments seen by the called function
+          * are not char or short.  C converts char and short arguments
+          * to int before passing them to a function.
+          */
+            int_arg = va_arg(ap, int);
+            if      (int_arg > 0) arg_sign =  1;
+            else if (int_arg < 0) arg_sign = -1;
+            break;
+          case 'l':
+            long_arg = va_arg(ap, long int);
+            if      (long_arg > 0) arg_sign =  1;
+            else if (long_arg < 0) arg_sign = -1;
+            break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+          case '2':
+            long_long_arg = va_arg(ap, long long int);
+            if      (long_long_arg > 0) arg_sign =  1;
+            else if (long_long_arg < 0) arg_sign = -1;
+            break;
+#endif
+          }
+        } else {  /* unsigned */
+          switch (length_modifier) {
+          case '\0':
+          case 'h':
+            uint_arg = va_arg(ap, unsigned int);
+            if (uint_arg) arg_sign = 1;
+            break;
+          case 'l':
+            ulong_arg = va_arg(ap, unsigned long int);
+            if (ulong_arg) arg_sign = 1;
+            break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+          case '2':
+            ulong_long_arg = va_arg(ap, unsigned long long int);
+            if (ulong_long_arg) arg_sign = 1;
+            break;
+#endif
+          }
+        }
+        str_arg = tmp; str_arg_l = 0;
+     /* NOTE:
+      *   For d, i, u, o, x, and X conversions, if precision is specified,
+      *   the '0' flag should be ignored. This is so with Solaris 2.6,
+      *   Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
+      */
+#ifndef PERL_COMPATIBLE
+        if (precision_specified) zero_padding = 0;
+#endif
+        if (fmt_spec == 'd') {
+          if (force_sign && arg_sign >= 0)
+            tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+         /* leave negative numbers for sprintf to handle,
+            to avoid handling tricky cases like (short int)(-32768) */
+#ifdef LINUX_COMPATIBLE
+        } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) {
+          tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+#endif
+        } else if (alternate_form) {
+          if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') )
+            { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; }
+         /* alternate form should have no effect for p conversion, but ... */
+#ifdef HPUX_COMPATIBLE
+          else if (fmt_spec == 'p'
+         /* HPUX 10: for an alternate form of p conversion,
+          *          a nonzero result is prefixed by 0x. */
+#ifndef HPUX_BUG_COMPATIBLE
+         /* Actually it uses 0x prefix even for a zero value. */
+                   && arg_sign != 0
+#endif
+                  ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; }
+#endif
+        }
+        zero_padding_insertion_ind = str_arg_l;
+        if (!precision_specified) precision = 1;   /* default precision is 1 */
+        if (precision == 0 && arg_sign == 0
+#if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE)
+            && fmt_spec != 'p'
+         /* HPUX 10 man page claims: With conversion character p the result of
+          * converting a zero value with a precision of zero is a null string.
+          * Actually HP returns all zeroes, and Linux returns "(nil)". */
+#endif
+        ) {
+         /* converted to null string */
+         /* When zero value is formatted with an explicit precision 0,
+            the resulting formatted string is empty (d, i, u, o, x, X, p).   */
+        } else {
+          char f[5]; int f_l = 0;
+          f[f_l++] = '%';    /* construct a simple format string for sprintf */
+          if (!length_modifier) { }
+          else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; }
+          else f[f_l++] = length_modifier;
+          f[f_l++] = fmt_spec; f[f_l++] = '\0';
+          if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg);
+          else if (fmt_spec == 'd') {  /* signed */
+            switch (length_modifier) {
+            case '\0':
+            case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg);  break;
+            case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+            case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break;
+#endif
+            }
+          } else {  /* unsigned */
+            switch (length_modifier) {
+            case '\0':
+            case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg);  break;
+            case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break;
+#ifdef SNPRINTF_LONGLONG_SUPPORT
+            case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break;
+#endif
+            }
+          }
+         /* include the optional minus sign and possible "0x"
+            in the region before the zero padding insertion point */
+          if (zero_padding_insertion_ind < str_arg_l &&
+              tmp[zero_padding_insertion_ind] == '-') {
+            zero_padding_insertion_ind++;
+          }
+          if (zero_padding_insertion_ind+1 < str_arg_l &&
+              tmp[zero_padding_insertion_ind]   == '0' &&
+             (tmp[zero_padding_insertion_ind+1] == 'x' ||
+              tmp[zero_padding_insertion_ind+1] == 'X') ) {
+            zero_padding_insertion_ind += 2;
+          }
+        }
+        { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
+          if (alternate_form && fmt_spec == 'o'
+#ifdef HPUX_COMPATIBLE                                  /* ("%#.o",0) -> ""  */
+              && (str_arg_l > 0)
+#endif
+#ifdef DIGITAL_UNIX_BUG_COMPATIBLE                      /* ("%#o",0) -> "00" */
+#else
+              /* unless zero is already the first character */
+              && !(zero_padding_insertion_ind < str_arg_l
+                   && tmp[zero_padding_insertion_ind] == '0')
+#endif
+          ) {        /* assure leading zero for alternate-form octal numbers */
+            if (!precision_specified || precision < num_of_digits+1) {
+             /* precision is increased to force the first character to be zero,
+                except if a zero value is formatted with an explicit precision
+                of zero */
+              precision = num_of_digits+1; precision_specified = 1;
+            }
+          }
+       /* zero padding to specified precision? */
+          if (num_of_digits < precision) 
+            number_of_zeros_to_pad = precision - num_of_digits;
+        }
+     /* zero padding to specified minimal field width? */
+        if (!justify_left && zero_padding) {
+          int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+          if (n > 0) number_of_zeros_to_pad += n;
+        }
+        break;
+      }
+      default: /* unrecognized conversion specifier, keep format string as-is*/
+        zero_padding = 0;  /* turn zero padding off for non-numeric convers. */
+#ifndef DIGITAL_UNIX_COMPATIBLE
+        justify_left = 1; min_field_width = 0;                /* reset flags */
+#endif
+#if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE)
+     /* keep the entire format string unchanged */
+        str_arg = starting_p; str_arg_l = p - starting_p;
+     /* well, not exactly so for Linux, which does something inbetween,
+      * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y"  */
+#else
+     /* discard the unrecognized conversion, just keep *
+      * the unrecognized conversion character          */
+        str_arg = p; str_arg_l = 0;
+#endif
+        if (*p) str_arg_l++;  /* include invalid conversion specifier unchanged
+                                 if not at end-of-string */
+        break;
+      }
+      if (*p) p++;      /* step over the just processed conversion specifier */
+   /* insert padding to the left as requested by min_field_width;
+      this does not include the zero padding in case of numerical conversions*/
+      if (!justify_left) {                /* left padding with blank or zero */
+        int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+   /* zero padding as requested by the precision or by the minimal field width
+    * for numeric conversions required? */
+      if (number_of_zeros_to_pad <= 0) {
+     /* will not copy first part of numeric right now, *
+      * force it to be copied later in its entirety    */
+        zero_padding_insertion_ind = 0;
+      } else {
+     /* insert first part of numerics (sign or '0x') before zero padding */
+        int n = zero_padding_insertion_ind;
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memcpy(str+str_l, str_arg, (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+     /* insert zero padding as requested by the precision or min field width */
+        n = number_of_zeros_to_pad;
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memset(str+str_l, '0', (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+   /* insert formatted string
+    * (or as-is conversion specifier for unknown conversions) */
+      { int n = str_arg_l - zero_padding_insertion_ind;
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind,
+                        (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+   /* insert right padding */
+      if (justify_left) {          /* right blank padding to the field width */
+        int n = min_field_width - (str_arg_l+number_of_zeros_to_pad);
+        if (n > 0) {
+          if (str_l < str_m) {
+            size_t avail = str_m-str_l;
+            fast_memset(str+str_l, ' ', (n>avail?avail:n));
+          }
+          str_l += n;
+        }
+      }
+    }
+  }
+#if defined(NEED_SNPRINTF_ONLY)
+  va_end(ap);
+#endif
+  if (str_m > 0) { /* make sure the string is null-terminated
+                      even at the expense of overwriting the last character
+                      (shouldn't happen, but just in case) */
+    str[str_l <= str_m-1 ? str_l : str_m-1] = '\0';
+  }
+  /* Return the number of characters formatted (excluding trailing null
+   * character), that is, the number of characters that would have been
+   * written to the buffer if it were large enough.
+   *
+   * The value of str_l should be returned, but str_l is of unsigned type
+   * size_t, and snprintf is int, possibly leading to an undetected
+   * integer overflow, resulting in a negative return value, which is illegal.
+   * Both XSH5 and ISO C99 (at least the draft) are silent on this issue.
+   * Should errno be set to EOVERFLOW and EOF returned in this case???
+   */
+  return (int) str_l;
+}
+#endif
+#endif /* __OS2__ */
 /*
   Local Variables:
   tab-width: 3
index 0a6b95e..e4793c8 100644 (file)
@@ -1,9 +1,9 @@
-#ifndef _MISCUTIL_H
-#define _MISCUTIL_H
-#define MISCUTIL_H_VERSION "$Id: miscutil.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef MISCUTIL_H_INCLUDED
+#define MISCUTIL_H_INCLUDED
+#define MISCUTIL_H_VERSION "$Id: miscutil.h,v 1.20 2002/03/26 22:29:55 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/miscutil.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/miscutil.h,v $
  *
  * Purpose     :  zalloc, hash_string, safe_strerror, strcmpic,
  *                strncmpic, and MinGW32 strdup functions.  These are
@@ -11,7 +11,7 @@
  *                really fit in any other file.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: miscutil.h,v $
+ *    Revision 1.20  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.19  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.18  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.17  2002/03/04 18:28:32  oes
+ *    Deleted deletePidFile, played syleguide police
+ *
+ *    Revision 1.16  2002/01/21 00:53:36  jongfoster
+ *    Adding string_join()
+ *
+ *    Revision 1.15  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.14  2001/11/05 21:43:48  steudten
+ *    Add global var 'basedir' for unix os.
+ *
+ *    Revision 1.13  2001/10/29 03:48:10  david__schmidt
+ *    OS/2 native needed a snprintf() routine.  Added one to miscutil, brackedted
+ *    by and __OS2__ ifdef.
+ *
+ *    Revision 1.12  2001/10/23 21:27:50  jongfoster
+ *    Standardising error codes in string_append
+ *    make_path() no longer adds '\\' if the dir already ends in '\\' (this
+ *    is just copying a UNIX-specific fix to the Windows-specific part)
+ *
+ *    Revision 1.11  2001/10/14 22:02:57  jongfoster
+ *    New function string_append() which is like strsav(), but running
+ *    out of memory isn't automatically FATAL.
+ *
+ *    Revision 1.10  2001/09/20 13:34:09  steudten
+ *
+ *    change long to int for prototype hash_string()
+ *
+ *    Revision 1.9  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.8  2001/06/29 13:32:14  oes
+ *    Removed logentry from cancelled commit
+ *
+ *    Revision 1.7  2001/06/05 22:32:01  jongfoster
+ *    New function make_path() to splice directory and file names together.
+ *
+ *    Revision 1.6  2001/06/03 19:12:30  oes
+ *    introduced bindup()
+ *
+ *    Revision 1.5  2001/06/01 10:31:51  oes
+ *    Added character class matching to trivimatch; renamed to simplematch
+ *
+ *    Revision 1.4  2001/05/31 17:32:31  oes
+ *
+ *     - Enhanced domain part globbing with infix and prefix asterisk
+ *       matching and optional unanchored operation
+ *
+ *    Revision 1.3  2001/05/29 23:10:09  oes
+ *
+ *
+ *     - Introduced chomp()
+ *     - Moved strsav() from showargs to miscutil
+ *
+ *    Revision 1.2  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:00  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
+#include "project.h"
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
-extern void *zalloc(int size);
+extern const char *basedir;
+extern void *zalloc(size_t size);
 
-extern unsigned long hash_string(const char* s);
+#if defined(unix)
+extern void write_pid_file(void);
+#endif /* unix */
+
+extern unsigned int hash_string(const char* s);
 
 extern char *safe_strerror(int err);
 
-extern int strcmpic(char *s1, char *s2);
-extern int strncmpic(char *s1, char *s2, size_t n);
+extern int strcmpic(const char *s1, const char *s2);
+extern int strncmpic(const char *s1, const char *s2, size_t n);
+
+extern char *strsav(char *old, const char *text_to_append);
+extern jb_err string_append(char **target_string, const char *text_to_append);
+extern jb_err string_join  (char **target_string,       char *text_to_append);
+
+extern char *string_toupper(const char *string);
+extern char *chomp(char *string);
+extern int simplematch(char *pattern, char *text);
+
+extern char *bindup(const char *string, size_t len);
+
+extern char *make_path(const char * dir, const char * file);
 
 #ifdef __MINGW32__
 extern char *strdup(const char *s);
 #endif /* def __MINGW32__ */
 
+#ifdef __OS2__
+extern int snprintf(char *, size_t, const char *, /*args*/ ...);
+#endif /* def __OS2__ */
+
 /* Revision control strings from this header and associated .c file */
 extern const char miscutil_rcs[];
 extern const char miscutil_h_rcs[];
@@ -66,7 +185,7 @@ extern const char miscutil_h_rcs[];
 }
 #endif
 
-#endif /* ndef _MISCUTIL_H */
+#endif /* ndef MISCUTIL_H_INCLUDED */
 
 /*
   Local Variables:
index f56c0b7..df2ae59 100644 (file)
--- a/parsers.c
+++ b/parsers.c
@@ -1,7 +1,7 @@
-const char parsers_rcs[] = "$Id: parsers.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.55 2002/05/08 16:01:07 oes Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/parsers.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/parsers.c,v $
  *
  * Purpose     :  Declares functions to parse/crunch headers and pages.
  *                Functions declared include:
@@ -10,18 +10,17 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.1 2001/05/13 21:57:06 administrat
  *                   `client_uagent', `client_x_forwarded',
  *                   `client_x_forwarded_adder', `client_xtra_adder',
  *                   `content_type', `crumble', `destroy_list', `enlist',
- *                   `flush_socket', `free_http_request', `get_header',
- *                   `list_to_text', `match', `parse_http_request', `sed',
+ *                   `flush_socket', ``get_header', `sed',
  *                   and `server_set_cookie'.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -41,33 +40,374 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.1 2001/05/13 21:57:06 administrat
  *
  * Revisions   :
  *    $Log: parsers.c,v $
+ *    Revision 1.55  2002/05/08 16:01:07  oes
+ *    Optimized add_to_iob:
+ *     - Use realloc instead of malloc(), memcpy(), free()
+ *     - Expand to powers of two if possible, to get
+ *       O(log n) reallocs instead of O(n).
+ *     - Moved check for buffer limit here from chat
+ *     - Report failure via returncode
+ *
+ *    Revision 1.54  2002/04/02 15:03:16  oes
+ *    Tiny code cosmetics
+ *
+ *    Revision 1.53  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.52  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.51  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.50  2002/03/12 01:45:35  oes
+ *    More verbose logging
+ *
+ *    Revision 1.49  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.48  2002/03/07 03:46:53  oes
+ *    Fixed compiler warnings etc
+ *
+ *    Revision 1.47  2002/02/20 23:15:13  jongfoster
+ *    Parsing functions now handle out-of-memory gracefully by returning
+ *    an error code.
+ *
+ *    Revision 1.46  2002/01/17 21:03:47  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Revision 1.45  2002/01/09 14:33:03  oes
+ *    Added support for localtime_r.
+ *
+ *    Revision 1.44  2001/12/14 01:22:54  steudten
+ *    Remove 'user:pass@' from 'proto://user:pass@host' for the
+ *    new added header 'Host: ..'. (See Req ID 491818)
+ *
+ *    Revision 1.43  2001/11/23 00:26:38  jongfoster
+ *    Fixing two really stupid errors in my previous commit
+ *
+ *    Revision 1.42  2001/11/22 21:59:30  jongfoster
+ *    Adding code to handle +no-cookies-keep
+ *
+ *    Revision 1.41  2001/11/05 23:43:05  steudten
+ *    Add time+date to log files.
+ *
+ *    Revision 1.40  2001/10/26 20:13:09  jongfoster
+ *    ctype.h is needed in Windows, too.
+ *
+ *    Revision 1.39  2001/10/26 17:40:04  oes
+ *    Introduced get_header_value()
+ *    Removed http->user_agent, csp->referrer and csp->accept_types
+ *    Removed client_accept()
+ *
+ *    Revision 1.38  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.37  2001/10/23 21:36:02  jongfoster
+ *    Documenting sed()'s error behaviou (doc change only)
+ *
+ *    Revision 1.36  2001/10/13 12:51:51  joergs
+ *    Removed client_host, (was only required for the old 2.0.2-11 http://noijb.
+ *    force-load), instead crumble Host: and add it (again) in client_host_adder
+ *    (in case we get a HTTP/1.0 request without Host: header and forward it to
+ *    a HTTP/1.1 server/proxy).
+ *
+ *    Revision 1.35  2001/10/09 22:39:21  jongfoster
+ *    assert.h is also required under Win32, so moving out of #ifndef _WIN32
+ *    block.
+ *
+ *    Revision 1.34  2001/10/07 18:50:55  oes
+ *    Added server_content_encoding, renamed server_transfer_encoding
+ *
+ *    Revision 1.33  2001/10/07 18:04:49  oes
+ *    Changed server_http11 to server_http and its pattern to "HTTP".
+ *      Additional functionality: it now saves the HTTP status into
+ *      csp->http->status and sets CT_TABOO for Status 206 (partial range)
+ *
+ *    Revision 1.32  2001/10/07 15:43:28  oes
+ *    Removed FEATURE_DENY_GZIP and replaced it with client_accept_encoding,
+ *       client_te and client_accept_encoding_adder, triggered by the new
+ *       +no-compression action. For HTTP/1.1 the Accept-Encoding header is
+ *       changed to allow only identity and chunked, and the TE header is
+ *       crunched. For HTTP/1.0, Accept-Encoding is crunched.
+ *
+ *    parse_http_request no longer does anything than parsing. The rewriting
+ *      of http->cmd and version mangling are gone. It now also recognizes
+ *      the put and delete methods and saves the url in http->url. Removed
+ *      unused variable.
+ *
+ *    renamed content_type and content_length to have the server_ prefix
+ *
+ *    server_content_type now only works if csp->content_type != CT_TABOO
+ *
+ *    added server_transfer_encoding, which
+ *      - Sets CT_TABOO to prohibit filtering if encoding compresses
+ *      - Raises the CSP_FLAG_CHUNKED flag if Encoding is "chunked"
+ *      - Change from "chunked" to "identity" if body was chunked
+ *        but has been de-chunked for filtering.
+ *
+ *    added server_content_md5 which crunches any Content-MD5 headers
+ *      if the body was modified.
+ *
+ *    made server_http11 conditional on +downgrade action
+ *
+ *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
+ *
+ *    Revision 1.31  2001/10/05 14:25:02  oes
+ *    Crumble Keep-Alive from Server
+ *
+ *    Revision 1.30  2001/09/29 12:56:03  joergs
+ *    IJB now changes HTTP/1.1 to HTTP/1.0 in requests and answers.
+ *
+ *    Revision 1.29  2001/09/24 21:09:24  jongfoster
+ *    Fixing 2 memory leaks that Guy spotted, where the paramater to
+ *    enlist() was not being free()d.
+ *
+ *    Revision 1.28  2001/09/22 16:32:28  jongfoster
+ *    Removing unused #includes.
+ *
+ *    Revision 1.27  2001/09/20 15:45:25  steudten
+ *
+ *    add casting from size_t to int for printf()
+ *    remove local variable shadow s2
+ *
+ *    Revision 1.26  2001/09/16 17:05:14  jongfoster
+ *    Removing unused #include showarg.h
+ *
+ *    Revision 1.25  2001/09/16 13:21:27  jongfoster
+ *    Changes to use new list functions.
+ *
+ *    Revision 1.24  2001/09/13 23:05:50  jongfoster
+ *    Changing the string paramater to the header parsers a "const".
+ *
+ *    Revision 1.23  2001/09/12 18:08:19  steudten
+ *
+ *    In parse_http_request() header rewriting miss the host value, so
+ *    from http://www.mydomain.com the result was just " / " not
+ *    http://www.mydomain.com/ in case we forward.
+ *
+ *    Revision 1.22  2001/09/10 10:58:53  oes
+ *    Silenced compiler warnings
+ *
+ *    Revision 1.21  2001/07/31 14:46:00  oes
+ *     - Persistant connections now suppressed
+ *     - sed() no longer appends empty header to csp->headers
+ *
+ *    Revision 1.20  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.19  2001/07/25 17:21:54  oes
+ *    client_uagent now saves copy of User-Agent: header value
+ *
+ *    Revision 1.18  2001/07/13 14:02:46  oes
+ *     - Included fix to repair broken HTTP requests that
+ *       don't contain a path, not even '/'.
+ *     - Removed all #ifdef PCRS
+ *     - content_type now always inspected and classified as
+ *       text, gif or other.
+ *     - formatting / comments
+ *
+ *    Revision 1.17  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.16  2001/06/29 13:32:42  oes
+ *    - Fixed a comment
+ *    - Adapted free_http_request
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.15  2001/06/03 19:12:38  oes
+ *    deleted const struct interceptors
+ *
+ *    Revision 1.14  2001/06/01 18:49:17  jongfoster
+ *    Replaced "list_share" with "list" - the tiny memory gain was not
+ *    worth the extra complexity.
+ *
+ *    Revision 1.13  2001/05/31 21:30:33  jongfoster
+ *    Removed list code - it's now in list.[ch]
+ *    Renamed "permission" to "action", and changed many features
+ *    to use the actions file rather than the global config.
+ *
+ *    Revision 1.12  2001/05/31 17:33:13  oes
+ *
+ *    CRLF -> LF
+ *
+ *    Revision 1.11  2001/05/29 20:11:19  joergs
+ *    '/ * inside comment' warning removed.
+ *
+ *    Revision 1.10  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.9  2001/05/28 17:26:33  jongfoster
+ *    Fixing segfault if last header was crunched.
+ *    Fixing Windows build (snprintf() is _snprintf() under Win32, but we
+ *    can use the cross-platform sprintf() instead.)
+ *
+ *    Revision 1.8  2001/05/27 22:17:04  oes
+ *
+ *    - re_process_buffer no longer writes the modified buffer
+ *      to the client, which was very ugly. It now returns the
+ *      buffer, which it is then written by chat.
+ *
+ *    - content_length now adjusts the Content-Length: header
+ *      for modified documents rather than crunch()ing it.
+ *      (Length info in csp->content_length, which is 0 for
+ *      unmodified documents)
+ *
+ *    - For this to work, sed() is called twice when filtering.
+ *
+ *    Revision 1.7  2001/05/27 13:19:06  oes
+ *    Patched Joergs solution for the content-length in.
+ *
+ *    Revision 1.6  2001/05/26 13:39:32  jongfoster
+ *    Only crunches Content-Length header if applying RE filtering.
+ *    Without this fix, Microsoft Windows Update wouldn't work.
+ *
+ *    Revision 1.5  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.4  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.3  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.2  2001/05/17 23:02:36  oes
+ *     - Made referrer option accept 'L' as a substitute for '§'
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:01  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
 #include "config.h"
 
+#ifndef _WIN32
 #include <stdio.h>
 #include <sys/types.h>
+#endif
+
 #include <stdlib.h>
 #include <ctype.h>
+#include <assert.h>
 #include <string.h>
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__OS2__)
 #include <unistd.h>
 #endif
 
 #include "project.h"
+#include "list.h"
 #include "parsers.h"
 #include "encode.h"
-#include "filters.h"
-#include "loaders.h"
-#include "showargs.h"
-#include "jcc.h"
 #include "ssplit.h"
 #include "errlog.h"
 #include "jbsockets.h"
 #include "miscutil.h"
+#include "list.h"
 
 const char parsers_h_rcs[] = PARSERS_H_VERSION;
 
@@ -77,8 +417,8 @@ const char parsers_h_rcs[] = PARSERS_H_VERSION;
  * as an array index.  Therefore we need to make sure that high-bit
  * characters generate +ve values, and ideally we also want to make
  * the argument match the declared parameter type of "int".
- * 
- * Why did they write a character function that can't take a simple 
+ *
+ * Why did they write a character function that can't take a simple
  * "char" argument?  Doh!
  */
 #define ijb_isupper(__X) isupper((int)(unsigned char)(__X))
@@ -92,89 +432,48 @@ const struct parsers client_patterns[] = {
    { "from:",                    5,    client_from },
    { "cookie:",                  7,    client_send_cookie },
    { "x-forwarded-for:",         16,   client_x_forwarded },
-   { "proxy-connection:",        17,   crumble },
-#ifdef DENY_GZIP
-   { "Accept-Encoding: gzip",    21,   crumble },
-#endif /* def DENY_GZIP */
-#if defined(DETECT_MSIE_IMAGES)
-   { "Accept:",                   7,   client_accept },
-#endif /* defined(DETECT_MSIE_IMAGES) */
-#ifdef FORCE_LOAD
-   { "Host:",                     5,   client_host },
-#endif /* def FORCE_LOAD */
+   { "Accept-Encoding:",         16,   client_accept_encoding },
+   { "TE:",                      3,    client_te },
+   { "Host:",                     5,   crumble },
 /* { "if-modified-since:",       18,   crumble }, */
+   { "Keep-Alive:",              11,   crumble },
+   { "connection:",              11,   crumble },
+   { "proxy-connection:",        17,   crumble },
    { NULL,                       0,    NULL }
 };
 
-const struct interceptors intercept_patterns[] = {
-   { "show-proxy-args",    14, show_proxy_args },
-#ifdef TRUST_FILES
-   { "ij-untrusted-url",   14, ij_untrusted_url },
-#endif /* def TRUST_FILES */
-   { NULL, 0, NULL }
-};
 
 const struct parsers server_patterns[] = {
+   { "HTTP",                4, server_http },
    { "set-cookie:",        11, server_set_cookie },
    { "connection:",        11, crumble },
-#ifdef PCRS
-   { "Content-Type:",      13, content_type },
-   { "Content-Length:",    15, crumble },
-#endif /* def PCRS */
+   { "Content-Type:",      13, server_content_type },
+   { "Content-Length:",    15, server_content_length },
+   { "Content-MD5:",       12, server_content_md5 },
+   { "Content-Encoding:",  17, server_content_encoding },
+   { "Transfer-Encoding:", 18, server_transfer_coding },
+   { "Keep-Alive:",        11, crumble },
    { NULL, 0, NULL }
 };
 
 
-void (* const add_client_headers[])(struct client_state *) = {
+const add_header_func_ptr add_client_headers[] = {
+   client_host_adder,
    client_cookie_adder,
    client_x_forwarded_adder,
    client_xtra_adder,
+   client_accept_encoding_adder,
+   connection_close_adder,
    NULL
 };
 
 
-void (* const add_server_headers[])(struct client_state *) = {
+const add_header_func_ptr add_server_headers[] = {
+   connection_close_adder,
    NULL
 };
 
 
-/*********************************************************************
- *
- * Function    :  match
- *
- * Description :  Do a `strncmpic' on every pattern in pats.
- *
- * Parameters  :
- *          1  :  buf = a string to match to a list of patterns
- *          2  :  pats = list of strings to compare against buf.
- *
- * Returns     :  Return the matching "struct parsers *",
- *                or NULL if no pattern matches.
- *
- *********************************************************************/
-static const struct parsers *match(char *buf, const struct parsers *pats)
-{
-   const struct parsers *v;
-
-   if (buf == NULL)
-   {
-      /* hit me */
-      log_error(LOG_LEVEL_ERROR, "NULL parameter to match()");
-      return(NULL);
-   }
-
-   for (v = pats; v->str ; v++)
-   {
-      if (strncmpic(buf, v->str, v->len) == 0)
-      {
-         return(v);
-      }
-   }
-   return(NULL);
-
-}
-
-
 /*********************************************************************
  *
  * Function    :  flush_socket
@@ -193,19 +492,22 @@ static const struct parsers *match(char *buf, const struct parsers *pats)
  *                file, the results are not portable.
  *
  *********************************************************************/
-int flush_socket(int fd, struct client_state *csp)
+int flush_socket(jb_socket fd, struct client_state *csp)
 {
    struct iob *iob = csp->iob;
-   int n = iob->eod - iob->cur;
+   int len = iob->eod - iob->cur;
 
-   if (n <= 0)
+   if (len <= 0)
    {
       return(0);
    }
 
-   n = write_socket(fd, iob->cur, n);
+   if (write_socket(fd, iob->cur, (size_t)len))
+   {
+      return(-1);
+   }
    iob->eod = iob->cur = iob->buf;
-   return(n);
+   return(len);
 
 }
 
@@ -214,70 +516,74 @@ int flush_socket(int fd, struct client_state *csp)
  *
  * Function    :  add_to_iob
  *
- * Description :  Add content to the buffered page.
+ * Description :  Add content to the buffered page, expanding the
+ *                buffer if necessary.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *          2  :  buf = holds the content to be added to the page
  *          3  :  n = number of bytes to be added
  *
- * Returns     :  Number of bytes in the content buffer.
+ * Returns     :  JB_ERR_OK on success, JB_ERR_MEMORY if out-of-memory
+ *                or buffer limit reached.
  *
  *********************************************************************/
-int add_to_iob(struct client_state *csp, char *buf, int n)
+jb_err add_to_iob(struct client_state *csp, char *buf, int n)
 {
    struct iob *iob = csp->iob;
-   int have, need;
+   size_t used, offset, need, want;
    char *p;
 
-   have = iob->eod - iob->cur;
+   if (n <= 0) return JB_ERR_OK;
 
-   if (n <= 0)
-   {
-      return(have);
-   }
-
-   need = have + n;
+   used   = iob->eod - iob->buf;
+   offset = iob->cur - iob->buf;
+   need   = used + n + 1;
 
-   if ((p = (char *)malloc(need + 1)) == NULL)
+   /*
+    * If the buffer can't hold the new data, extend it first.
+    * Use the next power of two if possible, else use the actual need.
+    */
+   if (need > csp->config->buffer_limit)
    {
-      log_error(LOG_LEVEL_ERROR, "malloc() iob failed: %E");
-      return(-1);
+      log_error(LOG_LEVEL_ERROR, "Buffer limit reached while extending the buffer (iob)");
+      return JB_ERR_MEMORY;
    }
 
-   if (have)
+   if (need > iob->size)
    {
-      /* there is something in the buffer - save it */
-      memcpy(p, iob->cur, have);
-
-      /* replace the buffer with the new space */
-      freez(iob->buf);
-      iob->buf = p;
+      for (want = csp->iob->size ? csp->iob->size : 512; want <= need;) want *= 2;
+      
+      if (want <= csp->config->buffer_limit && NULL != (p = (char *)realloc(iob->buf, want)))
+      {
+         iob->size = want;
+      }
+      else if (NULL != (p = (char *)realloc(iob->buf, need)))
+      {
+         iob->size = need;
+      }
+      else
+      {
+         log_error(LOG_LEVEL_ERROR, "Extending the buffer (iob) failed: %E");
+         return JB_ERR_MEMORY;
+      }
 
-      /* point to the end of the data */
-      p += have;
-   }
-   else
-   {
-      /* the buffer is empty, free it and reinitialize */
-      freez(iob->buf);
+      /* Update the iob pointers */
+      iob->cur = p + offset;
+      iob->eod = p + used;
       iob->buf = p;
    }
 
    /* copy the new data into the iob buffer */
-   memcpy(p, buf, n);
+   memcpy(iob->eod, buf, (size_t)n);
 
    /* point to the end of the data */
-   p += n;
+   iob->eod += n;
 
    /* null terminate == cheap insurance */
-   *p = '\0';
-
-   /* set the pointers to the new values */
-   iob->cur = iob->buf;
-   iob->eod = p;
+   *iob->eod = '\0';
 
-   return(need);
+   return JB_ERR_OK;
 
 }
 
@@ -314,12 +620,17 @@ char *get_header(struct client_state *csp)
    *p = '\0';
 
    ret = strdup(iob->cur);
+   if (ret == NULL)
+   {
+      /* FIXME No way to handle error properly */
+      log_error(LOG_LEVEL_FATAL, "Out of memory in get_header()");
+   }
 
    iob->cur = p+1;
 
-   if ((q = strchr(ret, '\r'))) *q = '\0';
+   if ((q = strchr(ret, '\r')) != NULL) *q = '\0';
 
-   /* is this a blank linke (i.e. the end of the header) ? */
+   /* is this a blank line (i.e. the end of the header) ? */
    if (*ret == '\0')
    {
       freez(ret);
@@ -333,123 +644,54 @@ char *get_header(struct client_state *csp)
 
 /*********************************************************************
  *
- * Function    :  enlist
+ * Function    :  get_header_value
  *
- * Description :  Append a string into a specified string list.
+ * Description :  Get the value of a given header from a chained list
+ *                of header lines or return NULL if no such header is
+ *                present in the list.
  *
  * Parameters  :
- *          1  :  h = pointer to list 'dummy' header
- *          2  :  s = string to add to the list
+ *          1  :  header_list = pointer to list
+ *          2  :  header_name = string with name of header to look for.
+ *                              Trailing colon required, capitalization
+ *                              doesn't matter.
  *
- * Returns     :  N/A
+ * Returns     :  NULL if not found, else value of header
  *
  *********************************************************************/
-void enlist(struct list *h, const char *s)
+char *get_header_value(const struct list *header_list, const char *header_name)
 {
-   struct list *n = (struct list *)malloc(sizeof(*n));
-   struct list *l;
-
-   if (n)
-   {
-      n->str  = strdup(s);
-      n->next = NULL;
-
-      if ((l = h->last))
-      {
-         l->next = n;
-      }
-      else
-      {
-         h->next = n;
-      }
-
-      h->last = n;
-   }
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  destroy_list
- *
- * Description :  Destroy a string list (opposite of enlist)
- *
- * Parameters  :
- *          1  :  h = pointer to list 'dummy' header
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-void destroy_list(struct list *h)
-{
-   struct list *p, *n;
-
-   for (p = h->next; p ; p = n)
-   {
-      n = p->next;
-      freez(p->str);
-      freez(p);
-   }
-
-   memset(h, '\0', sizeof(*h));
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  list_to_text
- *
- * Description :  "Flaten" a string list into 1 long \r\n delimited string.
- *
- * Parameters  :
- *          1  :  h = pointer to list 'dummy' header
- *
- * Returns     :  NULL on malloc error, else new long string.
- *
- *********************************************************************/
-static char *list_to_text(struct list *h)
-{
-   struct list *p;
+   struct list_entry *cur_entry;
    char *ret = NULL;
-   char *s;
-   int size;
-
-   size = 0;
-
-   for (p = h->next; p ; p = p->next)
-   {
-      if (p->str)
-      {
-         size += strlen(p->str) + 2;
-      }
-   }
-
-   if ((ret = (char *)malloc(size + 1)) == NULL)
-   {
-      return(NULL);
-   }
+   size_t length = 0;
 
-   ret[size] = '\0';
+   assert(header_list);
+   assert(header_name);
+   length = strlen(header_name);
 
-   s = ret;
-
-   for (p = h->next; p ; p = p->next)
+   for (cur_entry = header_list->first; cur_entry ; cur_entry = cur_entry->next)
    {
-      if (p->str)
+      if (cur_entry->str)
       {
-         strcpy(s, p->str);
-         s += strlen(s);
-         *s++ = '\r'; *s++ = '\n';
+         if (!strncmpic(cur_entry->str, header_name, length))
+         {
+            /*
+             * Found: return pointer to start of value
+             */
+            ret = (char *) (cur_entry->str + length);
+            while (*ret && ijb_isspace(*ret)) ret++;
+            return(ret);
+         }
       }
    }
 
-   return(ret);
+   /* 
+    * Not found
+    */
+   return NULL;
 
 }
 
-
 /*********************************************************************
  *
  * Function    :  sed
@@ -468,272 +710,336 @@ static char *list_to_text(struct list *h)
  *                headers (client or server)
  *          3  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  Single pointer to a fully formed header.
+ * Returns     :  Single pointer to a fully formed header, or NULL
+ *                on out-of-memory error.
  *
  *********************************************************************/
-char *sed(const struct parsers pats[], void (* const more_headers[])(struct client_state *), struct client_state *csp)
+char *sed(const struct parsers pats[],
+          const add_header_func_ptr more_headers[],
+          struct client_state *csp)
 {
-   struct list *p;
+   struct list_entry *p;
    const struct parsers *v;
-   char *hdr;
-   void (* const *f)();
+   const add_header_func_ptr *f;
+   jb_err err = JB_ERR_OK;
 
-   for (p = csp->headers->next; p ; p = p->next)
+   for (v = pats; (err == JB_ERR_OK) && (v->str != NULL) ; v++)
    {
-      log_error(LOG_LEVEL_HEADER, "scan: %s", p->str);
-
-      if ((v = match(p->str, pats)))
+      for (p = csp->headers->first; (err == JB_ERR_OK) && (p != NULL) ; p = p->next)
       {
-         hdr = v->parser(v, p->str, csp);
-         freez(p->str);
-         p->str = hdr;
-      }
+         /* Header crunch()ed in previous run? -> ignore */
+         if (p->str == NULL) continue;
 
+         if (v == pats) log_error(LOG_LEVEL_HEADER, "scan: %s", p->str);
+
+         if (strncmpic(p->str, v->str, v->len) == 0)
+         {
+            err = v->parser(csp, (char **)&(p->str));
+         }
+      }
    }
 
    /* place any additional headers on the csp->headers list */
-   for (f = more_headers; *f ; f++)
+   for (f = more_headers; (err == JB_ERR_OK) && (*f) ; f++)
    {
-      (*f)(csp);
+      err = (*f)(csp);
    }
 
-   /* add the blank line at the end of the header */
-   enlist(csp->headers, "");
+   if (err != JB_ERR_OK)
+   {
+      return NULL;
+   }
 
-   hdr = list_to_text(csp->headers);
+   return list_to_text(csp->headers);
+}
 
-   return(hdr);
 
-}
+/* here begins the family of parser functions that reformat header lines */
 
 
 /*********************************************************************
  *
- * Function    :  free_http_request
+ * Function    :  crumble
  *
- * Description :  Freez a http_request structure
+ * Description :  This is called if a header matches a pattern to "crunch"
  *
  * Parameters  :
- *          1  :  http = points to a http_request structure to free
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  N/A
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-void free_http_request(struct http_request *http)
+jb_err crumble(struct client_state *csp, char **header)
 {
-   freez(http->cmd);
-   freez(http->gpc);
-   freez(http->host);
-   freez(http->hostport);
-   freez(http->path);
-   freez(http->ver);
-
+   log_error(LOG_LEVEL_HEADER, "crunch!");
+   freez(*header);
+   return JB_ERR_OK;
 }
 
 
 /*********************************************************************
  *
- * Function    :  parse_http_request
+ * Function    :  server_content_type
  *
- * Description :  Parse out the host and port from the URL.  Find the
- *                hostname & path, port (if ':'), and/or password (if '@')
+ * Description :  Set the content-type for filterable types (text/.*,
+ *                javascript and image/gif) unless filtering has been
+ *                forbidden (CT_TABOO) while parsing earlier headers.
  *
  * Parameters  :
- *          1  :  req = URL (or is it URI?) to break down
- *          2  :  http = pointer to the http structure to hold elements
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  N/A
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-void parse_http_request(char *req, struct http_request *http, struct client_state *csp)
+jb_err server_content_type(struct client_state *csp, char **header)
 {
-   char *buf, *v[10], *url, *p;
-   int n;
-
-   memset(http, '\0', sizeof(*http));
-
-   http->cmd = strdup(req);
-
-   buf = strdup(req);
-
-   n = ssplit(buf, " \r\n", v, SZ(v), 1, 1);
-
-   if (n == 3)
+   if (csp->content_type != CT_TABOO)
    {
-      /* this could be a CONNECT request */
-      if (strcmpic(v[0], "connect") == 0)
-      {
-         http->ssl      = 1;
-         http->gpc      = strdup(v[0]);
-         http->hostport = strdup(v[1]);
-         http->ver      = strdup(v[2]);
-      }
-
-#ifdef WEBDAV
-
-/* This next line is a little ugly, but it simplifies the if statement below. */
-/* Basically if using webDAV, we want the OR condition to use these too.      */
-
-/*
- * by haroon
- * These are the headers as defined in RFC2518 to add webDAV support
- */
+      if (strstr(*header, " text/")
+       || strstr(*header, "application/x-javascript"))
+         csp->content_type = CT_TEXT;
+      else if (strstr(*header, " image/gif"))
+         csp->content_type = CT_GIF;
+      else
+         csp->content_type = 0;
+   }
 
-#define OR_WEBDAV || \
-         (0 == strcmpic(v[0], "propfind")) || \
-         (0 == strcmpic(v[0], "proppatch")) || \
-         (0 == strcmpic(v[0], "move")) || \
-         (0 == strcmpic(v[0], "copy")) || \
-         (0 == strcmpic(v[0], "mkcol")) || \
-         (0 == strcmpic(v[0], "lock")) || \
-         (0 == strcmpic(v[0], "unlock"))
+   return JB_ERR_OK;
+}
 
-#else /* No webDAV support is enabled.  Provide an empty OR_WEBDAV macro. */
 
-#define OR_WEBDAV
+/*********************************************************************
+ *
+ * Function    :  server_transfer_coding
+ *
+ * Description :  - Prohibit filtering (CT_TABOO) if transfer coding compresses
+ *                - Raise the CSP_FLAG_CHUNKED flag if coding is "chunked"
+ *                - Change from "chunked" to "identity" if body was chunked
+ *                  but has been de-chunked for filtering.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
+ *
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err server_transfer_coding(struct client_state *csp, char **header)
+{
+   /*
+    * Turn off pcrs and gif filtering if body compressed
+    */
+   if (strstr(*header, "gzip") || strstr(*header, "compress") || strstr(*header, "deflate"))
+   {
+      csp->content_type = CT_TABOO;
+   }
 
-#endif
+   /*
+    * Raise flag if body chunked
+    */
+   if (strstr(*header, "chunked"))
+   {
+      csp->flags |= CSP_FLAG_CHUNKED;
 
-      /* or it could be a GET or a POST (possibly webDAV too) */
-      if ((strcmpic(v[0], "get")  == 0) ||
-          (strcmpic(v[0], "head") == 0) OR_WEBDAV ||
-          (strcmpic(v[0], "post") == 0))
+      /*
+       * If the body was modified, it has been
+       * de-chunked first, so adjust the header:
+       */
+      if (csp->flags & CSP_FLAG_MODIFIED)
       {
-         http->ssl      = 0;
-         http->gpc      = strdup(v[0]);
-         url            = v[1];
-         http->ver      = strdup(v[2]);
-
-         if (strncmpic(url, "http://",  7) == 0)
-         {
-            url += 7;
-         }
-         else if (strncmpic(url, "https://", 8) == 0)
-         {
-            url += 8;
-         }
-         else
-         {
-            url = NULL;
-         }
-
-         if (url && (p = strchr(url, '/')))
-         {
-            http->path = strdup(p);
-            *p = '\0';
-            http->hostport = strdup(url);
-         }
+         freez(*header);
+         *header = strdup("Transfer-Encoding: identity");
+         return (header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
       }
    }
 
-   freez(buf);
+   return JB_ERR_OK;
+}
 
 
-   if (http->hostport == NULL)
+/*********************************************************************
+ *
+ * Function    :  server_content_encoding
+ *
+ * Description :  Prohibit filtering (CT_TABOO) if content encoding compresses
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
+ *
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err server_content_encoding(struct client_state *csp, char **header)
+{
+   /*
+    * Turn off pcrs and gif filtering if body compressed
+    */
+   if (strstr(*header, "gzip") || strstr(*header, "compress") || strstr(*header, "deflate"))
    {
-      free_http_request(http);
-      return;
+      csp->content_type = CT_TABOO;
    }
 
-   buf = strdup(http->hostport);
-
+   return JB_ERR_OK;
 
-   /* check if url contains password */
-   n = ssplit(buf, "@", v, SZ(v), 1, 1);
-   if (n == 2)
-   {
-      char * newbuf = NULL;
-      newbuf = strdup(v[1]);
-      freez(buf);
-      buf = newbuf;
-   }
+}
 
-   n = ssplit(buf, ":", v, SZ(v), 1, 1);
 
-   if (n == 1)
+/*********************************************************************
+ *
+ * Function    :  server_content_length
+ *
+ * Description :  Adjust Content-Length header if we modified
+ *                the body.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
+ *
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err server_content_length(struct client_state *csp, char **header)
+{
+   if (csp->content_length != 0) /* Content length has been modified */
    {
-      http->host = strdup(v[0]);
-      http->port = 80;
-   }
+      freez(*header);
+      *header = (char *) zalloc(100);
+      if (*header == NULL)
+      {
+         return JB_ERR_MEMORY;
+      }
 
-   if (n == 2)
-   {
-      http->host = strdup(v[0]);
-      http->port = atoi(v[1]);
+      sprintf(*header, "Content-Length: %d", (int) csp->content_length);
+
+      log_error(LOG_LEVEL_HEADER, "Adjust Content-Length to %d", (int) csp->content_length);
    }
 
-   freez(buf);
+   return JB_ERR_OK;
+}
 
-   if (http->host == NULL)
-   {
-      free_http_request(http);
-   }
 
-   if (http->path == NULL)
+/*********************************************************************
+ *
+ * Function    :  server_content_md5
+ *
+ * Description :  Crumble any Content-MD5 headers if the document was
+ *                modified. FIXME: Should we re-compute instead?
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
+ *
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err server_content_md5(struct client_state *csp, char **header)
+{
+   if (csp->flags & CSP_FLAG_MODIFIED)
    {
-      http->path = strdup("");
+      log_error(LOG_LEVEL_HEADER, "Crunching Content-MD5");
+      freez(*header);
    }
 
+   return JB_ERR_OK;
 }
 
 
-/* here begins the family of parser functions that reformat header lines */
-
-
 /*********************************************************************
  *
- * Function    :  crumble
+ * Function    :  client_accept_encoding
  *
- * Description :  This is called if a header matches a pattern to "crunch"
+ * Description :  Rewrite the client's Accept-Encoding header so that
+ *                if doesn't allow compression, if the action applies.
+ *                Note: For HTTP/1.0 the absence of the header is enough.
  *
  * Parameters  :
- *          1  :  v = Pointer to parsers structure, which basically holds
- *                headers (client or server) that we want to "crunch"
- *          2  :  s = header (from sed) to "crunch"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  Always NULL.
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *crumble(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_accept_encoding(struct client_state *csp, char **header)
 {
-   log_error(LOG_LEVEL_HEADER, "crunch!");
-   return(NULL);
+   if ((csp->action->flags & ACTION_NO_COMPRESSION) != 0)
+   {
+      log_error(LOG_LEVEL_HEADER, "Supressed offer to compress content");
 
-}
+      freez(*header);
+      if (!strcmpic(csp->http->ver, "HTTP/1.1"))
+      {
+         *header = strdup("Accept-Encoding: identity;q=1.0, *;q=0");
+         if (*header == NULL)
+         {
+            return JB_ERR_MEMORY;
+         }
+      }
+   }
 
+   return JB_ERR_OK;
+}
 
-#ifdef PCRS
 
 /*********************************************************************
  *
- * Function    :  content_type
+ * Function    :  client_te
  *
- * Description :  Is this a text/* or javascript MIME Type?
+ * Description :  Rewrite the client's TE header so that
+ *                if doesn't allow compression, if the action applies.
  *
  * Parameters  :
- *          1  :  v = ignored
- *          2  :  s = header string we are "considering"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  A duplicate string pointer to this header (ie. pass thru)
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *content_type(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_te(struct client_state *csp, char **header)
 {
-   if (strstr (s, " text/") || strstr (s, "application/x-javascript"))
-      csp->is_text = 1;
-   else
-      csp->is_text = 0;
-
-   return(strdup(s));
+   if ((csp->action->flags & ACTION_NO_COMPRESSION) != 0)
+   {
+      freez(*header);
+      log_error(LOG_LEVEL_HEADER, "Supressed offer to compress transfer");
+   }
 
+   return JB_ERR_OK;
 }
 
-#endif /* def PCRS */
-
-
 /*********************************************************************
  *
  * Function    :  client_referrer
@@ -742,78 +1048,81 @@ char *content_type(const struct parsers *v, char *s, struct client_state *csp)
  *                Called from `sed'.
  *
  * Parameters  :
- *          1  :  v = ignored
- *          2  :  s = header (from sed) to "crunch"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  NULL if crunched, or a malloc'ed string with the original
- *                or modified header
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_referrer(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_referrer(struct client_state *csp, char **header)
 {
-#ifdef FORCE_LOAD
+   const char *newval;
+
+#ifdef FEATURE_FORCE_LOAD
    /* Since the referrer can include the prefix even
     * even if the request itself is non-forced, we must
-    * clean it unconditionally 
+    * clean it unconditionally
     */
-   strclean(s, FORCE_PREFIX);
-#endif /* def FORCE_LOAD */
+   strclean(*header, FORCE_PREFIX);
+#endif /* def FEATURE_FORCE_LOAD */
 
-   csp->referrer = strdup(s);
-
-   if (referrer == NULL)
+   /*
+    * Are we sending referer?
+    */
+   if ((csp->action->flags & ACTION_HIDE_REFERER) == 0)
    {
-      log_error(LOG_LEVEL_HEADER, "crunch!");
-      return(NULL);
+      return JB_ERR_OK;
    }
 
-   if (*referrer == '.')
-   {
-      return(strdup(s));
-   }
+   freez(*header);
+
+   newval = csp->action->string[ACTION_STRING_REFERER];
 
-   if (*referrer == '@')
+   if ((newval == NULL) || (0 == strcmpic(newval, "block")) )
    {
-      if (csp->send_user_cookie)
-      {
-         return(strdup(s));
-      }
-      else
-      {
-         log_error(LOG_LEVEL_HEADER, "crunch!");
-         return(NULL);
-      }
+      /*
+       * Blocking referer
+       */
+      log_error(LOG_LEVEL_HEADER, "crunch!");
+      return JB_ERR_OK;
    }
+   else if (0 == strncmpic(newval, "http://", 7))
+   {
+      /*
+       * We have a specific (fixed) referer we want to send.
+       */
+      log_error(LOG_LEVEL_HEADER, "modified");
 
-   /*
-    * New option Â§: Forge a referer as http://[hostname:port of REQUEST]/
-    * to fool stupid checks for in-site links
-    */
+      *header = strdup("Referer: ");
+      string_append(header, newval);
 
-   if (*referrer == '§')
+      return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
+   }
+   else
    {
-      if (csp->send_user_cookie)
-      {
-         return(strdup(s));
-      }
-      else
+      /*
+       * Forge a referer as http://[hostname:port of REQUEST]/
+       * to fool stupid checks for in-site links
+       */
+      if (0 != strcmpic(newval, "forge"))
       {
-         log_error(LOG_LEVEL_HEADER, "crunch+forge!");
-         s = strsav(NULL, "Referer: ");
-         s = strsav(s, "http://");
-         s = strsav(s, csp->http->hostport);
-         s = strsav(s, "/");
-         return(s);
+         /*
+          * Invalid choice - but forge is probably the best default.
+          */
+         log_error(LOG_LEVEL_ERROR, "Bad parameter: +referer{%s}", newval);
       }
-   }
-
-   log_error(LOG_LEVEL_HEADER, "modified");
-
-   s = strsav( NULL, "Referer: " );
-   s = strsav( s, referrer );
-   return(s);
 
+      *header = strdup("Referer: http://");
+      string_append(header, csp->http->hostport);
+      string_append(header, "/");
+      log_error(LOG_LEVEL_HEADER, "crunch+forge to %s", *header);
+      
+      return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
+   }
 }
 
 
@@ -821,60 +1130,43 @@ char *client_referrer(const struct parsers *v, char *s, struct client_state *csp
  *
  * Function    :  client_uagent
  *
- * Description :  Handle the "user-agent" config setting properly.
- *                Called from `sed'.
+ * Description :  Handle the "user-agent" config setting properly
+ *                and remember its original value to enable browser
+ *                bug workarounds. Called from `sed'.
  *
  * Parameters  :
- *          1  :  v = ignored
- *          2  :  s = header (from sed) to "crunch"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  A malloc'ed pointer to the default agent, or
- *                a malloc'ed string pointer to this header (ie. pass thru).
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_uagent(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_uagent(struct client_state *csp, char **header)
 {
-#ifdef DETECT_MSIE_IMAGES
-   if (strstr (s, "MSIE "))
-   {
-      /* This is Microsoft Internet Explorer.
-       * Enable auto-detect.
-       */
-      csp->accept_types |= ACCEPT_TYPE_IS_MSIE;
-   }
-#endif /* def DETECT_MSIE_IMAGES */
-
-   if (uagent == NULL)
-   {
-      log_error(LOG_LEVEL_HEADER, "default");
-      return(strdup(DEFAULT_USER_AGENT));
-   }
+   const char *newval;
 
-   if (*uagent == '.')
+   if ((csp->action->flags & ACTION_HIDE_USER_AGENT) == 0)
    {
-      return(strdup(s));
+      return JB_ERR_OK;
    }
 
-   if (*uagent == '@')
+   newval = csp->action->string[ACTION_STRING_USER_AGENT];
+   if (newval == NULL)
    {
-      if (csp->send_user_cookie)
-      {
-         return(strdup(s));
-      }
-      else
-      {
-         log_error(LOG_LEVEL_HEADER, "default");
-         return(strdup(DEFAULT_USER_AGENT));
-      }
+      return JB_ERR_OK;
    }
 
    log_error(LOG_LEVEL_HEADER, "modified");
 
-   s = strsav( NULL, "User-Agent: " );
-   s = strsav( s, uagent );
-   return(s);
+   freez(*header);
+   *header = strdup("User-Agent: ");
+   string_append(header, newval);
 
+   return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
 }
 
 
@@ -885,42 +1177,25 @@ char *client_uagent(const struct parsers *v, char *s, struct client_state *csp)
  * Description :  Handle "ua-" headers properly.  Called from `sed'.
  *
  * Parameters  :
- *          1  :  v = ignored
- *          2  :  s = header (from sed) to "crunch"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  NULL if crunched, or a malloc'ed string to original header
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_ua(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_ua(struct client_state *csp, char **header)
 {
-   if (uagent == NULL)
+   if ((csp->action->flags & ACTION_HIDE_USER_AGENT) != 0)
    {
       log_error(LOG_LEVEL_HEADER, "crunch!");
-      return(NULL);
-   }
-
-   if (*uagent == '.')
-   {
-      return(strdup(s));
-   }
-
-   if (*uagent == '@')
-   {
-      if (csp->send_user_cookie)
-      {
-         return(strdup(s));
-      }
-      else
-      {
-         log_error(LOG_LEVEL_HEADER, "crunch!");
-         return(NULL);
-      }
+      freez(*header);
    }
 
-   log_error(LOG_LEVEL_HEADER, "crunch!");
-   return(NULL);
-
+   return JB_ERR_OK;
 }
 
 
@@ -932,34 +1207,44 @@ char *client_ua(const struct parsers *v, char *s, struct client_state *csp)
  *                Called from `sed'.
  *
  * Parameters  :
- *          1  :  v = ignored
- *          2  :  s = header (from sed) to "crunch"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  NULL if crunched, or a malloc'ed string to
- *                modified/original header.
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_from(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_from(struct client_state *csp, char **header)
 {
-   /* if not set, zap it */
-   if (from == NULL)
+   const char *newval;
+
+   if ((csp->action->flags & ACTION_HIDE_FROM) == 0)
    {
-      log_error(LOG_LEVEL_HEADER, "crunch!");
-      return(NULL);
+      return JB_ERR_OK;
    }
 
-   if (*from == '.')
+   freez(*header);
+
+   newval = csp->action->string[ACTION_STRING_FROM];
+
+   /*
+    * Are we blocking the e-mail address?
+    */
+   if ((newval == NULL) || (0 == strcmpic(newval, "block")) )
    {
-      return(strdup(s));
+      log_error(LOG_LEVEL_HEADER, "crunch!");
+      return JB_ERR_OK;
    }
 
    log_error(LOG_LEVEL_HEADER, " modified");
 
-   s = strsav( NULL, "From: " );
-   s = strsav( s, from );
-   return(s);
+   *header = strdup("From: ");
+   string_append(header, newval);
 
+   return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK;
 }
 
 
@@ -972,18 +1257,24 @@ char *client_from(const struct parsers *v, char *s, struct client_state *csp)
  *                else we crunch it.  Mmmmmmmmmmm ... cookie ......
  *
  * Parameters  :
- *          1  :  v = pattern of cookie `sed' found matching
- *          2  :  s = header (from sed) to "crunch"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  Always NULL.
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_send_cookie(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_send_cookie(struct client_state *csp, char **header)
 {
-   if (csp->send_user_cookie)
+   jb_err result = JB_ERR_OK;
+
+   if ((csp->action->flags & ACTION_NO_COOKIE_READ) == 0)
    {
-      enlist(csp->cookie_list, s + v->len + 1);
+      /* strlen("cookie: ") == 8 */
+      result = enlist(csp->cookie_list, *header + 8);
    }
    else
    {
@@ -991,11 +1282,12 @@ char *client_send_cookie(const struct parsers *v, char *s, struct client_state *
    }
 
    /*
-    * Always return NULL here.  The cookie header
+    * Always remove the cookie here.  The cookie header
     * will be sent at the end of the header.
     */
-   return(NULL);
+   freez(*header);
 
+   return result;
 }
 
 
@@ -1007,71 +1299,91 @@ char *client_send_cookie(const struct parsers *v, char *s, struct client_state *
  *                also used in the add_client_headers list.  Called from `sed'.
  *
  * Parameters  :
- *          1  :  v = ignored
- *          2  :  s = header (from sed) to "crunch"
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  Always NULL.
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_x_forwarded(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_x_forwarded(struct client_state *csp, char **header)
 {
-   if (add_forwarded)
+   if ((csp->action->flags & ACTION_HIDE_FORWARDED) == 0)
    {
-      csp->x_forwarded = strdup(s);
-   }
-
-   /*
-    * Always return NULL, since this information
-    * will be sent at the end of the header.
-    */
+      /* Save it so we can re-add it later */
+      freez(csp->x_forwarded);
+      csp->x_forwarded = *header;
 
-   return(NULL);
+      /*
+       * Always set *header = NULL, since this information
+       * will be sent at the end of the header.
+       */
+      *header = NULL;
+   }
+   else
+   {
+      freez(*header);
+      log_error(LOG_LEVEL_HEADER, " crunch!");
+   }
 
+   return JB_ERR_OK;
 }
 
-#if defined(DETECT_MSIE_IMAGES)
+/* the following functions add headers directly to the header list */
+
 /*********************************************************************
  *
- * Function    :  client_accept
+ * Function    :  client_host_adder
  *
- * Description :  Detect whether the client wants HTML or an image.
- *                Clients do not always make this information available
- *                in a sane way.  Always passes the header through
- *                the proxy unchanged.
+ * Description :  (re)adds the host header. Called from `sed'.
  *
  * Parameters  :
- *          1  :  v = Ignored.
- *          2  :  s = Header string.  Null terminated.
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  Duplicate of argument s.
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_accept(const struct parsers *v, char *s, struct client_state *csp)
+jb_err client_host_adder(struct client_state *csp)
 {
-#ifdef DETECT_MSIE_IMAGES
-   if (strstr (s, "image/gif"))
+   char *p;
+   char *pos;
+   jb_err err;
+
+   if ( !csp->http->hostport || !*(csp->http->hostport))
    {
-      /* Client will accept HTML.  If this seems counterintuitive,
-       * blame Microsoft. 
-       */
-      csp->accept_types |= ACCEPT_TYPE_MSIE_HTML;
+      return JB_ERR_OK;
+   }
+
+   p = strdup("Host: ");
+   /*
+   ** remove 'user:pass@' from 'proto://user:pass@host'
+   */
+   if ( (pos = strchr( csp->http->hostport, '@')) != NULL )
+   {
+       string_append(&p, pos+1);
    }
    else
    {
-      csp->accept_types |= ACCEPT_TYPE_MSIE_IMAGE;
+      string_append(&p, csp->http->hostport);
    }
-#endif /* def DETECT_MSIE_IMAGES */
 
-   return(strdup(s));
+   if (p == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
 
-}
-#endif /* defined(DETECT_MSIE_IMAGES) */
+   log_error(LOG_LEVEL_HEADER, "addh: %s", p);
 
+   err = enlist(csp->headers, p);
 
+   freez(p);
 
-/* the following functions add headers directly to the header list */
+   return err;
+}
 
 
 /*********************************************************************
@@ -1083,50 +1395,90 @@ char *client_accept(const struct parsers *v, char *s, struct client_state *csp)
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  N/A
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-void client_cookie_adder(struct client_state *csp)
+jb_err client_cookie_adder(struct client_state *csp)
 {
-   struct list *l;
-   char *tmp = NULL;
-   char *e;
+   struct list_entry *lst;
+   char *tmp;
+   struct list_entry *list1 = csp->cookie_list->first;
+   struct list_entry *list2 = csp->action->multi[ACTION_MULTI_WAFER]->first;
+   int first_cookie = 1;
+   jb_err err;
+
+   if ((list1 == NULL) && (list2 == NULL))
+   {
+      /* Nothing to do */
+      return JB_ERR_OK;
+   }
+
+   tmp = strdup("Cookie: ");
 
-   for (l = csp->cookie_list->next; l ; l = l->next)
+   for (lst = list1; lst ; lst = lst->next)
    {
-      if (tmp)
+      if (first_cookie)
+      {
+         first_cookie = 0;
+      }
+      else
       {
-         tmp = strsav(tmp, "; ");
+         string_append(&tmp, "; ");
       }
-      tmp = strsav(tmp, l->str);
+      string_append(&tmp, lst->str);
    }
 
-   for (l = wafer_list->next;  l ; l = l->next)
+   for (lst = list2;  lst ; lst = lst->next)
    {
-      if (tmp)
+      if (first_cookie)
       {
-         tmp = strsav(tmp, "; ");
+         first_cookie = 0;
       }
-
-      if ((e = cookie_encode(l->str)))
+      else
       {
-         tmp = strsav(tmp, e);
-         freez(e);
+         string_append(&tmp, "; ");
       }
+      string_join(&tmp, cookie_encode(lst->str));
    }
 
-   if (tmp)
+   if (tmp == NULL)
    {
-      char *ret;
+      return JB_ERR_MEMORY;
+   }
 
-      ret = strdup("Cookie: ");
-      ret = strsav(ret, tmp);
-      log_error(LOG_LEVEL_HEADER, "addh: %s", ret);
-      enlist(csp->headers, ret);
-      freez(tmp);
-      freez(ret);
+   log_error(LOG_LEVEL_HEADER, "addh: %s", tmp);
+   err = enlist(csp->headers, tmp);
+   free(tmp);
+   return err;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  client_accept_encoding_adder
+ *
+ * Description :  Add an Accept-Encoding header to the client's request
+ *                that disables compression if the action applies, and
+ *                the header is not already there. Called from `sed'.
+ *                Note: For HTTP/1.0, the absence of the header is enough.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err client_accept_encoding_adder(struct client_state *csp)
+{
+   if (   ((csp->action->flags & ACTION_NO_COMPRESSION) != 0)
+       && (!strcmpic(csp->http->ver, "HTTP/1.1")) )
+   {
+      return enlist_unique(csp->headers, "Accept-Encoding: identity;q=1.0, *;q=0", 16);
    }
 
+   return JB_ERR_OK;
 }
 
 
@@ -1139,19 +1491,28 @@ void client_cookie_adder(struct client_state *csp)
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  N/A
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-void client_xtra_adder(struct client_state *csp)
+jb_err client_xtra_adder(struct client_state *csp)
 {
-   struct list *l;
+   struct list_entry *lst;
+   jb_err err;
 
-   for (l = xtra_list->next; l ; l = l->next)
+   for (lst = csp->action->multi[ACTION_MULTI_ADD_HEADER]->first;
+        lst ; lst = lst->next)
    {
-      log_error(LOG_LEVEL_HEADER, "addh: %s", l->str);
-      enlist(csp->headers, l->str);
+      log_error(LOG_LEVEL_HEADER, "addh: %s", lst->str);
+      err = enlist(csp->headers, lst->str);
+      if (err)
+      {
+         return err;
+      }
+
    }
 
+   return JB_ERR_OK;
 }
 
 
@@ -1164,102 +1525,234 @@ void client_xtra_adder(struct client_state *csp)
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  N/A
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-void client_x_forwarded_adder(struct client_state *csp)
+jb_err client_x_forwarded_adder(struct client_state *csp)
 {
    char *p = NULL;
+   jb_err err;
 
-   if (add_forwarded == 0) return;
+   if ((csp->action->flags & ACTION_HIDE_FORWARDED) != 0)
+   {
+      return JB_ERR_OK;
+   }
 
    if (csp->x_forwarded)
    {
-      p = strsav(p, csp->x_forwarded);
-      p = strsav(p, ", ");
-      p = strsav(p, csp->ip_addr_str);
+      p = strdup(csp->x_forwarded);
+      string_append(&p, ", ");
    }
    else
    {
-      p = strsav(p, "X-Forwarded-For: ");
-      p = strsav(p, csp->ip_addr_str);
+      p = strdup("X-Forwarded-For: ");
+   }
+   string_append(&p, csp->ip_addr_str);
+
+   if (p == NULL)
+   {
+      return JB_ERR_MEMORY;
    }
 
    log_error(LOG_LEVEL_HEADER, "addh: %s", p);
-   enlist(csp->headers, p);
+   err = enlist(csp->headers, p);
+   free(p);
 
+   return err;
 }
 
 
 /*********************************************************************
  *
- * Function    :  server_set_cookie
+ * Function    :  connection_close_adder
  *
- * Description :  Handle the server "cookie" header properly.
- *                Log cookie to the jar file.  Then "crunch" it,
- *                or accept it.  Called from `sed'.
+ * Description :  Adds a "Connection: close" header to csp->headers
+ *                as a temporary fix for the needed but missing HTTP/1.1
+ *                support. Called from `sed'.
+ *                FIXME: This whole function shouldn't be neccessary!
  *
  * Parameters  :
- *          1  :  v = parser pattern that matched this header
- *          2  :  s = header that matched this pattern
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  `crumble' or a newly malloc'ed string.
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *server_set_cookie(const struct parsers *v, char *s, struct client_state *csp)
+jb_err connection_close_adder(struct client_state *csp)
 {
-#ifdef JAR_FILES
-   if (jar)
+   return enlist(csp->headers, "Connection: close");
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  server_http
+ *
+ * Description :  - Save the HTTP Status into csp->http->status
+ *                - Set CT_TABOO to prevent filtering if the answer
+ *                  is a partial range (HTTP status 206)
+ *                - Rewrite HTTP/1.1 answers to HTTP/1.0 if +downgrade
+ *                  action applies.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
+ *
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err server_http(struct client_state *csp, char **header)
+{
+   sscanf(*header, "HTTP/%*d.%*d %d", &(csp->http->status));
+   if (csp->http->status == 206)
    {
-      fprintf(jar, "%s\t%s\n", csp->http->host, (s + v->len + 1));
+      csp->content_type = CT_TABOO;
    }
-#endif /* def JAR_FILES */
 
-   if (csp->accept_server_cookie == 0)
+   if ((csp->action->flags & ACTION_DOWNGRADE) != 0)
    {
-      return(crumble(v, s, csp));
+      (*header)[7] = '0';
+      log_error(LOG_LEVEL_HEADER, "Downgraded answer to HTTP/1.0");
    }
 
-   return(strdup(s));
-
+   return JB_ERR_OK;
 }
 
 
-#ifdef FORCE_LOAD
 /*********************************************************************
  *
- * Function    :  client_host
+ * Function    :  server_set_cookie
  *
- * Description :  Clean the FORCE_PREFIX out of the 'host' http
- *                header, if we use force
+ * Description :  Handle the server "cookie" header properly.
+ *                Log cookie to the jar file.  Then "crunch" it,
+ *                or accept it.  Called from `sed'.
  *
  * Parameters  :
- *          1  :  v = ignored
- *          2  :  s = header (from sed) to clean
- *          3  :  csp = Current client state (buffers, headers, etc...)
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  header = On input, pointer to header to modify.
+ *                On output, pointer to the modified header, or NULL
+ *                to remove the header.  This function frees the
+ *                original string if necessary.
  *
- * Returns     :  A malloc'ed pointer to the cleaned host header 
+ * Returns     :  JB_ERR_OK on success, or
+ *                JB_ERR_MEMORY on out-of-memory error.
  *
  *********************************************************************/
-char *client_host(const struct parsers *v, char *s, struct client_state *csp)
+jb_err server_set_cookie(struct client_state *csp, char **header)
 {
-   char *cleanhost = strdup(s);
-   if(csp->force)
-      strclean(cleanhost, FORCE_PREFIX);
-   return(cleanhost);
+#ifdef FEATURE_COOKIE_JAR
+   if (csp->config->jar)
+   {
+      /*
+       * Write timestamp into outbuf.
+       *
+       * Complex because not all OSs have tm_gmtoff or
+       * the %z field in strftime()
+       */
+      char tempbuf[ BUFFER_SIZE ];
+      time_t now; 
+      struct tm tm_now; 
+      time (&now); 
+#ifdef HAVE_LOCALTIME_R
+      tm_now = *localtime_r(&now, &tm_now);
+#else
+      tm_now = *localtime (&now); 
+#endif
+      strftime(tempbuf, BUFFER_SIZE-6, "%b %d %H:%M:%S ", &tm_now); 
+
+      /* strlen("set-cookie: ") = 12 */
+      fprintf(csp->config->jar, "%s %s\t%s\n", tempbuf, csp->http->host, *header + 12);
+   }
+#endif /* def FEATURE_COOKIE_JAR */
+
+   if ((csp->action->flags & ACTION_NO_COOKIE_SET) != 0)
+   {
+      return crumble(csp, header);
+   }
+   else if ((csp->action->flags & ACTION_NO_COOKIE_KEEP) != 0)
+   {
+      /* Flag whether or not to log a message */
+      int changed = 0;
+
+      /* A variable to store the tag we're working on */
+      char *cur_tag;
+
+      /* Skip "Set-Cookie:" (11 characters) in header */
+      cur_tag = *header + 11;
+
+      /* skip whitespace between "Set-Cookie:" and value */
+      while (*cur_tag && ijb_isspace(*cur_tag))
+      {
+         cur_tag++;
+      }
+
+      /* Loop through each tag in the cookie */
+      while (*cur_tag)
+      {
+         /* Find next tag */
+         char *next_tag = strchr(cur_tag, ';');
+         if (next_tag != NULL)
+         {
+            /* Skip the ';' character itself */
+            next_tag++;
+
+            /* skip whitespace ";" and start of tag */
+            while (*next_tag && ijb_isspace(*next_tag))
+            {
+               next_tag++;
+            }
+         }
+         else
+         {
+            /* "Next tag" is the end of the string */
+            next_tag = cur_tag + strlen(cur_tag);
+         }
+
+         /* Is this the "Expires" tag? */
+         if (strncmpic(cur_tag, "expires=", 8) == 0)
+         {
+            /* Delete the tag by copying the rest of the string over it.
+             * (Note that we cannot just use "strcpy(cur_tag, next_tag)",
+             * since the behaviour of strcpy is undefined for overlapping
+             * strings.)
+             */
+            memmove(cur_tag, next_tag, strlen(next_tag) + 1);
+
+            /* That changed the header, need to issue a log message */
+            changed = 1;
+
+            /* Note that the next tag has now been moved to *cur_tag,
+             * so we do not need to update the cur_tag pointer.
+             */
+         }
+         else
+         {
+            /* Move on to next cookie tag */
+            cur_tag = next_tag;
+         }
+      }
+
+      if (changed)
+      {
+         log_error(LOG_LEVEL_HEADER, "Changed cookie to a temporary one.");
+      }
+   }
+
+   return JB_ERR_OK;
 }
-#endif /* def FORCE_LOAD */
-#ifdef FORCE_LOAD 
+
+
+#ifdef FEATURE_FORCE_LOAD
 /*********************************************************************
  *
  * Function    :  strclean
  *
- * Description :  In-Situ-Eliminate all occurances of substring in 
+ * Description :  In-Situ-Eliminate all occurances of substring in
  *                string
  *
  * Parameters  :
@@ -1274,12 +1767,12 @@ int strclean(const char *string, const char *substring)
    int hits = 0, len = strlen(substring);
    char *pos, *p;
 
-   while((pos = strstr(string, substring)))
+   while((pos = strstr(string, substring)) != NULL)
    {
       p = pos + len;
       do
       {
-         *(p - len) = *p; 
+         *(p - len) = *p;
       }
       while (*p++ != '\0');
 
@@ -1288,7 +1781,7 @@ int strclean(const char *string, const char *substring)
 
    return(hits);
 }
-#endif /* def FORCE_LOAD */
+#endif /* def FEATURE_FORCE_LOAD */
 
 
 /*
index 1402544..837bac4 100644 (file)
--- a/parsers.h
+++ b/parsers.h
@@ -1,9 +1,9 @@
-#ifndef _PARSERS_H
-#define _PARSERS_H
-#define PARSERS_H_VERSION "$Id: parsers.h,v 1.1 2001/05/13 21:57:06 administrator Exp $"
+#ifndef PARSERS_H_INCLUDED
+#define PARSERS_H_INCLUDED
+#define PARSERS_H_VERSION "$Id: parsers.h,v 1.25 2002/03/26 22:29:55 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/parsers.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/parsers.h,v $
  *
  * Purpose     :  Declares functions to parse/crunch headers and pages.
  *                Functions declared include:
  *                   `client_x_forwarded_adder', `client_xtra_adder',
  *                   `content_type', `crumble', `destroy_list', `enlist',
  *                   `flush_socket', `free_http_request', `get_header',
- *                   `list_to_text', `match', `parse_http_request', `sed',
+ *                   `list_to_text', `parse_http_request', `sed',
  *                   and `server_set_cookie'.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: parsers.h,v $
+ *    Revision 1.25  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.24  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.23  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.22  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.21  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.20  2002/02/20 23:15:13  jongfoster
+ *    Parsing functions now handle out-of-memory gracefully by returning
+ *    an error code.
+ *
+ *    Revision 1.19  2002/01/17 21:03:47  jongfoster
+ *    Moving all our URL and URL pattern parsing code to urlmatch.c.
+ *
+ *    Revision 1.18  2001/10/26 17:40:23  oes
+ *    Introduced get_header_value()
+ *    Removed client_accept()
+ *
+ *    Revision 1.17  2001/10/13 12:47:32  joergs
+ *    Removed client_host, added client_host_adder
+ *
+ *    Revision 1.16  2001/10/07 18:50:16  oes
+ *    Added server_content_encoding, renamed server_transfer_encoding
+ *
+ *    Revision 1.15  2001/10/07 18:01:55  oes
+ *    Changed server_http11 to server_http
+ *
+ *    Revision 1.14  2001/10/07 15:45:48  oes
+ *    added client_accept_encoding, client_te, client_accept_encoding_adder
+ *
+ *    renamed content_type and content_length
+ *
+ *    fixed client_host and strclean prototypes
+ *
+ *    Revision 1.13  2001/09/29 12:56:03  joergs
+ *    IJB now changes HTTP/1.1 to HTTP/1.0 in requests and answers.
+ *
+ *    Revision 1.12  2001/09/13 23:05:50  jongfoster
+ *    Changing the string paramater to the header parsers a "const".
+ *
+ *    Revision 1.11  2001/07/31 14:46:53  oes
+ *    Added prototype for connection_close_adder
+ *
+ *    Revision 1.10  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.9  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.8  2001/07/13 14:01:54  oes
+ *    Removed all #ifdef PCRS
+ *
+ *    Revision 1.7  2001/06/29 13:32:14  oes
+ *    Removed logentry from cancelled commit
+ *
+ *    Revision 1.6  2001/06/03 19:12:38  oes
+ *    deleted const struct interceptors
+ *
+ *    Revision 1.5  2001/05/31 21:30:33  jongfoster
+ *    Removed list code - it's now in list.[ch]
+ *    Renamed "permission" to "action", and changed many features
+ *    to use the actions file rather than the global config.
+ *
+ *    Revision 1.4  2001/05/27 13:19:06  oes
+ *    Patched Joergs solution for the content-length in.
+ *
+ *    Revision 1.3  2001/05/26 13:39:32  jongfoster
+ *    Only crunches Content-Length header if applying RE filtering.
+ *    Without this fix, Microsoft Windows Update wouldn't work.
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:01  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -55,47 +174,45 @@ extern "C" {
 
 extern const struct parsers client_patterns[];
 extern const struct parsers server_patterns[];
-extern const struct interceptors intercept_patterns[];
 
-extern void (* const add_client_headers[])(struct client_state *);
-extern void (* const add_server_headers[])(struct client_state *);
+extern const add_header_func_ptr add_client_headers[];
+extern const add_header_func_ptr add_server_headers[];
 
-extern int flush_socket(int fd, struct client_state *csp);
-extern int add_to_iob(struct client_state *csp, char *buf, int n);
+extern int flush_socket(jb_socket fd, struct client_state *csp);
+extern jb_err add_to_iob(struct client_state *csp, char *buf, int n);
 extern char *get_header(struct client_state *csp);
-extern void enlist(struct list *h, const char *s);
-extern void destroy_list(struct list *h);
-
-extern char *sed(const struct parsers pats[], void (* const more_headers[])(struct client_state *), struct client_state *csp);
-
-extern void free_http_request(struct http_request *http);
-extern void parse_http_request(char *req, struct http_request *http, struct client_state *csp);
-
-extern char *crumble(const struct parsers *v, char *s, struct client_state *csp);
-
-extern char *client_referrer(const struct parsers *v, char *s, struct client_state *csp);
-extern char *client_uagent(const struct parsers *v, char *s, struct client_state *csp);
-extern char *client_ua(const struct parsers *v, char *s, struct client_state *csp);
-extern char *client_from(const struct parsers *v, char *s, struct client_state *csp);
-extern char *client_send_cookie(const struct parsers *v, char *s, struct client_state *csp);
-extern char *client_x_forwarded(const struct parsers *v, char *s, struct client_state *csp);
-extern void client_cookie_adder(struct client_state *csp);
-extern void client_xtra_adder(struct client_state *csp);
-extern void client_x_forwarded_adder(struct client_state *csp);
-extern char *server_set_cookie(const struct parsers *v, char *s, struct client_state *csp);
-
-#ifdef PCRS
-extern char *content_type(const struct parsers *v, char *s, struct client_state *csp);
-#endif /* def PCRS */
-
-#ifdef FORCE_LOAD
-char *client_host(const struct parsers *v, char *s, struct client_state *csp);
-int strclean(const char *string, const char *substring);
-#endif /* def FORCE_LOAD */
-
-#if defined(DETECT_MSIE_IMAGES)
-extern char *client_accept(const struct parsers *v, char *s, struct client_state *csp);
-#endif /* defined(DETECT_MSIE_IMAGES) */
+extern char *get_header_value(const struct list *header_list, const char *header_name);
+extern char *sed(const struct parsers pats[], const add_header_func_ptr more_headers[], struct client_state *csp);
+
+extern jb_err crumble                (struct client_state *csp, char **header);
+extern jb_err client_referrer        (struct client_state *csp, char **header);
+extern jb_err client_uagent          (struct client_state *csp, char **header);
+extern jb_err client_ua              (struct client_state *csp, char **header);
+extern jb_err client_from            (struct client_state *csp, char **header);
+extern jb_err client_send_cookie     (struct client_state *csp, char **header);
+extern jb_err client_x_forwarded     (struct client_state *csp, char **header);
+extern jb_err client_accept_encoding (struct client_state *csp, char **header);
+extern jb_err client_te              (struct client_state *csp, char **header);
+
+extern jb_err client_host_adder           (struct client_state *csp);
+extern jb_err client_cookie_adder         (struct client_state *csp);
+extern jb_err client_xtra_adder           (struct client_state *csp);
+extern jb_err client_accept_encoding_adder(struct client_state *csp);
+extern jb_err client_x_forwarded_adder    (struct client_state *csp);
+
+extern jb_err connection_close_adder      (struct client_state *csp); 
+
+extern jb_err server_set_cookie      (struct client_state *csp, char **header);
+extern jb_err server_content_type    (struct client_state *csp, char **header);
+extern jb_err server_content_length  (struct client_state *csp, char **header);
+extern jb_err server_content_md5     (struct client_state *csp, char **header);
+extern jb_err server_content_encoding(struct client_state *csp, char **header);
+extern jb_err server_transfer_coding (struct client_state *csp, char **header);
+extern jb_err server_http            (struct client_state *csp, char **header);
+
+#ifdef FEATURE_FORCE_LOAD
+extern int strclean(const char *string, const char *substring);
+#endif /* def FEATURE_FORCE_LOAD */
 
 /* Revision control strings from this header and associated .c file */
 extern const char parsers_rcs[];
@@ -105,7 +222,7 @@ extern const char parsers_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _PARSERS_H */
+#endif /* ndef PARSERS_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/pcre/.gitignore b/pcre/.gitignore
new file mode 100644 (file)
index 0000000..58124c0
--- /dev/null
@@ -0,0 +1,5 @@
+chartables.c
+dftables
+vc_dftables.plg
+vc_dftables
+vc_dftables_dbg
diff --git a/pcre/Makefile.in b/pcre/Makefile.in
new file mode 100644 (file)
index 0000000..94edf49
--- /dev/null
@@ -0,0 +1,219 @@
+
+# Makefile.in for PCRE (Perl-Compatible Regular Expression) library.
+
+#---------------------------------------------------------------------------#
+# To build mingw32 DLL uncomment the next two lines. This addition for      #
+# mingw32 was contributed by <Paul.Sokolovsky@technologist.com>. I (Philip  #
+# Hazel) don't know anything about it! There are some additional targets at #
+# the bottom of this Makefile.                                              #
+#---------------------------------------------------------------------------#
+#
+# include dll.mk
+# DLL_LDFLAGS=-s
+
+
+#---------------------------------------------------------------------------#
+# The next few lines are modified by "configure" to insert data that it is  #
+# given in its arguments, or which it finds out for itself.                 #
+#---------------------------------------------------------------------------#
+
+# BINDIR is the directory in which the pcregrep command is installed.
+# INCDIR is the directory in which the public header file pcre.h is installed.
+# LIBDIR is the directory in which the libraries are installed.
+# MANDIR is the directory in which the man pages are installed.
+# The pcretest program, as it is a test program, does not get installed
+# anywhere.
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+BINDIR = @bindir@
+LIBDIR = @libdir@
+INCDIR = @includedir@
+MANDIR = @mandir@
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+RANLIB = @RANLIB@
+UTF8   = @UTF8@
+
+# LIBTOOL defaults to "./libtool", which enables the building of shared
+# libraries. If "configure" is called with --disable-shared-libraries, LIBTOOL
+# is set to "", which stops shared libraries from being built, and LIBSUFFIX
+# is set to "a" instead of "la", which causes the shared libraries not to be
+# installed.
+
+LIBTOOL = @LIBTOOL@
+LIBSUFFIX = @LIBSUFFIX@
+
+# These are the version numbers for the shared libraries
+
+PCRELIBVERSION = @PCRE_LIB_VERSION@
+PCREPOSIXLIBVERSION = @PCRE_POSIXLIB_VERSION@
+
+
+#---------------------------------------------------------------------------#
+# A copy of install-sh is in this distribution and is used by default.      #
+#---------------------------------------------------------------------------#
+
+INSTALL = ./install-sh -c
+INSTALL_DATA = ${INSTALL} -m 644
+
+
+#---------------------------------------------------------------------------#
+# For almost all systems, the command to create a library is "ar cq", but   #
+# there is at least one where it is different, so this command must be      #
+# configurable. However, I haven't got round to learning how to make        #
+# "configure" find this out for itself. It is necessary to use a command    #
+# such as "make AR='ar -rc'" if you need to vary this. The setting of AR is #
+# *not* passed over to ./ltconfig, because it does its own setting up.      #
+#---------------------------------------------------------------------------#
+
+AR = ar cq
+
+
+##############################################################################
+
+
+OBJ = maketables.o get.o study.o pcre.o
+LOBJ = maketables.lo get.lo study.lo pcre.lo
+
+all:            libtool libpcre.$(LIBSUFFIX) libpcreposix.$(LIBSUFFIX) pcretest pcregrep
+
+libtool:        config.guess config.sub ltconfig ltmain.sh
+               @if test "$(LIBTOOL)" = "./libtool"; then \
+                 echo '--- Building libtool ---'; \
+                 CC=$(CC) CFLAGS='$(CFLAGS)' RANLIB='$(RANLIB)' ./ltconfig ./ltmain.sh; \
+                 echo '--- Built libtool ---'; fi
+
+pcregrep:       libpcre.$(LIBSUFFIX) pcregrep.o
+                 @echo ' '
+                 @echo '--- Building pcregrep utility'
+                 @echo ' '
+               $(LIBTOOL) $(CC) $(CFLAGS) -o pcregrep pcregrep.o libpcre.$(LIBSUFFIX)
+
+pcretest:       libpcre.$(LIBSUFFIX) libpcreposix.$(LIBSUFFIX) pcretest.o
+                 @echo ' '
+                 @echo '--- Building pcretest testing program'
+                 @echo ' '
+               $(LIBTOOL) $(PURIFY) $(CC) $(CFLAGS) -o pcretest pcretest.o \
+                 libpcre.$(LIBSUFFIX) libpcreposix.$(LIBSUFFIX)
+
+libpcre.a:      $(OBJ)
+               @echo ' '
+               @echo '--- Building static library: libpcre'
+               @echo ' '
+               -rm -f libpcre.a
+               $(AR) libpcre.a $(OBJ)
+               $(RANLIB) libpcre.a
+
+libpcre.la:     $(OBJ)
+               @echo ' '
+               @echo '--- Building shared library: libpcre'
+               @echo ' '
+               -rm -f libpcre.la
+               ./libtool $(CC) -version-info '$(PCRELIBVERSION)' -o libpcre.la -rpath $(LIBDIR) $(LOBJ)
+
+libpcreposix.a: pcreposix.o
+               @echo ' '
+               @echo '--- Building static library: libpcreposix'
+               @echo ' '
+               -rm -f libpcreposix.a
+               $(AR) libpcreposix.a pcreposix.o
+               $(RANLIB) libpcreposix.a
+
+libpcreposix.la: pcreposix.o
+               @echo ' '
+               @echo '--- Building shared library: libpcreposix'
+               @echo ' '
+               -rm -f libpcreposix.la
+               ./libtool $(CC) -version-info '$(PCREPOSIXLIBVERSION)' -o libpcreposix.la -rpath $(LIBDIR) pcreposix.lo
+
+pcre.o:         chartables.c pcre.c pcre.h internal.h config.h Makefile
+               $(LIBTOOL) $(CC) -c $(CFLAGS) $(UTF8) pcre.c
+
+pcreposix.o:    pcreposix.c pcreposix.h internal.h pcre.h config.h Makefile
+               $(LIBTOOL) $(CC) -c $(CFLAGS) pcreposix.c
+
+maketables.o:   maketables.c pcre.h internal.h config.h Makefile
+               $(LIBTOOL) $(CC) -c $(CFLAGS) maketables.c
+
+get.o:          get.c pcre.h internal.h config.h Makefile
+               $(LIBTOOL) $(CC) -c $(CFLAGS) get.c
+
+study.o:        study.c pcre.h internal.h config.h Makefile
+               $(LIBTOOL) $(CC) -c $(CFLAGS) $(UTF8) study.c
+
+pcretest.o:     pcretest.c pcre.h config.h Makefile
+               $(CC) -c $(CFLAGS) $(UTF8) pcretest.c
+
+pcregrep.o:     pcregrep.c pcre.h Makefile config.h
+               $(CC) -c $(CFLAGS) $(UTF8) pcregrep.c
+
+# An auxiliary program makes the default character table source
+
+chartables.c:   dftables
+               ./dftables >chartables.c
+
+dftables:       dftables.c maketables.c pcre.h internal.h config.h Makefile
+               $(CC) -o dftables $(CFLAGS) dftables.c
+
+install:        all
+               $(LIBTOOL) $(INSTALL_DATA) libpcre.$(LIBSUFFIX) $(DESTDIR)/$(LIBDIR)/libpcre.$(LIBSUFFIX)
+               $(LIBTOOL) $(INSTALL_DATA) libpcreposix.$(LIBSUFFIX) $(DESTDIR)/$(LIBDIR)/libpcreposix.$(LIBSUFFIX)
+               $(INSTALL_DATA) pcre.h $(DESTDIR)/$(INCDIR)/pcre.h
+               $(INSTALL_DATA) pcreposix.h $(DESTDIR)/$(INCDIR)/pcreposix.h
+               $(INSTALL_DATA) doc/pcre.3 $(DESTDIR)/$(MANDIR)/man3/pcre.3
+               $(INSTALL_DATA) doc/pcreposix.3 $(DESTDIR)/$(MANDIR)/man3/pcreposix.3
+               $(INSTALL_DATA) doc/pcregrep.1 $(DESTDIR)/$(MANDIR)/man1/pcregrep.1
+               @if test "$(LIBTOOL)" = "./libtool"; then \
+                 echo ' '; \
+                 echo '--- Rebuilding pcregrep to use installed shared library ---'; \
+                 echo $(CC) $(CFLAGS) -o pcregrep pcregrep.o -L$(DESTDIR)/$(LIBDIR) -lpcre; \
+                 $(CC) $(CFLAGS) -o pcregrep pcregrep.o -L$(DESTDIR)/$(LIBDIR) -lpcre; \
+                 echo '--- Rebuilding pcretest to use installed shared library ---'; \
+                 echo $(CC) $(CFLAGS) -o pcretest pcretest.o -L$(DESTDIR)/$(LIBDIR) -lpcre -lpcreposix; \
+                 $(CC) $(CFLAGS) -o pcretest pcretest.o -L$(DESTDIR)/$(LIBDIR) -lpcre -lpcreposix; \
+               fi
+               $(INSTALL)      pcregrep $(DESTDIR)/$(BINDIR)/pcregrep
+               $(INSTALL)      pcre-config $(DESTDIR)/$(BINDIR)/pcre-config
+
+# We deliberately omit dftables and chartables.c from 'make clean'; once made
+# chartables.c shouldn't change, and if people have edited the tables by hand,
+# you don't want to throw them away.
+
+clean:;         -rm -rf *.o *.lo *.a *.la .libs pcretest pcregrep testtry
+
+# But "make distclean" should get back to a virgin distribution
+
+distclean:      clean
+               -rm -f chartables.c libtool pcre-config pcre.h \
+               Makefile config.h config.status config.log config.cache
+
+check:          runtest
+
+test:           runtest
+
+runtest:        all
+               ./RunTest
+
+######## MINGW32 ############### MINGW32 ############### MINGW32 #############
+
+# This addition for mingw32 was contributed by  Paul Sokolovsky
+# <Paul.Sokolovsky@technologist.com>. I (PH) don't know anything about it!
+
+dll:            _dll libpcre.dll.a pcregrep_d pcretest_d
+
+_dll:
+               $(MAKE) CFLAGS=-DSTATIC pcre.dll
+
+pcre.dll:       $(OBJ) pcreposix.o pcre.def
+libpcre.dll.a:  pcre.def
+
+pcregrep_d:     libpcre.dll.a pcregrep.o
+               $(CC) $(CFLAGS) -L. -o pcregrep pcregrep.o -lpcre.dll
+
+pcretest_d:     libpcre.dll.a pcretest.o
+               $(PURIFY) $(CC) $(CFLAGS) -L. -o pcretest pcretest.o -lpcre.dll
+
+# End
diff --git a/pcre/RunTest.in b/pcre/RunTest.in
new file mode 100644 (file)
index 0000000..6e4eb08
--- /dev/null
@@ -0,0 +1,148 @@
+#! /bin/sh
+
+# This file is generated by configure from RunTest.in. Make any changes
+# to that file.
+
+# Run PCRE tests
+
+cf=diff
+
+# Select which tests to run; if no selection, run all
+
+do1=no
+do2=no
+do3=no
+do4=no
+do5=no
+do6=no
+
+while [ $# -gt 0 ] ; do
+  case $1 in
+    1) do1=yes;;
+    2) do2=yes;;
+    3) do3=yes;;
+    4) do4=yes;;
+    5) do5=yes;; 
+    6) do6=yes;; 
+    *) echo "Unknown test number $1"; exit 1;;
+  esac
+  shift
+done
+
+if [ "@UTF8@" = "" ] ; then
+  if [ $do5 = yes ] ; then
+    echo "Can't run test 5 because UFT8 support is not configured"
+    exit 1
+  fi   
+  if [ $do6 = yes ] ; then
+    echo "Can't run test 6 because UFT8 support is not configured"
+    exit 1
+  fi   
+fi    
+
+if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a\
+     $do5 = no -a $do6 = no ] ; then
+  do1=yes
+  do2=yes
+  do3=yes
+  do4=yes
+  if [ "@UTF8@" != "" ] ; then do5=yes; fi
+  if [ "@UTF8@" != "" ] ; then do6=yes; fi
+fi
+
+# Primary test, Perl-compatible
+
+if [ $do1 = yes ] ; then
+  echo "Testing main functionality (Perl compatible)"
+  ./pcretest testdata/testinput1 testtry
+  if [ $? = 0 ] ; then
+    $cf testtry testdata/testoutput1
+    if [ $? != 0 ] ; then exit 1; fi
+  else exit 1
+  fi
+fi
+
+# PCRE tests that are not Perl-compatible - API & error tests, mostly
+
+if [ $do2 = yes ] ; then
+  echo "Testing API and error handling (not Perl compatible)"
+  ./pcretest -i testdata/testinput2 testtry
+  if [ $? = 0 ] ; then
+    $cf testtry testdata/testoutput2
+    if [ $? != 0 ] ; then exit 1; fi
+  else exit 1
+  fi
+fi
+
+# Additional Perl-compatible tests for Perl 5.005's new features
+
+if [ $do3 = yes ] ; then
+  echo "Testing Perl 5.005 features (Perl 5.005 compatible)"
+  ./pcretest testdata/testinput3 testtry
+  if [ $? = 0 ] ; then
+    $cf testtry testdata/testoutput3
+    if [ $? != 0 ] ; then exit 1; fi
+  else exit 1
+  fi
+fi
+
+if [ $do1 = yes -a $do2 = yes -a $do3 = yes ] ; then
+  echo " " 
+  echo "The three main tests all ran OK"
+  echo " " 
+fi
+
+# Locale-specific tests, provided the "fr" locale is available
+
+if [ $do4 = yes ] ; then
+  locale -a | grep '^fr$' >/dev/null
+  if [ $? -eq 0 ] ; then
+    echo "Testing locale-specific features (using 'fr' locale)"
+    ./pcretest testdata/testinput4 testtry
+    if [ $? = 0 ] ; then
+      $cf testtry testdata/testoutput4
+      if [ $? != 0 ] ; then 
+        echo " "
+        echo "Locale test did not run entirely successfully."
+        echo "This usually means that there is a problem with the locale"
+        echo "settings rather than a bug in PCRE."    
+      else
+      echo "Locale test ran OK" 
+      fi 
+      echo " " 
+    else exit 1
+    fi
+  else
+    echo "Cannot test locale-specific features - 'fr' locale not found,"
+    echo "or the \"locale\" command is not available to check for it."
+    echo " " 
+  fi
+fi
+
+# Additional tests for UTF8 support
+
+if [ $do5 = yes ] ; then
+  echo "Testing experimental, incomplete UTF8 support (Perl compatible)"
+  ./pcretest testdata/testinput5 testtry 
+  if [ $? = 0 ] ; then
+    $cf testtry testdata/testoutput5
+    if [ $? != 0 ] ; then exit 1; fi
+  else exit 1
+  fi
+  echo "UTF8 test ran OK"
+  echo " "
+fi
+
+if [ $do6 = yes ] ; then
+  echo "Testing API and internals for UTF8 support (not Perl compatible)"
+  ./pcretest testdata/testinput6 testtry 
+  if [ $? = 0 ] ; then
+    $cf testtry testdata/testoutput6
+    if [ $? != 0 ] ; then exit 1; fi
+  else exit 1
+  fi
+  echo "UTF8 internals test ran OK"
+  echo " "
+fi
+
+# End
diff --git a/pcre/chartables.c b/pcre/chartables.c
deleted file mode 100644 (file)
index 9055da2..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*************************************************
-*      Perl-Compatible Regular Expressions       *
-*************************************************/
-
-/* This file is automatically written by the dftables auxiliary 
-program. If you edit it by hand, you might like to edit the Makefile to 
-prevent its ever being regenerated.
-
-This file is #included in the compilation of pcre.c to build the default
-character tables which are used when no tables are passed to the compile
-function. */
-
-static unsigned char pcre_default_tables[] = {
-
-/* This table is a lower casing table. */
-
-    0,  1,  2,  3,  4,  5,  6,  7,
-    8,  9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31,
-   32, 33, 34, 35, 36, 37, 38, 39,
-   40, 41, 42, 43, 44, 45, 46, 47,
-   48, 49, 50, 51, 52, 53, 54, 55,
-   56, 57, 58, 59, 60, 61, 62, 63,
-   64, 97, 98, 99,100,101,102,103,
-  104,105,106,107,108,109,110,111,
-  112,113,114,115,116,117,118,119,
-  120,121,122, 91, 92, 93, 94, 95,
-   96, 97, 98, 99,100,101,102,103,
-  104,105,106,107,108,109,110,111,
-  112,113,114,115,116,117,118,119,
-  120,121,122,123,124,125,126,127,
-  128,129,130,131,132,133,134,135,
-  136,137,138,139,140,141,142,143,
-  144,145,146,147,148,149,150,151,
-  152,153,154,155,156,157,158,159,
-  160,161,162,163,164,165,166,167,
-  168,169,170,171,172,173,174,175,
-  176,177,178,179,180,181,182,183,
-  184,185,186,187,188,189,190,191,
-  192,193,194,195,196,197,198,199,
-  200,201,202,203,204,205,206,207,
-  208,209,210,211,212,213,214,215,
-  216,217,218,219,220,221,222,223,
-  224,225,226,227,228,229,230,231,
-  232,233,234,235,236,237,238,239,
-  240,241,242,243,244,245,246,247,
-  248,249,250,251,252,253,254,255,
-
-/* This table is a case flipping table. */
-
-    0,  1,  2,  3,  4,  5,  6,  7,
-    8,  9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31,
-   32, 33, 34, 35, 36, 37, 38, 39,
-   40, 41, 42, 43, 44, 45, 46, 47,
-   48, 49, 50, 51, 52, 53, 54, 55,
-   56, 57, 58, 59, 60, 61, 62, 63,
-   64, 97, 98, 99,100,101,102,103,
-  104,105,106,107,108,109,110,111,
-  112,113,114,115,116,117,118,119,
-  120,121,122, 91, 92, 93, 94, 95,
-   96, 65, 66, 67, 68, 69, 70, 71,
-   72, 73, 74, 75, 76, 77, 78, 79,
-   80, 81, 82, 83, 84, 85, 86, 87,
-   88, 89, 90,123,124,125,126,127,
-  128,129,130,131,132,133,134,135,
-  136,137,138,139,140,141,142,143,
-  144,145,146,147,148,149,150,151,
-  152,153,154,155,156,157,158,159,
-  160,161,162,163,164,165,166,167,
-  168,169,170,171,172,173,174,175,
-  176,177,178,179,180,181,182,183,
-  184,185,186,187,188,189,190,191,
-  192,193,194,195,196,197,198,199,
-  200,201,202,203,204,205,206,207,
-  208,209,210,211,212,213,214,215,
-  216,217,218,219,220,221,222,223,
-  224,225,226,227,228,229,230,231,
-  232,233,234,235,236,237,238,239,
-  240,241,242,243,244,245,246,247,
-  248,249,250,251,252,253,254,255,
-
-/* This table contains bit maps for various character classes.
-Each map is 32 bytes long and the bits run from the least
-significant end of each byte. The classes that have their own
-maps are: space, xdigit, digit, upper, lower, word, graph
-print, punct, and cntrl. Other classes are built from combinations. */
-
-  0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
-  0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
-  0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
-  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
-  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
-  0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-  0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-/* This table identifies various classes of character by individual bits:
-  0x01   white space character
-  0x02   letter
-  0x04   decimal digit
-  0x08   hexadecimal digit
-  0x10   alphanumeric or '_'
-  0x80   regular expression metacharacter or binary zero
-*/
-
-  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */
-  0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /*   8- 15 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */
-  0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /*    - '  */
-  0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /*  ( - /  */
-  0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /*  0 - 7  */
-  0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /*  8 - ?  */
-  0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  @ - G  */
-  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */
-  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */
-  0x12,0x12,0x12,0x80,0x00,0x00,0x80,0x10, /*  X - _  */
-  0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  ` - g  */
-  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  h - o  */
-  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  p - w  */
-  0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /*  x -127 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
-  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-/* End of chartables.c */
diff --git a/pcre/config.guess b/pcre/config.guess
new file mode 100644 (file)
index 0000000..e1b5871
--- /dev/null
@@ -0,0 +1,1121 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
+#   Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+# Please send patches to <autoconf-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# Use $HOST_CC if defined. $CC may point to a cross-compiler
+if test x"$CC_FOR_BUILD" = x; then
+  if test x"$HOST_CC" != x; then
+    CC_FOR_BUILD="$HOST_CC"
+  else
+    if test x"$CC" != x; then
+      CC_FOR_BUILD="$CC"
+    else
+      CC_FOR_BUILD=cc
+    fi
+  fi
+fi
+
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >$dummy.s
+       .globl main
+       .ent main
+main:
+       .frame \$30,0,\$26,0
+       .prologue 0
+       .long 0x47e03d80 # implver $0
+       lda \$2,259
+       .long 0x47e20c21 # amask $2,$1
+       srl \$1,8,\$2
+       sll \$2,2,\$2
+       sll \$0,3,\$0
+       addl \$1,\$0,\$0
+       addl \$2,\$0,\$0
+       ret \$31,(\$26),1
+       .end main
+EOF
+       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               ./$dummy
+               case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-cbm-sysv4
+       exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    arm32:NetBSD:*:*)
+       echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:NetBSD:*:*)
+       echo m68k-atari-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor 
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:NetBSD:*:*)
+       echo m68k-sun-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:NetBSD:*:*)
+       echo m68k-apple-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:NetBSD:*:*)
+        echo powerpc-apple-netbsd${UNAME_RELEASE}
+        exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD $dummy.c -o $dummy \
+         && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+               rm -f $dummy.c $dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:4)
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=4.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+              sed 's/^              //' << EOF >$dummy.c
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+       (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+       rm -f $dummy.c $dummy
+       esac
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i?86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    hppa*:OpenBSD:*:*)
+       echo hppa-unknown-openbsd
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+       echo m68k-hp-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       if test -x /usr/bin/objformat; then
+           if test "elf" = "`/usr/bin/objformat`"; then
+               echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+               exit 0
+           fi
+       fi
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:NetBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *:Linux:*:*)
+
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       ld_help_string=`cd /; ld --help 2>&1`
+       ld_supported_emulations=`echo $ld_help_string \
+                        | sed -ne '/supported emulations:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported emulations: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_emulations" in
+         *ia64)
+               echo "${UNAME_MACHINE}-unknown-linux"
+               exit 0
+               ;;
+         i?86linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0
+               ;;
+         i?86coff)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0
+               ;;
+         sparclinux)
+               echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+               exit 0
+               ;;
+         armlinux)
+               echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+               exit 0
+               ;;
+         elf32arm*)
+               echo "${UNAME_MACHINE}-unknown-linux-gnu"
+               exit 0
+               ;;
+         armelf_linux*)
+               echo "${UNAME_MACHINE}-unknown-linux-gnu"
+               exit 0
+               ;;
+         m68klinux)
+               echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+               exit 0
+               ;;
+         elf32ppc)
+               # Determine Lib Version
+               cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#if defined(__GLIBC__)
+  printf("%s %s\n", __libc_version, __libc_release);
+#else
+  printf("unkown\n");
+#endif
+  return 0;
+}
+EOF
+               LIBC=""
+               $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       ./$dummy | grep 1\.99 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi      
+               rm -f $dummy.c $dummy
+               echo powerpc-unknown-linux-gnu${LIBC}
+               exit 0
+               ;;
+       esac
+
+       if test "${UNAME_MACHINE}" = "alpha" ; then
+               sed 's/^        //'  <<EOF >$dummy.s
+               .globl main
+               .ent main
+       main:
+               .frame \$30,0,\$26,0
+               .prologue 0
+               .long 0x47e03d80 # implver $0
+               lda \$2,259
+               .long 0x47e20c21 # amask $2,$1
+               srl \$1,8,\$2
+               sll \$2,2,\$2
+               sll \$0,3,\$0
+               addl \$1,\$0,\$0
+               addl \$2,\$0,\$0
+               ret \$31,(\$26),1
+               .end main
+EOF
+               LIBC=""
+               $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       ./$dummy
+                       case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       esac
+
+                       objdump --private-headers $dummy | \
+                         grep ld.so.1 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi
+               rm -f $dummy.s $dummy
+               echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+       elif test "${UNAME_MACHINE}" = "mips" ; then
+         cat >$dummy.c <<EOF
+#ifdef __cplusplus
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+         rm -f $dummy.c $dummy
+       else
+         # Either a pre-BFD a.out linker (linux-gnuoldld)
+         # or one that does not give us useful --help.
+         # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+         # If ld does not provide *any* "supported emulations:"
+         # that means it is gnuoldld.
+         echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+         test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+         case "${UNAME_MACHINE}" in
+         i?86)
+           VENDOR=pc;
+           ;;
+         *)
+           VENDOR=unknown;
+           ;;
+         esac
+         # Determine whether the default compiler is a.out or elf
+         cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+         rm -f $dummy.c $dummy
+       fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i?86:*:5:7*)
+        # Fixed at (any) Pentium or better
+        UNAME_MACHINE=i586
+        if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
+           echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
+       else
+           echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    i?86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:*:6*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-qnx-qnx${UNAME_VERSION}
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
index 048b8c3..c767cbb 100644 (file)
@@ -1,34 +1,5 @@
-/* config.h.  Generated automatically by configure.  */
 
-/* On Unix systems config.in is converted by configure into config.h. PCRE is
-written in Standard C, but there are a few non-standard things it can cope
-with, allowing it to run on SunOS4 and other "close to standard" systems.
+/* For Privoxy, we just use Privoxy's config.h */
 
-On a non-Unix system you should just copy this file into config.h and change
-the definitions of HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because
-of the way autoconf works, these cannot be made the defaults. If your system
-has bcopy() and not memmove(), change the definition of HAVE_BCOPY instead of
-HAVE_MEMMOVE. If your system has neither bcopy() nor memmove(), leave them both
-as 0; an emulation function will be used. */
+#include "../config.h"
 
-/* Define to empty if the keyword does not work. */
-
-/* #undef const */
-
-/* Define to `unsigned' if <stddef.h> doesn't define size_t. */
-
-/* #undef size_t */
-
-/* The following two definitions are mainly for the benefit of SunOS4, which
-doesn't have the strerror() or memmove() functions that should be present in
-all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should
-normally be defined with the value 1 for other systems, but unfortunately we
-can't make this the default because "configure" files generated by autoconf
-will only change 0 to 1; they won't change 1 to 0 if the functions are not
-found. If HAVE_MEMMOVE is set to 1, the value of HAVE_BCOPY is not relevant. */
-
-#define HAVE_STRERROR 1
-#define HAVE_MEMMOVE  1
-#define HAVE_BCOPY    1
-
-/* End */
diff --git a/pcre/config.in b/pcre/config.in
new file mode 100644 (file)
index 0000000..02f4259
--- /dev/null
@@ -0,0 +1,33 @@
+
+/* On Unix systems config.in is converted by configure into config.h. PCRE is
+written in Standard C, but there are a few non-standard things it can cope
+with, allowing it to run on SunOS4 and other "close to standard" systems.
+
+On a non-Unix system you should just copy this file into config.h and change
+the definitions of HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because
+of the way autoconf works, these cannot be made the defaults. If your system
+has bcopy() and not memmove(), change the definition of HAVE_BCOPY instead of
+HAVE_MEMMOVE. If your system has neither bcopy() nor memmove(), leave them both
+as 0; an emulation function will be used. */
+
+/* Define to empty if the keyword does not work. */
+
+#undef const
+
+/* Define to `unsigned' if <stddef.h> doesn't define size_t. */
+
+#undef size_t
+
+/* The following two definitions are mainly for the benefit of SunOS4, which
+doesn't have the strerror() or memmove() functions that should be present in
+all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should
+normally be defined with the value 1 for other systems, but unfortunately we
+can't make this the default because "configure" files generated by autoconf
+will only change 0 to 1; they won't change 1 to 0 if the functions are not
+found. If HAVE_MEMMOVE is set to 1, the value of HAVE_BCOPY is not relevant. */
+
+#define HAVE_STRERROR 0
+#define HAVE_MEMMOVE  0
+#define HAVE_BCOPY    0
+
+/* End */
diff --git a/pcre/config.sub b/pcre/config.sub
new file mode 100644 (file)
index 0000000..28426bb
--- /dev/null
@@ -0,0 +1,1232 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+       echo Configuration name missing. 1>&2
+       echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+       echo "or     $0 ALIAS" 1>&2
+       echo where ALIAS is a recognized configuration type. 1>&2
+       exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+       *local*)
+               echo $1
+               exit 0
+               ;;
+       *)
+       ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+               | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+               | 580 | i960 | h8300 \
+               | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+               | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \
+               | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+               | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
+               | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+               | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+               | mips64vr5000 | miprs64vr5000el | mcore \
+               | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
+               | thumb | d10v | fr30)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i[34567]86)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       # FIXME: clean up the formatting here.
+       vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+             | xmp-* | ymp-* \
+             | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
+             | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \
+             | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+             | clipper-* | orion-* \
+             | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+             | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-* \
+             | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+             | mipstx39-* | mipstx39el-* | mcore-* \
+             | f301-* | armv*-* | t3e-* \
+             | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+             | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* )
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-cbm
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-cbm
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-cbm
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [ctj]90-cray)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i[34567]86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i[34567]86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i[34567]86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i[34567]86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       i386-go32 | go32)
+               basic_machine=i386-unknown
+               os=-go32
+               ;;
+       i386-mingw32 | mingw32)
+               basic_machine=i386-unknown
+               os=-mingw32
+               ;;
+       i386-qnx | qnx)
+               basic_machine=i386-qnx
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       msdos)
+               basic_machine=i386-unknown
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexen)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexen-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=rs6000-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=t3e-cray
+               os=-unicos
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sparc | sparcv9)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       c4x*)
+               basic_machine=c4x-none
+               os=-coff
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -opened* | -openstep* | -oskit*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+        -qnx)
+               os=-qnx4
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+        -*mint | -*MiNT)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f301-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -*MiNT)
+                               vendor=atari
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
old mode 100755 (executable)
new mode 100644 (file)
similarity index 74%
rename from configure
rename to pcre/configure
index 6c620ec..fbd3831
--- a/configure
@@ -12,42 +12,9 @@ ac_help=
 ac_default_prefix=/usr/local
 # Any additions from configure.in:
 ac_help="$ac_help
-  --enable-mingw32        Use mingw32 for a Windows GUI"
+  --disable-shared        build PCRE as a static library"
 ac_help="$ac_help
-  --disable-regex         Don't allow regular expressions in the blockfile"
-ac_help="$ac_help
-  --disable-pcre-regex    Use old, slow GNU Regex instead of PCRE."
-ac_help="$ac_help
-  --disable-toggle        Don't support temporary disable"
-ac_help="$ac_help
-  --disable-pcrs          Don't support arbitrary content modification"
-ac_help="$ac_help
-  --disable-force         Don't allow blockfle to be bypassed"
-ac_help="$ac_help
-  --disable-killpopup     Never block popups"
-ac_help="$ac_help
-  --disable-stats         Don't keep statistics"
-ac_help="$ac_help
-  --disable-split-proxy-args  One big show-proxy-args page, not one per file."
-ac_help="$ac_help
-  --disable-webdav        Don't support WebDAV.  This option stops MS Outlook
-                          Express from accessing HotMail e-mail."
-ac_help="$ac_help
-  --disable-ie-images     Don't auto-detect whether a request from MS Internet
-                          Explorer is for an image or HTML."
-ac_help="$ac_help
-  --disable-image-list    Don't try to figure out whether a request is for an
-                          image or HTML using the imagelist - assume HTML."
-ac_help="$ac_help
-  --disable-acl-files     Prevents the use of ACL files to control access to
-                          the proxy by IP address."
-ac_help="$ac_help
-  --disable-trust-files   Prevents the use of trust files."
-ac_help="$ac_help
-  --disable-jar-files     Prevents the use of jar files to capture cookies."
-ac_help="$ac_help
-  --disable-static-pcre   Link dynamically with the pcre and pcreposix
-                          libraries.  You must build the libraries seperately."
+  --enable-utf8           enable UTF8 support (incomplete)"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -170,9 +137,18 @@ do
 
   -help | --help | --hel | --he)
     # Omit some internal or obsolete options to make the list less imposing.
+    # The list generated by autoconf has been trimmed to remove many
+    # options that are totally irrelevant to PCRE (e.g. relating to X),
+    # or are not supported by its Makefile.
+    # The list generated by autoconf has been trimmed to remove many
+    # options that are totally irrelevant to PCRE (e.g. relating to X),
+    # or are not supported by its Makefile.
+    # The list generated by autoconf has been trimmed to remove many
+    # options that are totally irrelevant to PCRE (e.g. relating to X),
+    # or are not supported by its Makefile.
     # This message is too long to be a string in the A/UX 3.1 sh.
     cat << EOF
-Usage: configure [options] [host]
+Usage: ./configure [options]
 Options: [defaults in brackets after descriptions]
 Configuration:
   --cache-file=FILE       cache test results in FILE
@@ -186,37 +162,11 @@ Directory and file names:
   --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                           [same as prefix]
   --bindir=DIR            user executables in DIR [EPREFIX/bin]
-  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
-  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
-  --datadir=DIR           read-only architecture-independent data in DIR
-                          [PREFIX/share]
-  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
-  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
-                          [PREFIX/com]
-  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
   --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
   --includedir=DIR        C header files in DIR [PREFIX/include]
-  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
-  --infodir=DIR           info documentation in DIR [PREFIX/info]
   --mandir=DIR            man documentation in DIR [PREFIX/man]
-  --srcdir=DIR            find the sources in DIR [configure dir or ..]
-  --program-prefix=PREFIX prepend PREFIX to installed program names
-  --program-suffix=SUFFIX append SUFFIX to installed program names
-  --program-transform-name=PROGRAM
-                          run sed PROGRAM on installed program names
 EOF
     cat << EOF
-Host type:
-  --build=BUILD           configure for building on BUILD [BUILD=HOST]
-  --host=HOST             configure for HOST [guessed]
-  --target=TARGET         configure for TARGET [TARGET=HOST]
-Features and packages:
-  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
-  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --x-includes=DIR        X include files are in DIR
-  --x-libraries=DIR       X library files are in DIR
 EOF
     if test -n "$ac_help"; then
       echo "--enable and --with options recognized:$ac_help"
@@ -488,7 +438,7 @@ echo > confdefs.h
 
 # A filename unique to this package, relative to the directory that
 # configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=jcc.c
+ac_unique_file=dftables.c
 
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
@@ -560,35 +510,22 @@ fi
 
 
 
-VERSION_MAJOR=2
-VERSION_MINOR=9
-VERSION_POINT=3
-
 
 
+PCRE_MAJOR=3
+PCRE_MINOR=4
+PCRE_DATE=22-Aug-2000
+PCRE_VERSION=${PCRE_MAJOR}.${PCRE_MINOR}
 
 
-cat >> confdefs.h <<EOF
-#define VERSION_MAJOR ${VERSION_MAJOR}
-EOF
-
-cat >> confdefs.h <<EOF
-#define VERSION_MINOR ${VERSION_MINOR}
-EOF
-
-cat >> confdefs.h <<EOF
-#define VERSION_POINT ${VERSION_POINT}
-EOF
-
-cat >> confdefs.h <<EOF
-#define VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_POINT}"
-EOF
+PCRE_LIB_VERSION=0:1:0
+PCRE_POSIXLIB_VERSION=0:0:0
 
 
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:592: checking for $ac_word" >&5
+echo "configure:546: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -618,7 +555,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:622: checking for $ac_word" >&5
+echo "configure:576: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -669,7 +606,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:673: checking for $ac_word" >&5
+echo "configure:627: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -701,7 +638,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:705: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:659: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -712,12 +649,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 716 "configure"
+#line 670 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -743,12 +680,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:747: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:701: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:752: checking whether we are using GNU C" >&5
+echo "configure:706: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -757,7 +694,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:761: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:715: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -776,7 +713,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:780: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:734: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -807,8 +744,40 @@ else
   fi
 fi
 
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:768: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:812: checking how to run the C preprocessor" >&5
+echo "configure:798: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -823,13 +792,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 827 "configure"
+#line 813 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:833: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:819: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -840,13 +809,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 844 "configure"
+#line 830 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:850: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:836: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -857,13 +826,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 861 "configure"
+#line 847 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:867: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:853: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -887,135 +856,13 @@ else
 fi
 echo "$ac_t""$CPP" 1>&6
 
-
-echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:893: checking for mingw32 environment" >&5
-if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 898 "configure"
-#include "confdefs.h"
-
-int main() {
-return __MINGW32__;
-; return 0; }
-EOF
-if { (eval echo configure:905: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  ac_cv_mingw32=yes
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  ac_cv_mingw32=no
-fi
-rm -f conftest*
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_mingw32" 1>&6
-MINGW32=
-test "$ac_cv_mingw32" = yes && MINGW32=yes
-echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:922: checking for Cygwin environment" >&5
-if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 927 "configure"
-#include "confdefs.h"
-
-int main() {
-
-#ifndef __CYGWIN__
-#define __CYGWIN__ __CYGWIN32__
-#endif
-return __CYGWIN__;
-; return 0; }
-EOF
-if { (eval echo configure:938: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  ac_cv_cygwin=yes
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  ac_cv_cygwin=no
-fi
-rm -f conftest*
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_cygwin" 1>&6
-CYGWIN=
-test "$ac_cv_cygwin" = yes && CYGWIN=yes
-
-
-echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:957: checking for executable suffix" >&5
-if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
-  ac_cv_exeext=.exe
-else
-  rm -f conftest*
-  echo 'int main () { return 0; }' > conftest.$ac_ext
-  ac_cv_exeext=
-  if { (eval echo configure:967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
-    for file in conftest.*; do
-      case $file in
-      *.c | *.o | *.obj) ;;
-      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
-      esac
-    done
-  else
-    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
-  fi
-  rm -f conftest*
-  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
-fi
-fi
-
-EXEEXT=""
-test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
-echo "$ac_t""${ac_cv_exeext}" 1>&6
-ac_exeext=$EXEEXT
-
-echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:988: checking for object suffix" >&5
-if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  rm -f conftest*
-echo 'int i = 1;' > conftest.$ac_ext
-if { (eval echo configure:994: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  for ac_file in conftest.*; do
-    case $ac_file in
-    *.c) ;;
-    *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
-    esac
-  done
-else
-  { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_objext" 1>&6
-OBJEXT=$ac_cv_objext
-ac_objext=$ac_cv_objext
-
-
-
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1014: checking for ANSI C header files" >&5
+echo "configure:878: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1019 "configure"
+#line 883 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1023,7 +870,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1027: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:891: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1040,7 +887,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1044 "configure"
+#line 908 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1058,7 +905,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1062 "configure"
+#line 926 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1079,7 +926,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1083 "configure"
+#line 947 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1090,7 +937,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1113,14 +960,55 @@ EOF
 
 fi
 
+for ac_hdr in limits.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:985: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 990 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:995: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1119: checking for working const" >&5
+echo "configure:1024: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1124 "configure"
+#line 1029 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1169,7 +1057,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:1173: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1078: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1190,12 +1078,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1194: checking for size_t" >&5
+echo "configure:1099: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1199 "configure"
+#line 1104 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1223,15 +1111,16 @@ EOF
 fi
 
 
-for ac_func in strerror bcopy memmove
+
+for ac_func in bcopy memmove strerror
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1230: checking for $ac_func" >&5
+echo "configure:1136: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1235 "configure"
+#line 1141 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1254,7 +1143,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1164: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1280,90 +1169,26 @@ done
 
 
 
-# Check whether --enable-mingw32 or --disable-mingw32 was given.
-if test "${enable_mingw32+set}" = set; then
-  enableval="$enable_mingw32"
-  if test $enableval = yes; then
-    WIN_ONLY=
-    CYGWIN_FLAGS="-mwindows -mno-cygwin"
-    echo "Using mingw32 (Win32 GUI)"
-  else
-    WIN_ONLY=#
-    if test "$CYGWIN" = "yes"; then
-      CYGWIN_FLAGS="-mno-win32"
-      echo "Using Cygnus (Win32 command line)"
-    else
-      CYGWIN_FLAGS=
-    fi
-  fi
-else
-  if test "$MINGW32" = "yes"; then
-    WIN_ONLY=
-    CYGWIN_FLAGS="-mwindows -mno-cygwin"
-    echo "Using mingw32 (Win32 GUI)"
-  else
-    WIN_ONLY=#
-    if test "$CYGWIN" = "yes"; then
-      CYGWIN_FLAGS="-mno-win32"
-      echo "Using Cygnus (Win32 command line)"
-    else
-      CYGWIN_FLAGS=
-    fi
-  fi
+LIBTOOL=./libtool
+LIBSUFFIX=la
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  if test "$enableval" = "no"; then
+  LIBTOOL=
+  LIBSUFFIX=a
 fi
 
-
-
-
-
-SOLARIS_ONLY=#
-
-
-
-
-GNU_REGEX_ONLY=
-PCRE_REGEX_ONLY=
-NO_REGEX_ONLY=#
-
-# Check whether --enable-regex or --disable-regex was given.
-if test "${enable_regex+set}" = set; then
-  enableval="$enable_regex"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define REGEX 1
-EOF
-
-else
-  NO_REGEX_ONLY=
-  GNU_REGEX_ONLY=#
-  PCRE_REGEX_ONLY=#
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define REGEX 1
-EOF
-
 fi
 
 
-# Check whether --enable-pcre-regex or --disable-pcre-regex was given.
-if test "${enable_pcre_regex+set}" = set; then
-  enableval="$enable_pcre_regex"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define PCRE 1
-EOF
 
-  GNU_REGEX_ONLY=#
-else
-  PCRE_REGEX_ONLY=#
+# Check whether --enable-utf8 or --disable-utf8 was given.
+if test "${enable_utf8+set}" = set; then
+  enableval="$enable_utf8"
+  if test "$enableval" = "yes"; then
+  UTF8=-DSUPPORT_UTF8
 fi
-else
-  cat >> confdefs.h <<\EOF
-#define PCRE 1
-EOF
-
-  GNU_REGEX_ONLY=#
 
 fi
 
 
 
 
-# Check whether --enable-toggle or --disable-toggle was given.
-if test "${enable_toggle+set}" = set; then
-  enableval="$enable_toggle"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define TOGGLE 1
-EOF
 
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define TOGGLE 1
-EOF
 
-fi
 
 
-PCRS_ONLY=
-# Check whether --enable-pcrs or --disable-pcrs was given.
-if test "${enable_pcrs+set}" = set; then
-  enableval="$enable_pcrs"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define PCRS 1
-EOF
-
-  cat >> confdefs.h <<\EOF
-#define DENY_GZIP 1
-EOF
-
-else
-  PCRS_ONLY=#
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define PCRS 1
-EOF
- cat >> confdefs.h <<\EOF
-#define DENY_GZIP 1
-EOF
-
-fi
-
-
-
-# Check whether --enable-force or --disable-force was given.
-if test "${enable_force+set}" = set; then
-  enableval="$enable_force"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define FORCE_LOAD 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define FORCE_LOAD 1
-EOF
-
-fi
-
-
-# Check whether --enable-killpopup or --disable-killpopup was given.
-if test "${enable_killpopup+set}" = set; then
-  enableval="$enable_killpopup"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define KILLPOPUPS 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define KILLPOPUPS 1
-EOF
-
-fi
-
-
-# Check whether --enable-stats or --disable-stats was given.
-if test "${enable_stats+set}" = set; then
-  enableval="$enable_stats"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define STATISTICS 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define STATISTICS 1
-EOF
-
-fi
-
-
-# Check whether --enable-split-proxy-args or --disable-split-proxy-args was given.
-if test "${enable_split_proxy_args+set}" = set; then
-  enableval="$enable_split_proxy_args"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define SPLIT_PROXY_ARGS 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define SPLIT_PROXY_ARGS 1
-EOF
-
-fi
-
-
-# Check whether --enable-webdav or --disable-webdav was given.
-if test "${enable_webdav+set}" = set; then
-  enableval="$enable_webdav"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define WEBDAV 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define WEBDAV 1
-EOF
-
-fi
-
-
-# Check whether --enable-ie-images or --disable-ie-images was given.
-if test "${enable_ie_images+set}" = set; then
-  enableval="$enable_ie_images"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define DETECT_MSIE_IMAGES 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define DETECT_MSIE_IMAGES 1
-EOF
-
-fi
-
-
-# Check whether --enable-image-list or --disable-image-list was given.
-if test "${enable_image_list+set}" = set; then
-  enableval="$enable_image_list"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define USE_IMAGE_LIST 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define USE_IMAGE_LIST 1
-EOF
-
-fi
-
-
-# Check whether --enable-acl-files or --disable-acl-files was given.
-if test "${enable_acl_files+set}" = set; then
-  enableval="$enable_acl_files"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define ACL_FILES 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define ACL_FILES 1
-EOF
-
-fi
-
-
-# Check whether --enable-trust-files or --disable-trust-files was given.
-if test "${enable_trust_files+set}" = set; then
-  enableval="$enable_trust_files"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define TRUST_FILES 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define TRUST_FILES 1
-EOF
-
-fi
-
-
-# Check whether --enable-jar-files or --disable-jar-files was given.
-if test "${enable_jar_files+set}" = set; then
-  enableval="$enable_jar_files"
-  if test $enableval = yes; then
-  cat >> confdefs.h <<\EOF
-#define JAR_FILES 1
-EOF
-
-fi
-else
-  cat >> confdefs.h <<\EOF
-#define JAR_FILES 1
-EOF
-
-fi
-
-
-LIBRARY_PCRE_ONLY=#
-STATIC_PCRE_ONLY=
-# Check whether --enable-static-pcre or --disable-static-pcre was given.
-if test "${enable_static_pcre+set}" = set; then
-  enableval="$enable_static_pcre"
-  if test $enableval = no; then
-  LIBRARY_PCRE_ONLY=
-  STATIC_PCRE_ONLY=#
-fi
-fi
-
 
 
 
@@ -1703,7 +1306,7 @@ done
 
 ac_given_srcdir=$srcdir
 
-trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+trap 'rm -fr `echo "Makefile pcre.h:pcre.in pcre-config:pcre-config.in RunTest:RunTest.in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
 
@@ -1735,22 +1338,20 @@ s%@includedir@%$includedir%g
 s%@oldincludedir@%$oldincludedir%g
 s%@infodir@%$infodir%g
 s%@mandir@%$mandir%g
-s%@VERSION_MAJOR@%$VERSION_MAJOR%g
-s%@VERSION_MINOR@%$VERSION_MINOR%g
-s%@VERSION_POINT@%$VERSION_POINT%g
 s%@CC@%$CC%g
+s%@RANLIB@%$RANLIB%g
 s%@CPP@%$CPP%g
-s%@EXEEXT@%$EXEEXT%g
-s%@OBJEXT@%$OBJEXT%g
-s%@WIN_ONLY@%$WIN_ONLY%g
-s%@CYGWIN_FLAGS@%$CYGWIN_FLAGS%g
-s%@SOLARIS_ONLY@%$SOLARIS_ONLY%g
-s%@GNU_REGEX_ONLY@%$GNU_REGEX_ONLY%g
-s%@PCRE_REGEX_ONLY@%$PCRE_REGEX_ONLY%g
-s%@NO_REGEX_ONLY@%$NO_REGEX_ONLY%g
-s%@PCRS_ONLY@%$PCRS_ONLY%g
-s%@LIBRARY_PCRE_ONLY@%$LIBRARY_PCRE_ONLY%g
-s%@STATIC_PCRE_ONLY@%$STATIC_PCRE_ONLY%g
+s%@HAVE_MEMMOVE@%$HAVE_MEMMOVE%g
+s%@HAVE_STRERROR@%$HAVE_STRERROR%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@LIBSUFFIX@%$LIBSUFFIX%g
+s%@UTF8@%$UTF8%g
+s%@PCRE_MAJOR@%$PCRE_MAJOR%g
+s%@PCRE_MINOR@%$PCRE_MINOR%g
+s%@PCRE_DATE@%$PCRE_DATE%g
+s%@PCRE_VERSION@%$PCRE_VERSION%g
+s%@PCRE_LIB_VERSION@%$PCRE_LIB_VERSION%g
+s%@PCRE_POSIXLIB_VERSION@%$PCRE_POSIXLIB_VERSION%g
 
 CEOF
 EOF
@@ -1792,7 +1393,7 @@ EOF
 
 cat >> $CONFIG_STATUS <<EOF
 
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+CONFIG_FILES=\${CONFIG_FILES-"Makefile pcre.h:pcre.in pcre-config:pcre-config.in RunTest:RunTest.in"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
@@ -1868,7 +1469,7 @@ ac_eD='%g'
 if test "${CONFIG_HEADERS+set}" != set; then
 EOF
 cat >> $CONFIG_STATUS <<EOF
-  CONFIG_HEADERS="config.h"
+  CONFIG_HEADERS="config.h:config.in"
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 fi
@@ -1958,11 +1559,10 @@ cat >> $CONFIG_STATUS <<EOF
 
 EOF
 cat >> $CONFIG_STATUS <<\EOF
-
+chmod a+x RunTest pcre-config
 exit 0
 EOF
 chmod +x $CONFIG_STATUS
 rm -fr confdefs* $ac_clean_files
 test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
 
-
diff --git a/pcre/configure.in b/pcre/configure.in
new file mode 100644 (file)
index 0000000..c98387d
--- /dev/null
@@ -0,0 +1,85 @@
+dnl Process this file with autoconf to produce a configure script.
+
+dnl This is required at the start; the name is the name of a file
+dnl it should be seeing, to verify it is in the same directory.
+
+AC_INIT(dftables.c)
+
+dnl Arrange to build config.h from config.in. Note that pcre.h is
+dnl built differently, as it is just a "substitution" file.
+dnl Manual says this macro should come right after AC_INIT.
+AC_CONFIG_HEADER(config.h:config.in)
+
+dnl Provide the current PCRE version information. Do not use numbers
+dnl with leading zeros for the minor version, as they end up in a C
+dnl macro, and may be treated as octal constants. Stick to single
+dnl digits for minor numbers less than 10. There are unlikely to be
+dnl that many releases anyway.
+
+PCRE_MAJOR=3
+PCRE_MINOR=4
+PCRE_DATE=22-Aug-2000
+PCRE_VERSION=${PCRE_MAJOR}.${PCRE_MINOR}
+
+dnl Provide versioning information for libtool shared libraries that
+dnl are built by default on Unix systems.
+
+PCRE_LIB_VERSION=0:1:0
+PCRE_POSIXLIB_VERSION=0:0:0
+
+dnl Checks for programs.
+
+AC_PROG_CC
+AC_PROG_RANLIB
+
+dnl Checks for header files.
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(limits.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+dnl Checks for library functions.
+
+AC_CHECK_FUNCS(bcopy memmove strerror)
+
+dnl Handle --enable-shared-libraries
+
+LIBTOOL=./libtool
+LIBSUFFIX=la
+AC_ARG_ENABLE(shared,
+[  --disable-shared        build PCRE as a static library],
+if test "$enableval" = "no"; then
+  LIBTOOL=
+  LIBSUFFIX=a
+fi
+)
+
+dnl Handle --enable-utf8
+
+AC_ARG_ENABLE(utf8,
+[  --enable-utf8           enable UTF8 support (incomplete)],
+if test "$enableval" = "yes"; then
+  UTF8=-DSUPPORT_UTF8
+fi
+)
+
+dnl "Export" these variables
+
+AC_SUBST(HAVE_MEMMOVE)
+AC_SUBST(HAVE_STRERROR)
+AC_SUBST(LIBTOOL)
+AC_SUBST(LIBSUFFIX)
+AC_SUBST(UTF8)
+AC_SUBST(PCRE_MAJOR)
+AC_SUBST(PCRE_MINOR)
+AC_SUBST(PCRE_DATE)
+AC_SUBST(PCRE_VERSION)
+AC_SUBST(PCRE_LIB_VERSION)
+AC_SUBST(PCRE_POSIXLIB_VERSION)
+
+dnl This must be last; it determines what files are written
+AC_OUTPUT(Makefile pcre.h:pcre.in pcre-config:pcre-config.in RunTest:RunTest.in,[chmod a+x RunTest pcre-config])
diff --git a/pcre/dftables.c b/pcre/dftables.c
new file mode 100644 (file)
index 0000000..d572dfd
--- /dev/null
@@ -0,0 +1,148 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/*
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+           Copyright (c) 1997-2000 University of Cambridge
+
+-----------------------------------------------------------------------------
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), then the terms of that licence shall
+   supersede any condition above with which it is incompatible.
+-----------------------------------------------------------------------------
+
+See the file Tech.Notes for some information on the internals.
+*/
+
+
+/* This is a support program to generate the file chartables.c, containing
+character tables of various kinds. They are built according to the default C
+locale and used as the default tables by PCRE. Now that pcre_maketables is
+a function visible to the outside world, we make use of its code from here in
+order to be consistent. */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "internal.h"
+
+#define DFTABLES          /* maketables.c notices this */
+#include "maketables.c"
+
+
+int main(void)
+{
+int i;
+unsigned const char *tables = pcre_maketables();
+
+printf(
+  "/*************************************************\n"
+  "*      Perl-Compatible Regular Expressions       *\n"
+  "*************************************************/\n\n"
+  "/* This file is automatically written by the dftables auxiliary \n"
+  "program. If you edit it by hand, you might like to edit the Makefile to \n"
+  "prevent its ever being regenerated.\n\n"
+  "This file is #included in the compilation of pcre.c to build the default\n"
+  "character tables which are used when no tables are passed to the compile\n"
+  "function. */\n\n"
+  "static unsigned char pcre_default_tables[] = {\n\n"
+  "/* This table is a lower casing table. */\n\n");
+
+printf("  ");
+for (i = 0; i < 256; i++)
+  {
+  if ((i & 7) == 0 && i != 0) printf("\n  ");
+  printf("%3d", *tables++);
+  if (i != 255) printf(",");
+  }
+printf(",\n\n");
+
+printf("/* This table is a case flipping table. */\n\n");
+
+printf("  ");
+for (i = 0; i < 256; i++)
+  {
+  if ((i & 7) == 0 && i != 0) printf("\n  ");
+  printf("%3d", *tables++);
+  if (i != 255) printf(",");
+  }
+printf(",\n\n");
+
+printf(
+  "/* This table contains bit maps for various character classes.\n"
+  "Each map is 32 bytes long and the bits run from the least\n"
+  "significant end of each byte. The classes that have their own\n"
+  "maps are: space, xdigit, digit, upper, lower, word, graph\n"
+  "print, punct, and cntrl. Other classes are built from combinations. */\n\n");
+
+printf("  ");
+for (i = 0; i < cbit_length; i++)
+  {
+  if ((i & 7) == 0 && i != 0)
+    {
+    if ((i & 31) == 0) printf("\n");
+    printf("\n  ");
+    }
+  printf("0x%02x", *tables++);
+  if (i != cbit_length - 1) printf(",");
+  }
+printf(",\n\n");
+
+printf(
+  "/* This table identifies various classes of character by individual bits:\n"
+  "  0x%02x   white space character\n"
+  "  0x%02x   letter\n"
+  "  0x%02x   decimal digit\n"
+  "  0x%02x   hexadecimal digit\n"
+  "  0x%02x   alphanumeric or '_'\n"
+  "  0x%02x   regular expression metacharacter or binary zero\n*/\n\n",
+  ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word,
+  ctype_meta);
+
+printf("  ");
+for (i = 0; i < 256; i++)
+  {
+  if ((i & 7) == 0 && i != 0)
+    {
+    printf(" /* ");
+    if (isprint(i-8)) printf(" %c -", i-8);
+      else printf("%3d-", i-8);
+    if (isprint(i-1)) printf(" %c ", i-1);
+      else printf("%3d", i-1);
+    printf(" */\n  ");
+    }
+  printf("0x%02x", *tables++);
+  if (i != 255) printf(",");
+  }
+
+printf("};/* ");
+if (isprint(i-8)) printf(" %c -", i-8);
+  else printf("%3d-", i-8);
+if (isprint(i-1)) printf(" %c ", i-1);
+  else printf("%3d", i-1);
+printf(" */\n\n/* End of chartables.c */\n");
+
+return 0;
+}
+
+/* End of dftables.c */
diff --git a/pcre/dll.mk b/pcre/dll.mk
new file mode 100644 (file)
index 0000000..d8b728e
--- /dev/null
@@ -0,0 +1,60 @@
+# dll.mk - auxilary Makefile to easy build dll's for mingw32 target
+# ver. 0.6 of 1999-03-25
+#
+# Homepage of this makefile - http://www.is.lg.ua/~paul/devel/
+# Homepage of original mingw32 project -
+#                    http://www.fu.is.saga-u.ac.jp/~colin/gcc.html
+#
+# How to use:
+# This makefile can:
+# 1. Create automatical .def file from list of objects
+# 2. Create .dll from objects and .def file, either automatical, or your
+#    hand-written (maybe) file, which must have same basename as dll
+# WARNING! There MUST be object, which name match dll's name. Make sux.
+# 3. Create import library from .def (as for .dll, only its name required,
+#    not dll itself)
+#    By convention implibs for dll have .dll.a suffix, e.g. libstuff.dll.a
+#    Why not just libstuff.a? 'Cos that's name for static lib, ok?
+# Process divided into 3 phases because:
+# 1. Pre-existent .def possible
+# 2. Generating implib is enough time-consuming
+#
+# Variables:
+#   DLL_LDLIBS  - libs for linking dll
+#   DLL_LDFLAGS - flags for linking dll
+#
+# By using $(DLL_SUFFIX) instead of 'dll', e.g. stuff.$(DLL_SUFFIX)
+# you may help porting makefiles to other platforms
+#
+# Put this file in your make's include path (e.g. main include dir, for
+# more information see include section in make doc). Put in the beginning
+# of your own Makefile line "include dll.mk". Specify dependences, e.g.:
+#
+# Do all stuff in one step
+# libstuff.dll.a: $(OBJECTS) stuff.def
+# stuff.def: $(OBJECTS)
+#
+# Steps separated, pre-provided .def, link with user32
+#
+# DLL_LDLIBS=-luser32
+# stuff.dll: $(OBJECTS)
+# libstuff.dll.a: $(OBJECTS)
+
+
+DLLWRAP=dllwrap
+DLLTOOL=dlltool
+
+DLL_SUFFIX=dll
+
+.SUFFIXES: .o .$(DLL_SUFFIX)
+
+_%.def: %.o
+      $(DLLTOOL) --export-all --output-def $@ $^
+
+%.$(DLL_SUFFIX): %.o
+      $(DLLWRAP) --dllname $(notdir $@) --driver-name $(CC) --def $*.def -o $@ $(filter %.o,$^) $(DLL_LDFLAGS) $(DLL_LDLIBS)
+
+lib%.$(DLL_SUFFIX).a:%.def
+      $(DLLTOOL) --dllname $(notdir $*.dll) --def $< --output-lib $@
+
+# End
diff --git a/pcre/doc/ChangeLog b/pcre/doc/ChangeLog
new file mode 100644 (file)
index 0000000..2133dd7
--- /dev/null
@@ -0,0 +1,655 @@
+ChangeLog for PCRE
+------------------
+
+
+Version 3.4 22-Aug-00
+---------------------
+
+1. Fixed typo in pcre.h: unsigned const char * changed to const unsigned char *.
+
+2. Diagnose condition (?(0) as an error instead of crashing on matching.
+
+
+Version 3.3 01-Aug-00
+---------------------
+
+1. If an octal character was given, but the value was greater than \377, it
+was not getting masked to the least significant bits, as documented. This could
+lead to crashes in some systems.
+
+2. Perl 5.6 (if not earlier versions) accepts classes like [a-\d] and treats
+the hyphen as a literal. PCRE used to give an error; it now behaves like Perl.
+
+3. Added the functions pcre_free_substring() and pcre_free_substring_list().
+These just pass their arguments on to (pcre_free)(), but they are provided
+because some uses of PCRE bind it to non-C systems that can call its functions,
+but cannot call free() or pcre_free() directly.
+
+4. Add "make test" as a synonym for "make check". Corrected some comments in
+the Makefile.
+
+5. Add $(DESTDIR)/ in front of all the paths in the "install" target in the
+Makefile.
+
+6. Changed the name of pgrep to pcregrep, because Solaris has introduced a
+command called pgrep for grepping around the active processes.
+
+7. Added the beginnings of support for UTF-8 character strings.
+
+8. Arranged for the Makefile to pass over the settings of CC, CFLAGS, and
+RANLIB to ./ltconfig so that they are used by libtool. I think these are all
+the relevant ones. (AR is not passed because ./ltconfig does its own figuring
+out for the ar command.)
+
+
+Version 3.2 12-May-00
+---------------------
+
+This is purely a bug fixing release.
+
+1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead
+of ZA. This was just one example of several cases that could provoke this bug,
+which was introduced by change 9 of version 2.00. The code for breaking
+infinite loops after an iteration that matches an empty string was't working
+correctly.
+
+2. The pcretest program was not imitating Perl correctly for the pattern /a*/g
+when matched against abbab (for example). After matching an empty string, it
+wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this
+caused it to match further down the string than it should.
+
+3. The code contained an inclusion of sys/types.h. It isn't clear why this
+was there because it doesn't seem to be needed, and it causes trouble on some
+systems, as it is not a Standard C header. It has been removed.
+
+4. Made 4 silly changes to the source to avoid stupid compiler warnings that
+were reported on the Macintosh. The changes were from
+
+  while ((c = *(++ptr)) != 0 && c != '\n');
+to
+  while ((c = *(++ptr)) != 0 && c != '\n') ;
+
+Totally extraordinary, but if that's what it takes...
+
+5. PCRE is being used in one environment where neither memmove() nor bcopy() is
+available. Added HAVE_BCOPY and an autoconf test for it; if neither
+HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which
+assumes the way PCRE uses memmove() (always moving upwards).
+
+6. PCRE is being used in one environment where strchr() is not available. There
+was only one use in pcre.c, and writing it out to avoid strchr() probably gives
+faster code anyway.
+
+
+Version 3.1 09-Feb-00
+---------------------
+
+The only change in this release is the fixing of some bugs in Makefile.in for
+the "install" target:
+
+(1) It was failing to install pcreposix.h.
+
+(2) It was overwriting the pcre.3 man page with the pcreposix.3 man page.
+
+
+Version 3.0 01-Feb-00
+---------------------
+
+1. Add support for the /+ modifier to perltest (to output $` like it does in
+pcretest).
+
+2. Add support for the /g modifier to perltest.
+
+3. Fix pcretest so that it behaves even more like Perl for /g when the pattern
+matches null strings.
+
+4. Fix perltest so that it doesn't do unwanted things when fed an empty
+pattern. Perl treats empty patterns specially - it reuses the most recent
+pattern, which is not what we want. Replace // by /(?#)/ in order to avoid this
+effect.
+
+5. The POSIX interface was broken in that it was just handing over the POSIX
+captured string vector to pcre_exec(), but (since release 2.00) PCRE has
+required a bigger vector, with some working space on the end. This means that
+the POSIX wrapper now has to get and free some memory, and copy the results.
+
+6. Added some simple autoconf support, placing the test data and the
+documentation in separate directories, re-organizing some of the
+information files, and making it build pcre-config (a GNU standard). Also added
+libtool support for building PCRE as a shared library, which is now the
+default.
+
+7. Got rid of the leading zero in the definition of PCRE_MINOR because 08 and
+09 are not valid octal constants. Single digits will be used for minor values
+less than 10.
+
+8. Defined REG_EXTENDED and REG_NOSUB as zero in the POSIX header, so that
+existing programs that set these in the POSIX interface can use PCRE without
+modification.
+
+9. Added a new function, pcre_fullinfo() with an extensible interface. It can
+return all that pcre_info() returns, plus additional data. The pcre_info()
+function is retained for compatibility, but is considered to be obsolete.
+
+10. Added experimental recursion feature (?R) to handle one common case that
+Perl 5.6 will be able to do with (?p{...}).
+
+11. Added support for POSIX character classes like [:alpha:], which Perl is
+adopting.
+
+
+Version 2.08 31-Aug-99
+----------------------
+
+1. When startoffset was not zero and the pattern began with ".*", PCRE was not
+trying to match at the startoffset position, but instead was moving forward to
+the next newline as if a previous match had failed.
+
+2. pcretest was not making use of PCRE_NOTEMPTY when repeating for /g and /G,
+and could get into a loop if a null string was matched other than at the start
+of the subject.
+
+3. Added definitions of PCRE_MAJOR and PCRE_MINOR to pcre.h so the version can
+be distinguished at compile time, and for completeness also added PCRE_DATE.
+
+5. Added Paul Sokolovsky's minor changes to make it easy to compile a Win32 DLL
+in GnuWin32 environments.
+
+
+Version 2.07 29-Jul-99
+----------------------
+
+1. The documentation is now supplied in plain text form and HTML as well as in
+the form of man page sources.
+
+2. C++ compilers don't like assigning (void *) values to other pointer types.
+In particular this affects malloc(). Although there is no problem in Standard
+C, I've put in casts to keep C++ compilers happy.
+
+3. Typo on pcretest.c; a cast of (unsigned char *) in the POSIX regexec() call
+should be (const char *).
+
+4. If NOPOSIX is defined, pcretest.c compiles without POSIX support. This may
+be useful for non-Unix systems who don't want to bother with the POSIX stuff.
+However, I haven't made this a standard facility. The documentation doesn't
+mention it, and the Makefile doesn't support it.
+
+5. The Makefile now contains an "install" target, with editable destinations at
+the top of the file. The pcretest program is not installed.
+
+6. pgrep -V now gives the PCRE version number and date.
+
+7. Fixed bug: a zero repetition after a literal string (e.g. /abcde{0}/) was
+causing the entire string to be ignored, instead of just the last character.
+
+8. If a pattern like /"([^\\"]+|\\.)*"/ is applied in the normal way to a
+non-matching string, it can take a very, very long time, even for strings of
+quite modest length, because of the nested recursion. PCRE now does better in
+some of these cases. It does this by remembering the last required literal
+character in the pattern, and pre-searching the subject to ensure it is present
+before running the real match. In other words, it applies a heuristic to detect
+some types of certain failure quickly, and in the above example, if presented
+with a string that has no trailing " it gives "no match" very quickly.
+
+9. A new runtime option PCRE_NOTEMPTY causes null string matches to be ignored;
+other alternatives are tried instead.
+
+
+Version 2.06 09-Jun-99
+----------------------
+
+1. Change pcretest's output for amount of store used to show just the code
+space, because the remainder (the data block) varies in size between 32-bit and
+64-bit systems.
+
+2. Added an extra argument to pcre_exec() to supply an offset in the subject to
+start matching at. This allows lookbehinds to work when searching for multiple
+occurrences in a string.
+
+3. Added additional options to pcretest for testing multiple occurrences:
+
+   /+   outputs the rest of the string that follows a match
+   /g   loops for multiple occurrences, using the new startoffset argument
+   /G   loops for multiple occurrences by passing an incremented pointer
+
+4. PCRE wasn't doing the "first character" optimization for patterns starting
+with \b or \B, though it was doing it for other lookbehind assertions. That is,
+it wasn't noticing that a match for a pattern such as /\bxyz/ has to start with
+the letter 'x'. On long subject strings, this gives a significant speed-up.
+
+
+Version 2.05 21-Apr-99
+----------------------
+
+1. Changed the type of magic_number from int to long int so that it works
+properly on 16-bit systems.
+
+2. Fixed a bug which caused patterns starting with .* not to work correctly
+when the subject string contained newline characters. PCRE was assuming
+anchoring for such patterns in all cases, which is not correct because .* will
+not pass a newline unless PCRE_DOTALL is set. It now assumes anchoring only if
+DOTALL is set at top level; otherwise it knows that patterns starting with .*
+must be retried after every newline in the subject.
+
+
+Version 2.04 18-Feb-99
+----------------------
+
+1. For parenthesized subpatterns with repeats whose minimum was zero, the
+computation of the store needed to hold the pattern was incorrect (too large).
+If such patterns were nested a few deep, this could multiply and become a real
+problem.
+
+2. Added /M option to pcretest to show the memory requirement of a specific
+pattern. Made -m a synonym of -s (which does this globally) for compatibility.
+
+3. Subpatterns of the form (regex){n,m} (i.e. limited maximum) were being
+compiled in such a way that the backtracking after subsequent failure was
+pessimal. Something like (a){0,3} was compiled as (a)?(a)?(a)? instead of
+((a)((a)(a)?)?)? with disastrous performance if the maximum was of any size.
+
+
+Version 2.03 02-Feb-99
+----------------------
+
+1. Fixed typo and small mistake in man page.
+
+2. Added 4th condition (GPL supersedes if conflict) and created separate
+LICENCE file containing the conditions.
+
+3. Updated pcretest so that patterns such as /abc\/def/ work like they do in
+Perl, that is the internal \ allows the delimiter to be included in the
+pattern. Locked out the use of \ as a delimiter. If \ immediately follows
+the final delimiter, add \ to the end of the pattern (to test the error).
+
+4. Added the convenience functions for extracting substrings after a successful
+match. Updated pcretest to make it able to test these functions.
+
+
+Version 2.02 14-Jan-99
+----------------------
+
+1. Initialized the working variables associated with each extraction so that
+their saving and restoring doesn't refer to uninitialized store.
+
+2. Put dummy code into study.c in order to trick the optimizer of the IBM C
+compiler for OS/2 into generating correct code. Apparently IBM isn't going to
+fix the problem.
+
+3. Pcretest: the timing code wasn't using LOOPREPEAT for timing execution
+calls, and wasn't printing the correct value for compiling calls. Increased the
+default value of LOOPREPEAT, and the number of significant figures in the
+times.
+
+4. Changed "/bin/rm" in the Makefile to "-rm" so it works on Windows NT.
+
+5. Renamed "deftables" as "dftables" to get it down to 8 characters, to avoid
+a building problem on Windows NT with a FAT file system.
+
+
+Version 2.01 21-Oct-98
+----------------------
+
+1. Changed the API for pcre_compile() to allow for the provision of a pointer
+to character tables built by pcre_maketables() in the current locale. If NULL
+is passed, the default tables are used.
+
+
+Version 2.00 24-Sep-98
+----------------------
+
+1. Since the (>?) facility is in Perl 5.005, don't require PCRE_EXTRA to enable
+it any more.
+
+2. Allow quantification of (?>) groups, and make it work correctly.
+
+3. The first character computation wasn't working for (?>) groups.
+
+4. Correct the implementation of \Z (it is permitted to match on the \n at the
+end of the subject) and add 5.005's \z, which really does match only at the
+very end of the subject.
+
+5. Remove the \X "cut" facility; Perl doesn't have it, and (?> is neater.
+
+6. Remove the ability to specify CASELESS, MULTILINE, DOTALL, and
+DOLLAR_END_ONLY at runtime, to make it possible to implement the Perl 5.005
+localized options. All options to pcre_study() were also removed.
+
+7. Add other new features from 5.005:
+
+   $(?<=           positive lookbehind
+   $(?<!           negative lookbehind
+   (?imsx-imsx)    added the unsetting capability
+                   such a setting is global if at outer level; local otherwise
+   (?imsx-imsx:)   non-capturing groups with option setting
+   (?(cond)re|re)  conditional pattern matching
+
+   A backreference to itself in a repeated group matches the previous
+   captured string.
+
+8. General tidying up of studying (both automatic and via "study")
+consequential on the addition of new assertions.
+
+9. As in 5.005, unlimited repeated groups that could match an empty substring
+are no longer faulted at compile time. Instead, the loop is forcibly broken at
+runtime if any iteration does actually match an empty substring.
+
+10. Include the RunTest script in the distribution.
+
+11. Added tests from the Perl 5.005_02 distribution. This showed up a few
+discrepancies, some of which were old and were also with respect to 5.004. They
+have now been fixed.
+
+
+Version 1.09 28-Apr-98
+----------------------
+
+1. A negated single character class followed by a quantifier with a minimum
+value of one (e.g.  [^x]{1,6}  ) was not compiled correctly. This could lead to
+program crashes, or just wrong answers. This did not apply to negated classes
+containing more than one character, or to minima other than one.
+
+
+Version 1.08 27-Mar-98
+----------------------
+
+1. Add PCRE_UNGREEDY to invert the greediness of quantifiers.
+
+2. Add (?U) and (?X) to set PCRE_UNGREEDY and PCRE_EXTRA respectively. The
+latter must appear before anything that relies on it in the pattern.
+
+
+Version 1.07 16-Feb-98
+----------------------
+
+1. A pattern such as /((a)*)*/ was not being diagnosed as in error (unlimited
+repeat of a potentially empty string).
+
+
+Version 1.06 23-Jan-98
+----------------------
+
+1. Added Markus Oberhumer's little patches for C++.
+
+2. Literal strings longer than 255 characters were broken.
+
+
+Version 1.05 23-Dec-97
+----------------------
+
+1. Negated character classes containing more than one character were failing if
+PCRE_CASELESS was set at run time.
+
+
+Version 1.04 19-Dec-97
+----------------------
+
+1. Corrected the man page, where some "const" qualifiers had been omitted.
+
+2. Made debugging output print "{0,xxx}" instead of just "{,xxx}" to agree with
+input syntax.
+
+3. Fixed memory leak which occurred when a regex with back references was
+matched with an offsets vector that wasn't big enough. The temporary memory
+that is used in this case wasn't being freed if the match failed.
+
+4. Tidied pcretest to ensure it frees memory that it gets.
+
+5. Temporary memory was being obtained in the case where the passed offsets
+vector was exactly big enough.
+
+6. Corrected definition of offsetof() from change 5 below.
+
+7. I had screwed up change 6 below and broken the rules for the use of
+setjmp(). Now fixed.
+
+
+Version 1.03 18-Dec-97
+----------------------
+
+1. A erroneous regex with a missing opening parenthesis was correctly
+diagnosed, but PCRE attempted to access brastack[-1], which could cause crashes
+on some systems.
+
+2. Replaced offsetof(real_pcre, code) by offsetof(real_pcre, code[0]) because
+it was reported that one broken compiler failed on the former because "code" is
+also an independent variable.
+
+3. The erroneous regex a[]b caused an array overrun reference.
+
+4. A regex ending with a one-character negative class (e.g. /[^k]$/) did not
+fail on data ending with that character. (It was going on too far, and checking
+the next character, typically a binary zero.) This was specific to the
+optimized code for single-character negative classes.
+
+5. Added a contributed patch from the TIN world which does the following:
+
+  + Add an undef for memmove, in case the the system defines a macro for it.
+
+  + Add a definition of offsetof(), in case there isn't one. (I don't know
+    the reason behind this - offsetof() is part of the ANSI standard - but
+    it does no harm).
+
+  + Reduce the ifdef's in pcre.c using macro DPRINTF, thereby eliminating
+    most of the places where whitespace preceded '#'. I have given up and
+    allowed the remaining 2 cases to be at the margin.
+
+  + Rename some variables in pcre to eliminate shadowing. This seems very
+    pedantic, but does no harm, of course.
+
+6. Moved the call to setjmp() into its own function, to get rid of warnings
+from gcc -Wall, and avoided calling it at all unless PCRE_EXTRA is used.
+
+7. Constructs such as \d{8,} were compiling into the equivalent of
+\d{8}\d{0,65527} instead of \d{8}\d* which didn't make much difference to the
+outcome, but in this particular case used more store than had been allocated,
+which caused the bug to be discovered because it threw up an internal error.
+
+8. The debugging code in both pcre and pcretest for outputting the compiled
+form of a regex was going wrong in the case of back references followed by
+curly-bracketed repeats.
+
+
+Version 1.02 12-Dec-97
+----------------------
+
+1. Typos in pcre.3 and comments in the source fixed.
+
+2. Applied a contributed patch to get rid of places where it used to remove
+'const' from variables, and fixed some signed/unsigned and uninitialized
+variable warnings.
+
+3. Added the "runtest" target to Makefile.
+
+4. Set default compiler flag to -O2 rather than just -O.
+
+
+Version 1.01 19-Nov-97
+----------------------
+
+1. PCRE was failing to diagnose unlimited repeat of empty string for patterns
+like /([ab]*)*/, that is, for classes with more than one character in them.
+
+2. Likewise, it wasn't diagnosing patterns with "once-only" subpatterns, such
+as /((?>a*))*/ (a PCRE_EXTRA facility).
+
+
+Version 1.00 18-Nov-97
+----------------------
+
+1. Added compile-time macros to support systems such as SunOS4 which don't have
+memmove() or strerror() but have other things that can be used instead.
+
+2. Arranged that "make clean" removes the executables.
+
+
+Version 0.99 27-Oct-97
+----------------------
+
+1. Fixed bug in code for optimizing classes with only one character. It was
+initializing a 32-byte map regardless, which could cause it to run off the end
+of the memory it had got.
+
+2. Added, conditional on PCRE_EXTRA, the proposed (?>REGEX) construction.
+
+
+Version 0.98 22-Oct-97
+----------------------
+
+1. Fixed bug in code for handling temporary memory usage when there are more
+back references than supplied space in the ovector. This could cause segfaults.
+
+
+Version 0.97 21-Oct-97
+----------------------
+
+1. Added the \X "cut" facility, conditional on PCRE_EXTRA.
+
+2. Optimized negated single characters not to use a bit map.
+
+3. Brought error texts together as macro definitions; clarified some of them;
+fixed one that was wrong - it said "range out of order" when it meant "invalid
+escape sequence".
+
+4. Changed some char * arguments to const char *.
+
+5. Added PCRE_NOTBOL and PCRE_NOTEOL (from POSIX).
+
+6. Added the POSIX-style API wrapper in pcreposix.a and testing facilities in
+pcretest.
+
+
+Version 0.96 16-Oct-97
+----------------------
+
+1. Added a simple "pgrep" utility to the distribution.
+
+2. Fixed an incompatibility with Perl: "{" is now treated as a normal character
+unless it appears in one of the precise forms "{ddd}", "{ddd,}", or "{ddd,ddd}"
+where "ddd" means "one or more decimal digits".
+
+3. Fixed serious bug. If a pattern had a back reference, but the call to
+pcre_exec() didn't supply a large enough ovector to record the related
+identifying subpattern, the match always failed. PCRE now remembers the number
+of the largest back reference, and gets some temporary memory in which to save
+the offsets during matching if necessary, in order to ensure that
+backreferences always work.
+
+4. Increased the compatibility with Perl in a number of ways:
+
+  (a) . no longer matches \n by default; an option PCRE_DOTALL is provided
+      to request this handling. The option can be set at compile or exec time.
+
+  (b) $ matches before a terminating newline by default; an option
+      PCRE_DOLLAR_ENDONLY is provided to override this (but not in multiline
+      mode). The option can be set at compile or exec time.
+
+  (c) The handling of \ followed by a digit other than 0 is now supposed to be
+      the same as Perl's. If the decimal number it represents is less than 10
+      or there aren't that many previous left capturing parentheses, an octal
+      escape is read. Inside a character class, it's always an octal escape,
+      even if it is a single digit.
+
+  (d) An escaped but undefined alphabetic character is taken as a literal,
+      unless PCRE_EXTRA is set. Currently this just reserves the remaining
+      escapes.
+
+  (e) {0} is now permitted. (The previous item is removed from the compiled
+      pattern).
+
+5. Changed all the names of code files so that the basic parts are no longer
+than 10 characters, and abolished the teeny "globals.c" file.
+
+6. Changed the handling of character classes; they are now done with a 32-byte
+bit map always.
+
+7. Added the -d and /D options to pcretest to make it possible to look at the
+internals of compilation without having to recompile pcre.
+
+
+Version 0.95 23-Sep-97
+----------------------
+
+1. Fixed bug in pre-pass concerning escaped "normal" characters such as \x5c or
+\x20 at the start of a run of normal characters. These were being treated as
+real characters, instead of the source characters being re-checked.
+
+
+Version 0.94 18-Sep-97
+----------------------
+
+1. The functions are now thread-safe, with the caveat that the global variables
+containing pointers to malloc() and free() or alternative functions are the
+same for all threads.
+
+2. Get pcre_study() to generate a bitmap of initial characters for non-
+anchored patterns when this is possible, and use it if passed to pcre_exec().
+
+
+Version 0.93 15-Sep-97
+----------------------
+
+1. /(b)|(:+)/ was computing an incorrect first character.
+
+2. Add pcre_study() to the API and the passing of pcre_extra to pcre_exec(),
+but not actually doing anything yet.
+
+3. Treat "-" characters in classes that cannot be part of ranges as literals,
+as Perl does (e.g. [-az] or [az-]).
+
+4. Set the anchored flag if a branch starts with .* or .*? because that tests
+all possible positions.
+
+5. Split up into different modules to avoid including unneeded functions in a
+compiled binary. However, compile and exec are still in one module. The "study"
+function is split off.
+
+6. The character tables are now in a separate module whose source is generated
+by an auxiliary program - but can then be edited by hand if required. There are
+now no calls to isalnum(), isspace(), isdigit(), isxdigit(), tolower() or
+toupper() in the code.
+
+7. Turn the malloc/free funtions variables into pcre_malloc and pcre_free and
+make them global. Abolish the function for setting them, as the caller can now
+set them directly.
+
+
+Version 0.92 11-Sep-97
+----------------------
+
+1. A repeat with a fixed maximum and a minimum of 1 for an ordinary character
+(e.g. /a{1,3}/) was broken (I mis-optimized it).
+
+2. Caseless matching was not working in character classes if the characters in
+the pattern were in upper case.
+
+3. Make ranges like [W-c] work in the same way as Perl for caseless matching.
+
+4. Make PCRE_ANCHORED public and accept as a compile option.
+
+5. Add an options word to pcre_exec() and accept PCRE_ANCHORED and
+PCRE_CASELESS at run time. Add escapes \A and \I to pcretest to cause it to
+pass them.
+
+6. Give an error if bad option bits passed at compile or run time.
+
+7. Add PCRE_MULTILINE at compile and exec time, and (?m) as well. Add \M to
+pcretest to cause it to pass that flag.
+
+8. Add pcre_info(), to get the number of identifying subpatterns, the stored
+options, and the first character, if set.
+
+9. Recognize C+ or C{n,m} where n >= 1 as providing a fixed starting character.
+
+
+Version 0.91 10-Sep-97
+----------------------
+
+1. PCRE was failing to diagnose unlimited repeats of subpatterns that could
+match the empty string as in /(a*)*/. It was looping and ultimately crashing.
+
+2. PCRE was looping on encountering an indefinitely repeated back reference to
+a subpattern that had matched an empty string, e.g. /(a|)\1*/. It now does what
+Perl does - treats the match as successful.
+
+****
diff --git a/pcre/doc/NON-UNIX-USE b/pcre/doc/NON-UNIX-USE
new file mode 100644 (file)
index 0000000..09a7432
--- /dev/null
@@ -0,0 +1,50 @@
+Compiling PCRE on non-Unix systems
+----------------------------------
+
+If you want to compile PCRE for a non-Unix system, note that it consists
+entirely of code written in Standard C, and so should compile successfully
+on any machine with a Standard C compiler and library, using normal compiling
+commands to do the following:
+
+(1) Copy or rename the file config.in as config.h, and change the macros that
+define HAVE_STRERROR and HAVE_MEMMOVE to define them as 1 rather than 0.
+Unfortunately, because of the way Unix autoconf works, the default setting has
+to be 0.
+
+(2) Copy or rename the file pcre.in as pcre.h, and change the macro definitions
+for PCRE_MAJOR, PCRE_MINOR, and PCRE_DATE near its start to the values set in
+configure.in.
+
+(3) Compile dftables.c as a stand-alone program, and then run it with
+the standard output sent to chartables.c. This generates a set of standard
+character tables.
+
+(4) Compile maketables.c, get.c, study.c and pcre.c and link them all
+together into an object library in whichever form your system keeps such
+libraries. This is the pcre library (chartables.c gets included by means of an
+#include directive).
+
+(5) Similarly, compile pcreposix.c and link it as the pcreposix library.
+
+(6) Compile the test program pcretest.c. This needs the functions in the
+pcre and pcreposix libraries when linking.
+
+(7) Run pcretest on the testinput files in the testdata directory, and check
+that the output matches the corresponding testoutput files. You must use the
+-i option when checking testinput2.
+
+If you have a system without "configure" but where you can use a Makefile, edit
+Makefile.in to create Makefile, substituting suitable values for the variables
+at the head of the file.
+
+Some help in building a Win32 DLL of PCRE in GnuWin32 environments was
+contributed by Paul.Sokolovsky@technologist.com. These environments are
+Mingw32 (http://www.xraylith.wisc.edu/~khan/software/gnu-win32/) and
+CygWin  (http://sourceware.cygnus.com/cygwin/). Paul comments:
+
+  For CygWin, set CFLAGS=-mno-cygwin, and do 'make dll'. You'll get
+  pcre.dll (containing pcreposix also), libpcre.dll.a, and dynamically
+  linked pgrep and pcretest. If you have /bin/sh, run RunTest (three
+  main test go ok, locale not supported).
+
+****
diff --git a/pcre/doc/Tech.Notes b/pcre/doc/Tech.Notes
new file mode 100644 (file)
index 0000000..7b96e5b
--- /dev/null
@@ -0,0 +1,243 @@
+Technical Notes about PCRE
+--------------------------
+
+Many years ago I implemented some regular expression functions to an algorithm
+suggested by Martin Richards. These were not Unix-like in form, and were quite
+restricted in what they could do by comparison with Perl. The interesting part
+about the algorithm was that the amount of space required to hold the compiled
+form of an expression was known in advance. The code to apply an expression did
+not operate by backtracking, as the Henry Spencer and Perl code does, but
+instead checked all possibilities simultaneously by keeping a list of current
+states and checking all of them as it advanced through the subject string. (In
+the terminology of Jeffrey Friedl's book, it was a "DFA algorithm".) When the
+pattern was all used up, all remaining states were possible matches, and the
+one matching the longest subset of the subject string was chosen. This did not
+necessarily maximize the individual wild portions of the pattern, as is
+expected in Unix and Perl-style regular expressions.
+
+By contrast, the code originally written by Henry Spencer and subsequently
+heavily modified for Perl actually compiles the expression twice: once in a
+dummy mode in order to find out how much store will be needed, and then for
+real. The execution function operates by backtracking and maximizing (or,
+optionally, minimizing in Perl) the amount of the subject that matches
+individual wild portions of the pattern. This is an "NFA algorithm" in Friedl's
+terminology.
+
+For the set of functions that forms PCRE (which are unrelated to those
+mentioned above), I tried at first to invent an algorithm that used an amount
+of store bounded by a multiple of the number of characters in the pattern, to
+save on compiling time. However, because of the greater complexity in Perl
+regular expressions, I couldn't do this. In any case, a first pass through the
+pattern is needed, in order to find internal flag settings like (?i) at top
+level. So PCRE works by running a very degenerate first pass to calculate a
+maximum store size, and then a second pass to do the real compile - which may
+use a bit less than the predicted amount of store. The idea is that this is
+going to turn out faster because the first pass is degenerate and the second
+pass can just store stuff straight into the vector. It does make the compiling
+functions bigger, of course, but they have got quite big anyway to handle all
+the Perl stuff.
+
+The compiled form of a pattern is a vector of bytes, containing items of
+variable length. The first byte in an item is an opcode, and the length of the
+item is either implicit in the opcode or contained in the data bytes which
+follow it. A list of all the opcodes follows:
+
+Opcodes with no following data
+------------------------------
+
+These items are all just one byte long
+
+  OP_END                 end of pattern
+  OP_ANY                 match any character
+  OP_SOD                 match start of data: \A
+  OP_CIRC                ^ (start of data, or after \n in multiline)
+  OP_NOT_WORD_BOUNDARY   \W
+  OP_WORD_BOUNDARY       \w
+  OP_NOT_DIGIT           \D
+  OP_DIGIT               \d
+  OP_NOT_WHITESPACE      \S
+  OP_WHITESPACE          \s
+  OP_NOT_WORDCHAR        \W
+  OP_WORDCHAR            \w
+  OP_EODN                match end of data or \n at end: \Z
+  OP_EOD                 match end of data: \z
+  OP_DOLL                $ (end of data, or before \n in multiline)
+  OP_RECURSE             match the pattern recursively
+
+
+Repeating single characters
+---------------------------
+
+The common repeats (*, +, ?) when applied to a single character appear as
+two-byte items using the following opcodes:
+
+  OP_STAR
+  OP_MINSTAR
+  OP_PLUS
+  OP_MINPLUS
+  OP_QUERY
+  OP_MINQUERY
+
+Those with "MIN" in their name are the minimizing versions. Each is followed by
+the character that is to be repeated. Other repeats make use of
+
+  OP_UPTO
+  OP_MINUPTO
+  OP_EXACT
+
+which are followed by a two-byte count (most significant first) and the
+repeated character. OP_UPTO matches from 0 to the given number. A repeat with a
+non-zero minimum and a fixed maximum is coded as an OP_EXACT followed by an
+OP_UPTO (or OP_MINUPTO).
+
+
+Repeating character types
+-------------------------
+
+Repeats of things like \d are done exactly as for single characters, except
+that instead of a character, the opcode for the type is stored in the data
+byte. The opcodes are:
+
+  OP_TYPESTAR
+  OP_TYPEMINSTAR
+  OP_TYPEPLUS
+  OP_TYPEMINPLUS
+  OP_TYPEQUERY
+  OP_TYPEMINQUERY
+  OP_TYPEUPTO
+  OP_TYPEMINUPTO
+  OP_TYPEEXACT
+
+
+Matching a character string
+---------------------------
+
+The OP_CHARS opcode is followed by a one-byte count and then that number of
+characters. If there are more than 255 characters in sequence, successive
+instances of OP_CHARS are used.
+
+
+Character classes
+-----------------
+
+OP_CLASS is used for a character class, provided there are at least two
+characters in the class. If there is only one character, OP_CHARS is used for a
+positive class, and OP_NOT for a negative one (that is, for something like
+[^a]). Another set of repeating opcodes (OP_NOTSTAR etc.) are used for a
+repeated, negated, single-character class. The normal ones (OP_STAR etc.) are
+used for a repeated positive single-character class.
+
+OP_CLASS is followed by a 32-byte bit map containing a 1 bit for every
+character that is acceptable. The bits are counted from the least significant
+end of each byte.
+
+
+Back references
+---------------
+
+OP_REF is followed by a single byte containing the reference number.
+
+
+Repeating character classes and back references
+-----------------------------------------------
+
+Single-character classes are handled specially (see above). This applies to
+OP_CLASS and OP_REF. In both cases, the repeat information follows the base
+item. The matching code looks at the following opcode to see if it is one of
+
+  OP_CRSTAR
+  OP_CRMINSTAR
+  OP_CRPLUS
+  OP_CRMINPLUS
+  OP_CRQUERY
+  OP_CRMINQUERY
+  OP_CRRANGE
+  OP_CRMINRANGE
+
+All but the last two are just single-byte items. The others are followed by
+four bytes of data, comprising the minimum and maximum repeat counts.
+
+
+Brackets and alternation
+------------------------
+
+A pair of non-capturing (round) brackets is wrapped round each expression at
+compile time, so alternation always happens in the context of brackets.
+Non-capturing brackets use the opcode OP_BRA, while capturing brackets use
+OP_BRA+1, OP_BRA+2, etc. [Note for North Americans: "bracket" to some English
+speakers, including myself, can be round, square, curly, or pointy. Hence this
+usage.]
+
+A bracket opcode is followed by two bytes which give the offset to the next
+alternative OP_ALT or, if there aren't any branches, to the matching KET
+opcode. Each OP_ALT is followed by two bytes giving the offset to the next one,
+or to the KET opcode.
+
+OP_KET is used for subpatterns that do not repeat indefinitely, while
+OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or
+maximally respectively. All three are followed by two bytes giving (as a
+positive number) the offset back to the matching BRA opcode.
+
+If a subpattern is quantified such that it is permitted to match zero times, it
+is preceded by one of OP_BRAZERO or OP_BRAMINZERO. These are single-byte
+opcodes which tell the matcher that skipping this subpattern entirely is a
+valid branch.
+
+A subpattern with an indefinite maximum repetition is replicated in the
+compiled data its minimum number of times (or once with a BRAZERO if the
+minimum is zero), with the final copy terminating with a KETRMIN or KETRMAX as
+appropriate.
+
+A subpattern with a bounded maximum repetition is replicated in a nested
+fashion up to the maximum number of times, with BRAZERO or BRAMINZERO before
+each replication after the minimum, so that, for example, (abc){2,5} is
+compiled as (abc)(abc)((abc)((abc)(abc)?)?)?. The 200-bracket limit does not
+apply to these internally generated brackets.
+
+
+Assertions
+----------
+
+Forward assertions are just like other subpatterns, but starting with one of
+the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes
+OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion
+is OP_REVERSE, followed by a two byte count of the number of characters to move
+back the pointer in the subject string. When operating in UTF-8 mode, the count
+is a character count rather than a byte count. A separate count is present in
+each alternative of a lookbehind assertion, allowing them to have different
+fixed lengths.
+
+
+Once-only subpatterns
+---------------------
+
+These are also just like other subpatterns, but they start with the opcode
+OP_ONCE.
+
+
+Conditional subpatterns
+-----------------------
+
+These are like other subpatterns, but they start with the opcode OP_COND. If
+the condition is a back reference, this is stored at the start of the
+subpattern using the opcode OP_CREF followed by one byte containing the
+reference number. Otherwise, a conditional subpattern will always start with
+one of the assertions.
+
+
+Changing options
+----------------
+
+If any of the /i, /m, or /s options are changed within a parenthesized group,
+an OP_OPT opcode is compiled, followed by one byte containing the new settings
+of these flags. If there are several alternatives in a group, there is an
+occurrence of OP_OPT at the start of all those following the first options
+change, to set appropriate options for the start of the alternative.
+Immediately after the end of the group there is another such item to reset the
+flags to their previous values. Other changes of flag within the pattern can be
+handled entirely at compile time, and so do not cause anything to be put into
+the compiled data.
+
+
+Philip Hazel
+August 2000
diff --git a/pcre/doc/authors b/pcre/doc/authors
new file mode 100644 (file)
index 0000000..bfe1b5d
--- /dev/null
@@ -0,0 +1,6 @@
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2000 University of Cambridge
diff --git a/pcre/doc/copying b/pcre/doc/copying
new file mode 100644 (file)
index 0000000..34d20db
--- /dev/null
@@ -0,0 +1,46 @@
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2000 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission. In practice, this means that if you use
+   PCRE in software which you distribute to others, commercially or
+   otherwise, you must put a sentence like this
+
+     Regular expression support is provided by the PCRE library package,
+     which is open source software, written by Philip Hazel, and copyright
+     by the University of Cambridge, England.
+
+   somewhere reasonably visible in your documentation and in any relevant
+   files or online help data or similar. A reference to the ftp site for
+   the source, that is, to
+
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+   should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), then the terms of that licence shall
+   supersede any condition above with which it is incompatible.
+
+End
diff --git a/pcre/doc/news b/pcre/doc/news
new file mode 100644 (file)
index 0000000..56fccdf
--- /dev/null
@@ -0,0 +1,54 @@
+News about PCRE releases
+------------------------
+
+Release 3.3 01-Aug-00
+---------------------
+
+There is some support for UTF-8 character strings. This is incomplete and
+experimental. The documentation describes what is and what is not implemented.
+Otherwise, this is just a bug-fixing release.
+
+
+Release 3.0 01-Feb-00
+---------------------
+
+1. A "configure" script is now used to configure PCRE for Unix systems. It
+builds a Makefile, a config.h file, and the pcre-config script.
+
+2. PCRE is built as a shared library by default.
+
+3. There is support for POSIX classes such as [:alpha:].
+
+5. There is an experimental recursion feature.
+
+----------------------------------------------------------------------------
+          IMPORTANT FOR THOSE UPGRADING FROM VERSIONS BEFORE 2.00
+
+Please note that there has been a change in the API such that a larger
+ovector is required at matching time, to provide some additional workspace.
+The new man page has details. This change was necessary in order to support
+some of the new functionality in Perl 5.005.
+
+          IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.00
+
+Another (I hope this is the last!) change has been made to the API for the
+pcre_compile() function. An additional argument has been added to make it
+possible to pass over a pointer to character tables built in the current
+locale by pcre_maketables(). To use the default tables, this new arguement
+should be passed as NULL.
+
+          IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05
+
+Yet another (and again I hope this really is the last) change has been made
+to the API for the pcre_exec() function. An additional argument has been
+added to make it possible to start the match other than at the start of the
+subject string. This is important if there are lookbehinds. The new man
+page has the details, but you just want to convert existing programs, all
+you need to do is to stick in a new fifth argument to pcre_exec(), with a
+value of zero. For example, change
+
+  pcre_exec(pattern, extra, subject, length, options, ovec, ovecsize)
+to
+  pcre_exec(pattern, extra, subject, length, 0, options, ovec, ovecsize)
+
+****
diff --git a/pcre/doc/pcre.3 b/pcre/doc/pcre.3
new file mode 100644 (file)
index 0000000..bb812f4
--- /dev/null
@@ -0,0 +1,1810 @@
+.TH PCRE 3\r
+.SH NAME\r
+pcre - Perl-compatible regular expressions.\r
+.SH SYNOPSIS\r
+.B #include <pcre.h>\r
+.PP\r
+.SM\r
+.br\r
+.B pcre *pcre_compile(const char *\fIpattern\fR, int \fIoptions\fR,\r
+.ti +5n\r
+.B const char **\fIerrptr\fR, int *\fIerroffset\fR,\r
+.ti +5n\r
+.B const unsigned char *\fItableptr\fR);\r
+.PP\r
+.br\r
+.B pcre_extra *pcre_study(const pcre *\fIcode\fR, int \fIoptions\fR,\r
+.ti +5n\r
+.B const char **\fIerrptr\fR);\r
+.PP\r
+.br\r
+.B int pcre_exec(const pcre *\fIcode\fR, "const pcre_extra *\fIextra\fR,"\r
+.ti +5n\r
+.B "const char *\fIsubject\fR," int \fIlength\fR, int \fIstartoffset\fR,\r
+.ti +5n\r
+.B int \fIoptions\fR, int *\fIovector\fR, int \fIovecsize\fR);\r
+.PP\r
+.br\r
+.B int pcre_copy_substring(const char *\fIsubject\fR, int *\fIovector\fR,\r
+.ti +5n\r
+.B int \fIstringcount\fR, int \fIstringnumber\fR, char *\fIbuffer\fR,\r
+.ti +5n\r
+.B int \fIbuffersize\fR);\r
+.PP\r
+.br\r
+.B int pcre_get_substring(const char *\fIsubject\fR, int *\fIovector\fR,\r
+.ti +5n\r
+.B int \fIstringcount\fR, int \fIstringnumber\fR,\r
+.ti +5n\r
+.B const char **\fIstringptr\fR);\r
+.PP\r
+.br\r
+.B int pcre_get_substring_list(const char *\fIsubject\fR,\r
+.ti +5n\r
+.B int *\fIovector\fR, int \fIstringcount\fR, "const char ***\fIlistptr\fR);"\r
+.PP\r
+.br\r
+.B void pcre_free_substring(const char *\fIstringptr\fR);\r
+.PP\r
+.br\r
+.B void pcre_free_substring_list(const char **\fIstringptr\fR);\r
+.PP\r
+.br\r
+.B const unsigned char *pcre_maketables(void);\r
+.PP\r
+.br\r
+.B int pcre_fullinfo(const pcre *\fIcode\fR, "const pcre_extra *\fIextra\fR,"\r
+.ti +5n\r
+.B int \fIwhat\fR, void *\fIwhere\fR);\r
+.PP\r
+.br\r
+.B int pcre_info(const pcre *\fIcode\fR, int *\fIoptptr\fR, int\r
+.B *\fIfirstcharptr\fR);\r
+.PP\r
+.br\r
+.B char *pcre_version(void);\r
+.PP\r
+.br\r
+.B void *(*pcre_malloc)(size_t);\r
+.PP\r
+.br\r
+.B void (*pcre_free)(void *);\r
+\r
+\r
+\r
+.SH DESCRIPTION\r
+The PCRE library is a set of functions that implement regular expression\r
+pattern matching using the same syntax and semantics as Perl 5, with just a few\r
+differences (see below). The current implementation corresponds to Perl 5.005,\r
+with some additional features from later versions. This includes some\r
+experimental, incomplete support for UTF-8 encoded strings. Details of exactly\r
+what is and what is not supported are given below.\r
+\r
+PCRE has its own native API, which is described in this document. There is also\r
+a set of wrapper functions that correspond to the POSIX regular expression API.\r
+These are described in the \fBpcreposix\fR documentation.\r
+\r
+The native API function prototypes are defined in the header file \fBpcre.h\fR,\r
+and on Unix systems the library itself is called \fBlibpcre.a\fR, so can be\r
+accessed by adding \fB-lpcre\fR to the command for linking an application which\r
+calls it. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to\r
+contain the major and minor release numbers for the library. Applications can\r
+use these to include support for different releases.\r
+\r
+The functions \fBpcre_compile()\fR, \fBpcre_study()\fR, and \fBpcre_exec()\fR\r
+are used for compiling and matching regular expressions.\r
+\r
+The functions \fBpcre_copy_substring()\fR, \fBpcre_get_substring()\fR, and\r
+\fBpcre_get_substring_list()\fR are convenience functions for extracting\r
+captured substrings from a matched subject string; \fBpcre_free_substring()\fR\r
+and \fBpcre_free_substring_list()\fR are also provided, to free the memory used\r
+for extracted strings.\r
+\r
+The function \fBpcre_maketables()\fR is used (optionally) to build a set of\r
+character tables in the current locale for passing to \fBpcre_compile()\fR.\r
+\r
+The function \fBpcre_fullinfo()\fR is used to find out information about a\r
+compiled pattern; \fBpcre_info()\fR is an obsolete version which returns only\r
+some of the available information, but is retained for backwards compatibility.\r
+The function \fBpcre_version()\fR returns a pointer to a string containing the\r
+version of PCRE and its date of release.\r
+\r
+The global variables \fBpcre_malloc\fR and \fBpcre_free\fR initially contain\r
+the entry points of the standard \fBmalloc()\fR and \fBfree()\fR functions\r
+respectively. PCRE calls the memory management functions via these variables,\r
+so a calling program can replace them if it wishes to intercept the calls. This\r
+should be done before calling any PCRE functions.\r
+\r
+\r
+.SH MULTI-THREADING\r
+The PCRE functions can be used in multi-threading applications, with the\r
+proviso that the memory management functions pointed to by \fBpcre_malloc\fR\r
+and \fBpcre_free\fR are shared by all threads.\r
+\r
+The compiled form of a regular expression is not altered during matching, so\r
+the same compiled pattern can safely be used by several threads at once.\r
+\r
+\r
+.SH COMPILING A PATTERN\r
+The function \fBpcre_compile()\fR is called to compile a pattern into an\r
+internal form. The pattern is a C string terminated by a binary zero, and\r
+is passed in the argument \fIpattern\fR. A pointer to a single block of memory\r
+that is obtained via \fBpcre_malloc\fR is returned. This contains the\r
+compiled code and related data. The \fBpcre\fR type is defined for this for\r
+convenience, but in fact \fBpcre\fR is just a typedef for \fBvoid\fR, since the\r
+contents of the block are not externally defined. It is up to the caller to\r
+free the memory when it is no longer required.\r
+.PP\r
+The size of a compiled pattern is roughly proportional to the length of the\r
+pattern string, except that each character class (other than those containing\r
+just a single character, negated or not) requires 33 bytes, and repeat\r
+quantifiers with a minimum greater than one or a bounded maximum cause the\r
+relevant portions of the compiled pattern to be replicated.\r
+.PP\r
+The \fIoptions\fR argument contains independent bits that affect the\r
+compilation. It should be zero if no options are required. Some of the options,\r
+in particular, those that are compatible with Perl, can also be set and unset\r
+from within the pattern (see the detailed description of regular expressions\r
+below). For these options, the contents of the \fIoptions\fR argument specifies\r
+their initial settings at the start of compilation and execution. The\r
+PCRE_ANCHORED option can be set at the time of matching as well as at compile\r
+time.\r
+.PP\r
+If \fIerrptr\fR is NULL, \fBpcre_compile()\fR returns NULL immediately.\r
+Otherwise, if compilation of a pattern fails, \fBpcre_compile()\fR returns\r
+NULL, and sets the variable pointed to by \fIerrptr\fR to point to a textual\r
+error message. The offset from the start of the pattern to the character where\r
+the error was discovered is placed in the variable pointed to by\r
+\fIerroffset\fR, which must not be NULL. If it is, an immediate error is given.\r
+.PP\r
+If the final argument, \fItableptr\fR, is NULL, PCRE uses a default set of\r
+character tables which are built when it is compiled, using the default C\r
+locale. Otherwise, \fItableptr\fR must be the result of a call to\r
+\fBpcre_maketables()\fR. See the section on locale support below.\r
+.PP\r
+The following option bits are defined in the header file:\r
+\r
+  PCRE_ANCHORED\r
+\r
+If this bit is set, the pattern is forced to be "anchored", that is, it is\r
+constrained to match only at the start of the string which is being searched\r
+(the "subject string"). This effect can also be achieved by appropriate\r
+constructs in the pattern itself, which is the only way to do it in Perl.\r
+\r
+  PCRE_CASELESS\r
+\r
+If this bit is set, letters in the pattern match both upper and lower case\r
+letters. It is equivalent to Perl's /i option.\r
+\r
+  PCRE_DOLLAR_ENDONLY\r
+\r
+If this bit is set, a dollar metacharacter in the pattern matches only at the\r
+end of the subject string. Without this option, a dollar also matches\r
+immediately before the final character if it is a newline (but not before any\r
+other newlines). The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is\r
+set. There is no equivalent to this option in Perl.\r
+\r
+  PCRE_DOTALL\r
+\r
+If this bit is set, a dot metacharater in the pattern matches all characters,\r
+including newlines. Without it, newlines are excluded. This option is\r
+equivalent to Perl's /s option. A negative class such as [^a] always matches a\r
+newline character, independent of the setting of this option.\r
+\r
+  PCRE_EXTENDED\r
+\r
+If this bit is set, whitespace data characters in the pattern are totally\r
+ignored except when escaped or inside a character class, and characters between\r
+an unescaped # outside a character class and the next newline character,\r
+inclusive, are also ignored. This is equivalent to Perl's /x option, and makes\r
+it possible to include comments inside complicated patterns. Note, however,\r
+that this applies only to data characters. Whitespace characters may never\r
+appear within special character sequences in a pattern, for example within the\r
+sequence (?( which introduces a conditional subpattern.\r
+\r
+  PCRE_EXTRA\r
+\r
+This option was invented in order to turn on additional functionality of PCRE\r
+that is incompatible with Perl, but it is currently of very little use. When\r
+set, any backslash in a pattern that is followed by a letter that has no\r
+special meaning causes an error, thus reserving these combinations for future\r
+expansion. By default, as in Perl, a backslash followed by a letter with no\r
+special meaning is treated as a literal. There are at present no other features\r
+controlled by this option. It can also be set by a (?X) option setting within a\r
+pattern.\r
+\r
+  PCRE_MULTILINE\r
+\r
+By default, PCRE treats the subject string as consisting of a single "line" of\r
+characters (even if it actually contains several newlines). The "start of line"\r
+metacharacter (^) matches only at the start of the string, while the "end of\r
+line" metacharacter ($) matches only at the end of the string, or before a\r
+terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as\r
+Perl.\r
+\r
+When PCRE_MULTILINE it is set, the "start of line" and "end of line" constructs\r
+match immediately following or immediately before any newline in the subject\r
+string, respectively, as well as at the very start and end. This is equivalent\r
+to Perl's /m option. If there are no "\\n" characters in a subject string, or\r
+no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no\r
+effect.\r
+\r
+  PCRE_UNGREEDY\r
+\r
+This option inverts the "greediness" of the quantifiers so that they are not\r
+greedy by default, but become greedy if followed by "?". It is not compatible\r
+with Perl. It can also be set by a (?U) option setting within the pattern.\r
+\r
+  PCRE_UTF8\r
+\r
+This option causes PCRE to regard both the pattern and the subject as strings\r
+of UTF-8 characters instead of just byte strings. However, it is available only\r
+if PCRE has been built to include UTF-8 support. If not, the use of this option\r
+provokes an error. Support for UTF-8 is new, experimental, and incomplete.\r
+Details of exactly what it entails are given below.\r
+\r
+\r
+.SH STUDYING A PATTERN\r
+When a pattern is going to be used several times, it is worth spending more\r
+time analyzing it in order to speed up the time taken for matching. The\r
+function \fBpcre_study()\fR takes a pointer to a compiled pattern as its first\r
+argument, and returns a pointer to a \fBpcre_extra\fR block (another \fBvoid\fR\r
+typedef) containing additional information about the pattern; this can be\r
+passed to \fBpcre_exec()\fR. If no additional information is available, NULL\r
+is returned.\r
+\r
+The second argument contains option bits. At present, no options are defined\r
+for \fBpcre_study()\fR, and this argument should always be zero.\r
+\r
+The third argument for \fBpcre_study()\fR is a pointer to an error message. If\r
+studying succeeds (even if no data is returned), the variable it points to is\r
+set to NULL. Otherwise it points to a textual error message.\r
+\r
+At present, studying a pattern is useful only for non-anchored patterns that do\r
+not have a single fixed starting character. A bitmap of possible starting\r
+characters is created.\r
+\r
+\r
+.SH LOCALE SUPPORT\r
+PCRE handles caseless matching, and determines whether characters are letters,\r
+digits, or whatever, by reference to a set of tables. The library contains a\r
+default set of tables which is created in the default C locale when PCRE is\r
+compiled. This is used when the final argument of \fBpcre_compile()\fR is NULL,\r
+and is sufficient for many applications.\r
+\r
+An alternative set of tables can, however, be supplied. Such tables are built\r
+by calling the \fBpcre_maketables()\fR function, which has no arguments, in the\r
+relevant locale. The result can then be passed to \fBpcre_compile()\fR as often\r
+as necessary. For example, to build and use tables that are appropriate for the\r
+French locale (where accented characters with codes greater than 128 are\r
+treated as letters), the following code could be used:\r
+\r
+  setlocale(LC_CTYPE, "fr");\r
+  tables = pcre_maketables();\r
+  re = pcre_compile(..., tables);\r
+\r
+The tables are built in memory that is obtained via \fBpcre_malloc\fR. The\r
+pointer that is passed to \fBpcre_compile\fR is saved with the compiled\r
+pattern, and the same tables are used via this pointer by \fBpcre_study()\fR\r
+and \fBpcre_exec()\fR. Thus for any single pattern, compilation, studying and\r
+matching all happen in the same locale, but different patterns can be compiled\r
+in different locales. It is the caller's responsibility to ensure that the\r
+memory containing the tables remains available for as long as it is needed.\r
+\r
+\r
+.SH INFORMATION ABOUT A PATTERN\r
+The \fBpcre_fullinfo()\fR function returns information about a compiled\r
+pattern. It replaces the obsolete \fBpcre_info()\fR function, which is\r
+nevertheless retained for backwards compability (and is documented below).\r
+\r
+The first argument for \fBpcre_fullinfo()\fR is a pointer to the compiled\r
+pattern. The second argument is the result of \fBpcre_study()\fR, or NULL if\r
+the pattern was not studied. The third argument specifies which piece of\r
+information is required, while the fourth argument is a pointer to a variable\r
+to receive the data. The yield of the function is zero for success, or one of\r
+the following negative numbers:\r
+\r
+  PCRE_ERROR_NULL       the argument \fIcode\fR was NULL\r
+                        the argument \fIwhere\fR was NULL\r
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found\r
+  PCRE_ERROR_BADOPTION  the value of \fIwhat\fR was invalid\r
+\r
+The possible values for the third argument are defined in \fBpcre.h\fR, and are\r
+as follows:\r
+\r
+  PCRE_INFO_OPTIONS\r
+\r
+Return a copy of the options with which the pattern was compiled. The fourth\r
+argument should point to au \fBunsigned long int\fR variable. These option bits\r
+are those specified in the call to \fBpcre_compile()\fR, modified by any\r
+top-level option settings within the pattern itself, and with the PCRE_ANCHORED\r
+bit forcibly set if the form of the pattern implies that it can match only at\r
+the start of a subject string.\r
+\r
+  PCRE_INFO_SIZE\r
+\r
+Return the size of the compiled pattern, that is, the value that was passed as\r
+the argument to \fBpcre_malloc()\fR when PCRE was getting memory in which to\r
+place the compiled data. The fourth argument should point to a \fBsize_t\fR\r
+variable.\r
+\r
+  PCRE_INFO_CAPTURECOUNT\r
+\r
+Return the number of capturing subpatterns in the pattern. The fourth argument\r
+should point to an \fbint\fR variable.\r
+\r
+  PCRE_INFO_BACKREFMAX\r
+\r
+Return the number of the highest back reference in the pattern. The fourth\r
+argument should point to an \fBint\fR variable. Zero is returned if there are\r
+no back references.\r
+\r
+  PCRE_INFO_FIRSTCHAR\r
+\r
+Return information about the first character of any matched string, for a\r
+non-anchored pattern. If there is a fixed first character, e.g. from a pattern\r
+such as (cat|cow|coyote), it is returned in the integer pointed to by\r
+\fIwhere\fR. Otherwise, if either\r
+\r
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch\r
+starts with "^", or\r
+\r
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set\r
+(if it were set, the pattern would be anchored),\r
+\r
+-1 is returned, indicating that the pattern matches only at the start of a\r
+subject string or after any "\\n" within the string. Otherwise -2 is returned.\r
+For anchored patterns, -2 is returned.\r
+\r
+  PCRE_INFO_FIRSTTABLE\r
+\r
+If the pattern was studied, and this resulted in the construction of a 256-bit\r
+table indicating a fixed set of characters for the first character in any\r
+matching string, a pointer to the table is returned. Otherwise NULL is\r
+returned. The fourth argument should point to an \fBunsigned char *\fR\r
+variable.\r
+\r
+  PCRE_INFO_LASTLITERAL\r
+\r
+For a non-anchored pattern, return the value of the rightmost literal character\r
+which must exist in any matched string, other than at its start. The fourth\r
+argument should point to an \fBint\fR variable. If there is no such character,\r
+or if the pattern is anchored, -1 is returned. For example, for the pattern\r
+/a\\d+z\\d+/ the returned value is 'z'.\r
+\r
+The \fBpcre_info()\fR function is now obsolete because its interface is too\r
+restrictive to return all the available data about a compiled pattern. New\r
+programs should use \fBpcre_fullinfo()\fR instead. The yield of\r
+\fBpcre_info()\fR is the number of capturing subpatterns, or one of the\r
+following negative numbers:\r
+\r
+  PCRE_ERROR_NULL       the argument \fIcode\fR was NULL\r
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found\r
+\r
+If the \fIoptptr\fR argument is not NULL, a copy of the options with which the\r
+pattern was compiled is placed in the integer it points to (see\r
+PCRE_INFO_OPTIONS above).\r
+\r
+If the pattern is not anchored and the \fIfirstcharptr\fR argument is not NULL,\r
+it is used to pass back information about the first character of any matched\r
+string (see PCRE_INFO_FIRSTCHAR above).\r
+\r
+\r
+.SH MATCHING A PATTERN\r
+The function \fBpcre_exec()\fR is called to match a subject string against a\r
+pre-compiled pattern, which is passed in the \fIcode\fR argument. If the\r
+pattern has been studied, the result of the study should be passed in the\r
+\fIextra\fR argument. Otherwise this must be NULL.\r
+\r
+The PCRE_ANCHORED option can be passed in the \fIoptions\fR argument, whose\r
+unused bits must be zero. However, if a pattern was compiled with\r
+PCRE_ANCHORED, or turned out to be anchored by virtue of its contents, it\r
+cannot be made unachored at matching time.\r
+\r
+There are also three further options that can be set only at matching time:\r
+\r
+  PCRE_NOTBOL\r
+\r
+The first character of the string is not the beginning of a line, so the\r
+circumflex metacharacter should not match before it. Setting this without\r
+PCRE_MULTILINE (at compile time) causes circumflex never to match.\r
+\r
+  PCRE_NOTEOL\r
+\r
+The end of the string is not the end of a line, so the dollar metacharacter\r
+should not match it nor (except in multiline mode) a newline immediately before\r
+it. Setting this without PCRE_MULTILINE (at compile time) causes dollar never\r
+to match.\r
+\r
+  PCRE_NOTEMPTY\r
+\r
+An empty string is not considered to be a valid match if this option is set. If\r
+there are alternatives in the pattern, they are tried. If all the alternatives\r
+match the empty string, the entire match fails. For example, if the pattern\r
+\r
+  a?b?\r
+\r
+is applied to a string not beginning with "a" or "b", it matches the empty\r
+string at the start of the subject. With PCRE_NOTEMPTY set, this match is not\r
+valid, so PCRE searches further into the string for occurrences of "a" or "b".\r
+\r
+Perl has no direct equivalent of PCRE_NOTEMPTY, but it does make a special case\r
+of a pattern match of the empty string within its \fBsplit()\fR function, and\r
+when using the /g modifier. It is possible to emulate Perl's behaviour after\r
+matching a null string by first trying the match again at the same offset with\r
+PCRE_NOTEMPTY set, and then if that fails by advancing the starting offset (see\r
+below) and trying an ordinary match again.\r
+\r
+The subject string is passed as a pointer in \fIsubject\fR, a length in\r
+\fIlength\fR, and a starting offset in \fIstartoffset\fR. Unlike the pattern\r
+string, it may contain binary zero characters. When the starting offset is\r
+zero, the search for a match starts at the beginning of the subject, and this\r
+is by far the most common case.\r
+\r
+A non-zero starting offset is useful when searching for another match in the\r
+same subject by calling \fBpcre_exec()\fR again after a previous success.\r
+Setting \fIstartoffset\fR differs from just passing over a shortened string and\r
+setting PCRE_NOTBOL in the case of a pattern that begins with any kind of\r
+lookbehind. For example, consider the pattern\r
+\r
+  \\Biss\\B\r
+\r
+which finds occurrences of "iss" in the middle of words. (\\B matches only if\r
+the current position in the subject is not a word boundary.) When applied to\r
+the string "Mississipi" the first call to \fBpcre_exec()\fR finds the first\r
+occurrence. If \fBpcre_exec()\fR is called again with just the remainder of the\r
+subject, namely "issipi", it does not match, because \\B is always false at the\r
+start of the subject, which is deemed to be a word boundary. However, if\r
+\fBpcre_exec()\fR is passed the entire string again, but with \fIstartoffset\fR\r
+set to 4, it finds the second occurrence of "iss" because it is able to look\r
+behind the starting point to discover that it is preceded by a letter.\r
+\r
+If a non-zero starting offset is passed when the pattern is anchored, one\r
+attempt to match at the given offset is tried. This can only succeed if the\r
+pattern does not require the match to be at the start of the subject.\r
+\r
+In general, a pattern matches a certain portion of the subject, and in\r
+addition, further substrings from the subject may be picked out by parts of the\r
+pattern. Following the usage in Jeffrey Friedl's book, this is called\r
+"capturing" in what follows, and the phrase "capturing subpattern" is used for\r
+a fragment of a pattern that picks out a substring. PCRE supports several other\r
+kinds of parenthesized subpattern that do not cause substrings to be captured.\r
+\r
+Captured substrings are returned to the caller via a vector of integer offsets\r
+whose address is passed in \fIovector\fR. The number of elements in the vector\r
+is passed in \fIovecsize\fR. The first two-thirds of the vector is used to pass\r
+back captured substrings, each substring using a pair of integers. The\r
+remaining third of the vector is used as workspace by \fBpcre_exec()\fR while\r
+matching capturing subpatterns, and is not available for passing back\r
+information. The length passed in \fIovecsize\fR should always be a multiple of\r
+three. If it is not, it is rounded down.\r
+\r
+When a match has been successful, information about captured substrings is\r
+returned in pairs of integers, starting at the beginning of \fIovector\fR, and\r
+continuing up to two-thirds of its length at the most. The first element of a\r
+pair is set to the offset of the first character in a substring, and the second\r
+is set to the offset of the first character after the end of a substring. The\r
+first pair, \fIovector[0]\fR and \fIovector[1]\fR, identify the portion of the\r
+subject string matched by the entire pattern. The next pair is used for the\r
+first capturing subpattern, and so on. The value returned by \fBpcre_exec()\fR\r
+is the number of pairs that have been set. If there are no capturing\r
+subpatterns, the return value from a successful match is 1, indicating that\r
+just the first pair of offsets has been set.\r
+\r
+Some convenience functions are provided for extracting the captured substrings\r
+as separate strings. These are described in the following section.\r
+\r
+It is possible for an capturing subpattern number \fIn+1\fR to match some\r
+part of the subject when subpattern \fIn\fR has not been used at all. For\r
+example, if the string "abc" is matched against the pattern (a|(z))(bc)\r
+subpatterns 1 and 3 are matched, but 2 is not. When this happens, both offset\r
+values corresponding to the unused subpattern are set to -1.\r
+\r
+If a capturing subpattern is matched repeatedly, it is the last portion of the\r
+string that it matched that gets returned.\r
+\r
+If the vector is too small to hold all the captured substrings, it is used as\r
+far as possible (up to two-thirds of its length), and the function returns a\r
+value of zero. In particular, if the substring offsets are not of interest,\r
+\fBpcre_exec()\fR may be called with \fIovector\fR passed as NULL and\r
+\fIovecsize\fR as zero. However, if the pattern contains back references and\r
+the \fIovector\fR isn't big enough to remember the related substrings, PCRE has\r
+to get additional memory for use during matching. Thus it is usually advisable\r
+to supply an \fIovector\fR.\r
+\r
+Note that \fBpcre_info()\fR can be used to find out how many capturing\r
+subpatterns there are in a compiled pattern. The smallest size for\r
+\fIovector\fR that will allow for \fIn\fR captured substrings in addition to\r
+the offsets of the substring matched by the whole pattern is (\fIn\fR+1)*3.\r
+\r
+If \fBpcre_exec()\fR fails, it returns a negative number. The following are\r
+defined in the header file:\r
+\r
+  PCRE_ERROR_NOMATCH        (-1)\r
+\r
+The subject string did not match the pattern.\r
+\r
+  PCRE_ERROR_NULL           (-2)\r
+\r
+Either \fIcode\fR or \fIsubject\fR was passed as NULL, or \fIovector\fR was\r
+NULL and \fIovecsize\fR was not zero.\r
+\r
+  PCRE_ERROR_BADOPTION      (-3)\r
+\r
+An unrecognized bit was set in the \fIoptions\fR argument.\r
+\r
+  PCRE_ERROR_BADMAGIC       (-4)\r
+\r
+PCRE stores a 4-byte "magic number" at the start of the compiled code, to catch\r
+the case when it is passed a junk pointer. This is the error it gives when the\r
+magic number isn't present.\r
+\r
+  PCRE_ERROR_UNKNOWN_NODE   (-5)\r
+\r
+While running the pattern match, an unknown item was encountered in the\r
+compiled pattern. This error could be caused by a bug in PCRE or by overwriting\r
+of the compiled pattern.\r
+\r
+  PCRE_ERROR_NOMEMORY       (-6)\r
+\r
+If a pattern contains back references, but the \fIovector\fR that is passed to\r
+\fBpcre_exec()\fR is not big enough to remember the referenced substrings, PCRE\r
+gets a block of memory at the start of matching to use for this purpose. If the\r
+call via \fBpcre_malloc()\fR fails, this error is given. The memory is freed at\r
+the end of matching.\r
+\r
+\r
+.SH EXTRACTING CAPTURED SUBSTRINGS\r
+Captured substrings can be accessed directly by using the offsets returned by\r
+\fBpcre_exec()\fR in \fIovector\fR. For convenience, the functions\r
+\fBpcre_copy_substring()\fR, \fBpcre_get_substring()\fR, and\r
+\fBpcre_get_substring_list()\fR are provided for extracting captured substrings\r
+as new, separate, zero-terminated strings. A substring that contains a binary\r
+zero is correctly extracted and has a further zero added on the end, but the\r
+result does not, of course, function as a C string.\r
+\r
+The first three arguments are the same for all three functions: \fIsubject\fR\r
+is the subject string which has just been successfully matched, \fIovector\fR\r
+is a pointer to the vector of integer offsets that was passed to\r
+\fBpcre_exec()\fR, and \fIstringcount\fR is the number of substrings that\r
+were captured by the match, including the substring that matched the entire\r
+regular expression. This is the value returned by \fBpcre_exec\fR if it\r
+is greater than zero. If \fBpcre_exec()\fR returned zero, indicating that it\r
+ran out of space in \fIovector\fR, the value passed as \fIstringcount\fR should\r
+be the size of the vector divided by three.\r
+\r
+The functions \fBpcre_copy_substring()\fR and \fBpcre_get_substring()\fR\r
+extract a single substring, whose number is given as \fIstringnumber\fR. A\r
+value of zero extracts the substring that matched the entire pattern, while\r
+higher values extract the captured substrings. For \fBpcre_copy_substring()\fR,\r
+the string is placed in \fIbuffer\fR, whose length is given by\r
+\fIbuffersize\fR, while for \fBpcre_get_substring()\fR a new block of memory is\r
+obtained via \fBpcre_malloc\fR, and its address is returned via\r
+\fIstringptr\fR. The yield of the function is the length of the string, not\r
+including the terminating zero, or one of\r
+\r
+  PCRE_ERROR_NOMEMORY       (-6)\r
+\r
+The buffer was too small for \fBpcre_copy_substring()\fR, or the attempt to get\r
+memory failed for \fBpcre_get_substring()\fR.\r
+\r
+  PCRE_ERROR_NOSUBSTRING    (-7)\r
+\r
+There is no substring whose number is \fIstringnumber\fR.\r
+\r
+The \fBpcre_get_substring_list()\fR function extracts all available substrings\r
+and builds a list of pointers to them. All this is done in a single block of\r
+memory which is obtained via \fBpcre_malloc\fR. The address of the memory block\r
+is returned via \fIlistptr\fR, which is also the start of the list of string\r
+pointers. The end of the list is marked by a NULL pointer. The yield of the\r
+function is zero if all went well, or\r
+\r
+  PCRE_ERROR_NOMEMORY       (-6)\r
+\r
+if the attempt to get the memory block failed.\r
+\r
+When any of these functions encounter a substring that is unset, which can\r
+happen when capturing subpattern number \fIn+1\fR matches some part of the\r
+subject, but subpattern \fIn\fR has not been used at all, they return an empty\r
+string. This can be distinguished from a genuine zero-length substring by\r
+inspecting the appropriate offset in \fIovector\fR, which is negative for unset\r
+substrings.\r
+\r
+The two convenience functions \fBpcre_free_substring()\fR and\r
+\fBpcre_free_substring_list()\fR can be used to free the memory returned by\r
+a previous call of \fBpcre_get_substring()\fR or\r
+\fBpcre_get_substring_list()\fR, respectively. They do nothing more than call\r
+the function pointed to by \fBpcre_free\fR, which of course could be called\r
+directly from a C program. However, PCRE is used in some situations where it is\r
+linked via a special interface to another programming language which cannot use\r
+\fBpcre_free\fR directly; it is for these cases that the functions are\r
+provided.\r
+\r
+\r
+.SH LIMITATIONS\r
+There are some size limitations in PCRE but it is hoped that they will never in\r
+practice be relevant.\r
+The maximum length of a compiled pattern is 65539 (sic) bytes.\r
+All values in repeating quantifiers must be less than 65536.\r
+The maximum number of capturing subpatterns is 99.\r
+The maximum number of all parenthesized subpatterns, including capturing\r
+subpatterns, assertions, and other types of subpattern, is 200.\r
+\r
+The maximum length of a subject string is the largest positive number that an\r
+integer variable can hold. However, PCRE uses recursion to handle subpatterns\r
+and indefinite repetition. This means that the available stack space may limit\r
+the size of a subject string that can be processed by certain patterns.\r
+\r
+\r
+.SH DIFFERENCES FROM PERL\r
+The differences described here are with respect to Perl 5.005.\r
+\r
+1. By default, a whitespace character is any character that the C library\r
+function \fBisspace()\fR recognizes, though it is possible to compile PCRE with\r
+alternative character type tables. Normally \fBisspace()\fR matches space,\r
+formfeed, newline, carriage return, horizontal tab, and vertical tab. Perl 5\r
+no longer includes vertical tab in its set of whitespace characters. The \\v\r
+escape that was in the Perl documentation for a long time was never in fact\r
+recognized. However, the character itself was treated as whitespace at least\r
+up to 5.002. In 5.004 and 5.005 it does not match \\s.\r
+\r
+2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl permits\r
+them, but they do not mean what you might think. For example, (?!a){3} does\r
+not assert that the next three characters are not "a". It just asserts that the\r
+next character is not "a" three times.\r
+\r
+3. Capturing subpatterns that occur inside negative lookahead assertions are\r
+counted, but their entries in the offsets vector are never set. Perl sets its\r
+numerical variables from any such patterns that are matched before the\r
+assertion fails to match something (thereby succeeding), but only if the\r
+negative lookahead assertion contains just one branch.\r
+\r
+4. Though binary zero characters are supported in the subject string, they are\r
+not allowed in a pattern string because it is passed as a normal C string,\r
+terminated by zero. The escape sequence "\\0" can be used in the pattern to\r
+represent a binary zero.\r
+\r
+5. The following Perl escape sequences are not supported: \\l, \\u, \\L, \\U,\r
+\\E, \\Q. In fact these are implemented by Perl's general string-handling and\r
+are not part of its pattern matching engine.\r
+\r
+6. The Perl \\G assertion is not supported as it is not relevant to single\r
+pattern matches.\r
+\r
+7. Fairly obviously, PCRE does not support the (?{code}) and (?p{code})\r
+constructions. However, there is some experimental support for recursive\r
+patterns using the non-Perl item (?R).\r
+\r
+8. There are at the time of writing some oddities in Perl 5.005_02 concerned\r
+with the settings of captured strings when part of a pattern is repeated. For\r
+example, matching "aba" against the pattern /^(a(b)?)+$/ sets $2 to the value\r
+"b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves $2 unset. However, if\r
+the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) are set.\r
+\r
+In Perl 5.004 $2 is set in both cases, and that is also true of PCRE. If in the\r
+future Perl changes to a consistent state that is different, PCRE may change to\r
+follow.\r
+\r
+9. Another as yet unresolved discrepancy is that in Perl 5.005_02 the pattern\r
+/^(a)?(?(1)a|b)+$/ matches the string "a", whereas in PCRE it does not.\r
+However, in both Perl and PCRE /^(a)?a/ matched against "a" leaves $1 unset.\r
+\r
+10. PCRE provides some extensions to the Perl regular expression facilities:\r
+\r
+(a) Although lookbehind assertions must match fixed length strings, each\r
+alternative branch of a lookbehind assertion can match a different length of\r
+string. Perl 5.005 requires them all to have the same length.\r
+\r
+(b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ meta-\r
+character matches only at the very end of the string.\r
+\r
+(c) If PCRE_EXTRA is set, a backslash followed by a letter with no special\r
+meaning is faulted.\r
+\r
+(d) If PCRE_UNGREEDY is set, the greediness of the repetition quantifiers is\r
+inverted, that is, by default they are not greedy, but if followed by a\r
+question mark they are.\r
+\r
+(e) PCRE_ANCHORED can be used to force a pattern to be tried only at the start\r
+of the subject.\r
+\r
+(f) The PCRE_NOTBOL, PCRE_NOTEOL, and PCRE_NOTEMPTY options for\r
+\fBpcre_exec()\fR have no Perl equivalents.\r
+\r
+(g) The (?R) construct allows for recursive pattern matching (Perl 5.6 can do\r
+this using the (?p{code}) construct, which PCRE cannot of course support.)\r
+\r
+\r
+.SH REGULAR EXPRESSION DETAILS\r
+The syntax and semantics of the regular expressions supported by PCRE are\r
+described below. Regular expressions are also described in the Perl\r
+documentation and in a number of other books, some of which have copious\r
+examples. Jeffrey Friedl's "Mastering Regular Expressions", published by\r
+O'Reilly (ISBN 1-56592-257), covers them in great detail.\r
+\r
+The description here is intended as reference documentation. The basic\r
+operation of PCRE is on strings of bytes. However, there is the beginnings of\r
+some support for UTF-8 character strings. To use this support you must\r
+configure PCRE to include it, and then call \fBpcre_compile()\fR with the\r
+PCRE_UTF8 option. How this affects the pattern matching is described in the\r
+final section of this document.\r
+\r
+A regular expression is a pattern that is matched against a subject string from\r
+left to right. Most characters stand for themselves in a pattern, and match the\r
+corresponding characters in the subject. As a trivial example, the pattern\r
+\r
+  The quick brown fox\r
+\r
+matches a portion of a subject string that is identical to itself. The power of\r
+regular expressions comes from the ability to include alternatives and\r
+repetitions in the pattern. These are encoded in the pattern by the use of\r
+\fImeta-characters\fR, which do not stand for themselves but instead are\r
+interpreted in some special way.\r
+\r
+There are two different sets of meta-characters: those that are recognized\r
+anywhere in the pattern except within square brackets, and those that are\r
+recognized in square brackets. Outside square brackets, the meta-characters are\r
+as follows:\r
+\r
+  \\      general escape character with several uses\r
+  ^      assert start of subject (or line, in multiline mode)\r
+  $      assert end of subject (or line, in multiline mode)\r
+  .      match any character except newline (by default)\r
+  [      start character class definition\r
+  |      start of alternative branch\r
+  (      start subpattern\r
+  )      end subpattern\r
+  ?      extends the meaning of (\r
+         also 0 or 1 quantifier\r
+         also quantifier minimizer\r
+  *      0 or more quantifier\r
+  +      1 or more quantifier\r
+  {      start min/max quantifier\r
+\r
+Part of a pattern that is in square brackets is called a "character class". In\r
+a character class the only meta-characters are:\r
+\r
+  \\      general escape character\r
+  ^      negate the class, but only if the first character\r
+  -      indicates character range\r
+  ]      terminates the character class\r
+\r
+The following sections describe the use of each of the meta-characters.\r
+\r
+\r
+.SH BACKSLASH\r
+The backslash character has several uses. Firstly, if it is followed by a\r
+non-alphameric character, it takes away any special meaning that character may\r
+have. This use of backslash as an escape character applies both inside and\r
+outside character classes.\r
+\r
+For example, if you want to match a "*" character, you write "\\*" in the\r
+pattern. This applies whether or not the following character would otherwise be\r
+interpreted as a meta-character, so it is always safe to precede a\r
+non-alphameric with "\\" to specify that it stands for itself. In particular,\r
+if you want to match a backslash, you write "\\\\".\r
+\r
+If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the\r
+pattern (other than in a character class) and characters between a "#" outside\r
+a character class and the next newline character are ignored. An escaping\r
+backslash can be used to include a whitespace or "#" character as part of the\r
+pattern.\r
+\r
+A second use of backslash provides a way of encoding non-printing characters\r
+in patterns in a visible manner. There is no restriction on the appearance of\r
+non-printing characters, apart from the binary zero that terminates a pattern,\r
+but when a pattern is being prepared by text editing, it is usually easier to\r
+use one of the following escape sequences than the binary character it\r
+represents:\r
+\r
+  \\a     alarm, that is, the BEL character (hex 07)\r
+  \\cx    "control-x", where x is any character\r
+  \\e     escape (hex 1B)\r
+  \\f     formfeed (hex 0C)\r
+  \\n     newline (hex 0A)\r
+  \\r     carriage return (hex 0D)\r
+  \\t     tab (hex 09)\r
+  \\xhh   character with hex code hh\r
+  \\ddd   character with octal code ddd, or backreference\r
+\r
+The precise effect of "\\cx" is as follows: if "x" is a lower case letter, it\r
+is converted to upper case. Then bit 6 of the character (hex 40) is inverted.\r
+Thus "\\cz" becomes hex 1A, but "\\c{" becomes hex 3B, while "\\c;" becomes hex\r
+7B.\r
+\r
+After "\\x", up to two hexadecimal digits are read (letters can be in upper or\r
+lower case).\r
+\r
+After "\\0" up to two further octal digits are read. In both cases, if there\r
+are fewer than two digits, just those that are present are used. Thus the\r
+sequence "\\0\\x\\07" specifies two binary zeros followed by a BEL character.\r
+Make sure you supply two digits after the initial zero if the character that\r
+follows is itself an octal digit.\r
+\r
+The handling of a backslash followed by a digit other than 0 is complicated.\r
+Outside a character class, PCRE reads it and any following digits as a decimal\r
+number. If the number is less than 10, or if there have been at least that many\r
+previous capturing left parentheses in the expression, the entire sequence is\r
+taken as a \fIback reference\fR. A description of how this works is given\r
+later, following the discussion of parenthesized subpatterns.\r
+\r
+Inside a character class, or if the decimal number is greater than 9 and there\r
+have not been that many capturing subpatterns, PCRE re-reads up to three octal\r
+digits following the backslash, and generates a single byte from the least\r
+significant 8 bits of the value. Any subsequent digits stand for themselves.\r
+For example:\r
+\r
+  \\040   is another way of writing a space\r
+  \\40    is the same, provided there are fewer than 40\r
+            previous capturing subpatterns\r
+  \\7     is always a back reference\r
+  \\11    might be a back reference, or another way of\r
+            writing a tab\r
+  \\011   is always a tab\r
+  \\0113  is a tab followed by the character "3"\r
+  \\113   is the character with octal code 113 (since there\r
+            can be no more than 99 back references)\r
+  \\377   is a byte consisting entirely of 1 bits\r
+  \\81    is either a back reference, or a binary zero\r
+            followed by the two characters "8" and "1"\r
+\r
+Note that octal values of 100 or greater must not be introduced by a leading\r
+zero, because no more than three octal digits are ever read.\r
+\r
+All the sequences that define a single byte value can be used both inside and\r
+outside character classes. In addition, inside a character class, the sequence\r
+"\\b" is interpreted as the backspace character (hex 08). Outside a character\r
+class it has a different meaning (see below).\r
+\r
+The third use of backslash is for specifying generic character types:\r
+\r
+  \\d     any decimal digit\r
+  \\D     any character that is not a decimal digit\r
+  \\s     any whitespace character\r
+  \\S     any character that is not a whitespace character\r
+  \\w     any "word" character\r
+  \\W     any "non-word" character\r
+\r
+Each pair of escape sequences partitions the complete set of characters into\r
+two disjoint sets. Any given character matches one, and only one, of each pair.\r
+\r
+A "word" character is any letter or digit or the underscore character, that is,\r
+any character which can be part of a Perl "word". The definition of letters and\r
+digits is controlled by PCRE's character tables, and may vary if locale-\r
+specific matching is taking place (see "Locale support" above). For example, in\r
+the "fr" (French) locale, some character codes greater than 128 are used for\r
+accented letters, and these are matched by \\w.\r
+\r
+These character type sequences can appear both inside and outside character\r
+classes. They each match one character of the appropriate type. If the current\r
+matching point is at the end of the subject string, all of them fail, since\r
+there is no character to match.\r
+\r
+The fourth use of backslash is for certain simple assertions. An assertion\r
+specifies a condition that has to be met at a particular point in a match,\r
+without consuming any characters from the subject string. The use of\r
+subpatterns for more complicated assertions is described below. The backslashed\r
+assertions are\r
+\r
+  \\b     word boundary\r
+  \\B     not a word boundary\r
+  \\A     start of subject (independent of multiline mode)\r
+  \\Z     end of subject or newline at end (independent of multiline mode)\r
+  \\z     end of subject (independent of multiline mode)\r
+\r
+These assertions may not appear in character classes (but note that "\\b" has a\r
+different meaning, namely the backspace character, inside a character class).\r
+\r
+A word boundary is a position in the subject string where the current character\r
+and the previous character do not both match \\w or \\W (i.e. one matches\r
+\\w and the other matches \\W), or the start or end of the string if the\r
+first or last character matches \\w, respectively.\r
+\r
+The \\A, \\Z, and \\z assertions differ from the traditional circumflex and\r
+dollar (described below) in that they only ever match at the very start and end\r
+of the subject string, whatever options are set. They are not affected by the\r
+PCRE_NOTBOL or PCRE_NOTEOL options. If the \fIstartoffset\fR argument of\r
+\fBpcre_exec()\fR is non-zero, \\A can never match. The difference between \\Z\r
+and \\z is that \\Z matches before a newline that is the last character of the\r
+string as well as at the end of the string, whereas \\z matches only at the\r
+end.\r
+\r
+\r
+.SH CIRCUMFLEX AND DOLLAR\r
+Outside a character class, in the default matching mode, the circumflex\r
+character is an assertion which is true only if the current matching point is\r
+at the start of the subject string. If the \fIstartoffset\fR argument of\r
+\fBpcre_exec()\fR is non-zero, circumflex can never match. Inside a character\r
+class, circumflex has an entirely different meaning (see below).\r
+\r
+Circumflex need not be the first character of the pattern if a number of\r
+alternatives are involved, but it should be the first thing in each alternative\r
+in which it appears if the pattern is ever to match that branch. If all\r
+possible alternatives start with a circumflex, that is, if the pattern is\r
+constrained to match only at the start of the subject, it is said to be an\r
+"anchored" pattern. (There are also other constructs that can cause a pattern\r
+to be anchored.)\r
+\r
+A dollar character is an assertion which is true only if the current matching\r
+point is at the end of the subject string, or immediately before a newline\r
+character that is the last character in the string (by default). Dollar need\r
+not be the last character of the pattern if a number of alternatives are\r
+involved, but it should be the last item in any branch in which it appears.\r
+Dollar has no special meaning in a character class.\r
+\r
+The meaning of dollar can be changed so that it matches only at the very end of\r
+the string, by setting the PCRE_DOLLAR_ENDONLY option at compile or matching\r
+time. This does not affect the \\Z assertion.\r
+\r
+The meanings of the circumflex and dollar characters are changed if the\r
+PCRE_MULTILINE option is set. When this is the case, they match immediately\r
+after and immediately before an internal "\\n" character, respectively, in\r
+addition to matching at the start and end of the subject string. For example,\r
+the pattern /^abc$/ matches the subject string "def\\nabc" in multiline mode,\r
+but not otherwise. Consequently, patterns that are anchored in single line mode\r
+because all branches start with "^" are not anchored in multiline mode, and a\r
+match for circumflex is possible when the \fIstartoffset\fR argument of\r
+\fBpcre_exec()\fR is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if\r
+PCRE_MULTILINE is set.\r
+\r
+Note that the sequences \\A, \\Z, and \\z can be used to match the start and\r
+end of the subject in both modes, and if all branches of a pattern start with\r
+\\A is it always anchored, whether PCRE_MULTILINE is set or not.\r
+\r
+\r
+.SH FULL STOP (PERIOD, DOT)\r
+Outside a character class, a dot in the pattern matches any one character in\r
+the subject, including a non-printing character, but not (by default) newline.\r
+If the PCRE_DOTALL option is set, dots match newlines as well. The handling of\r
+dot is entirely independent of the handling of circumflex and dollar, the only\r
+relationship being that they both involve newline characters. Dot has no\r
+special meaning in a character class.\r
+\r
+\r
+.SH SQUARE BRACKETS\r
+An opening square bracket introduces a character class, terminated by a closing\r
+square bracket. A closing square bracket on its own is not special. If a\r
+closing square bracket is required as a member of the class, it should be the\r
+first data character in the class (after an initial circumflex, if present) or\r
+escaped with a backslash.\r
+\r
+A character class matches a single character in the subject; the character must\r
+be in the set of characters defined by the class, unless the first character in\r
+the class is a circumflex, in which case the subject character must not be in\r
+the set defined by the class. If a circumflex is actually required as a member\r
+of the class, ensure it is not the first character, or escape it with a\r
+backslash.\r
+\r
+For example, the character class [aeiou] matches any lower case vowel, while\r
+[^aeiou] matches any character that is not a lower case vowel. Note that a\r
+circumflex is just a convenient notation for specifying the characters which\r
+are in the class by enumerating those that are not. It is not an assertion: it\r
+still consumes a character from the subject string, and fails if the current\r
+pointer is at the end of the string.\r
+\r
+When caseless matching is set, any letters in a class represent both their\r
+upper case and lower case versions, so for example, a caseless [aeiou] matches\r
+"A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a\r
+caseful version would.\r
+\r
+The newline character is never treated in any special way in character classes,\r
+whatever the setting of the PCRE_DOTALL or PCRE_MULTILINE options is. A class\r
+such as [^a] will always match a newline.\r
+\r
+The minus (hyphen) character can be used to specify a range of characters in a\r
+character class. For example, [d-m] matches any letter between d and m,\r
+inclusive. If a minus character is required in a class, it must be escaped with\r
+a backslash or appear in a position where it cannot be interpreted as\r
+indicating a range, typically as the first or last character in the class.\r
+\r
+It is not possible to have the literal character "]" as the end character of a\r
+range. A pattern such as [W-]46] is interpreted as a class of two characters\r
+("W" and "-") followed by a literal string "46]", so it would match "W46]" or\r
+"-46]". However, if the "]" is escaped with a backslash it is interpreted as\r
+the end of range, so [W-\\]46] is interpreted as a single class containing a\r
+range followed by two separate characters. The octal or hexadecimal\r
+representation of "]" can also be used to end a range.\r
+\r
+Ranges operate in ASCII collating sequence. They can also be used for\r
+characters specified numerically, for example [\\000-\\037]. If a range that\r
+includes letters is used when caseless matching is set, it matches the letters\r
+in either case. For example, [W-c] is equivalent to [][\\^_`wxyzabc], matched\r
+caselessly, and if character tables for the "fr" locale are in use,\r
+[\\xc8-\\xcb] matches accented E characters in both cases.\r
+\r
+The character types \\d, \\D, \\s, \\S, \\w, and \\W may also appear in a\r
+character class, and add the characters that they match to the class. For\r
+example, [\\dABCDEF] matches any hexadecimal digit. A circumflex can\r
+conveniently be used with the upper case character types to specify a more\r
+restricted set of characters than the matching lower case type. For example,\r
+the class [^\\W_] matches any letter or digit, but not underscore.\r
+\r
+All non-alphameric characters other than \\, -, ^ (at the start) and the\r
+terminating ] are non-special in character classes, but it does no harm if they\r
+are escaped.\r
+\r
+\r
+.SH POSIX CHARACTER CLASSES\r
+Perl 5.6 (not yet released at the time of writing) is going to support the\r
+POSIX notation for character classes, which uses names enclosed by [: and :]\r
+within the enclosing square brackets. PCRE supports this notation. For example,\r
+\r
+  [01[:alpha:]%]\r
+\r
+matches "0", "1", any alphabetic character, or "%". The supported class names\r
+are\r
+\r
+  alnum    letters and digits\r
+  alpha    letters\r
+  ascii    character codes 0 - 127\r
+  cntrl    control characters\r
+  digit    decimal digits (same as \\d)\r
+  graph    printing characters, excluding space\r
+  lower    lower case letters\r
+  print    printing characters, including space\r
+  punct    printing characters, excluding letters and digits\r
+  space    white space (same as \\s)\r
+  upper    upper case letters\r
+  word     "word" characters (same as \\w)\r
+  xdigit   hexadecimal digits\r
+\r
+The names "ascii" and "word" are Perl extensions. Another Perl extension is\r
+negation, which is indicated by a ^ character after the colon. For example,\r
+\r
+  [12[:^digit:]]\r
+\r
+matches "1", "2", or any non-digit. PCRE (and Perl) also recogize the POSIX\r
+syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not\r
+supported, and an error is given if they are encountered.\r
+\r
+\r
+.SH VERTICAL BAR\r
+Vertical bar characters are used to separate alternative patterns. For example,\r
+the pattern\r
+\r
+  gilbert|sullivan\r
+\r
+matches either "gilbert" or "sullivan". Any number of alternatives may appear,\r
+and an empty alternative is permitted (matching the empty string).\r
+The matching process tries each alternative in turn, from left to right,\r
+and the first one that succeeds is used. If the alternatives are within a\r
+subpattern (defined below), "succeeds" means matching the rest of the main\r
+pattern as well as the alternative in the subpattern.\r
+\r
+\r
+.SH INTERNAL OPTION SETTING\r
+The settings of PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and PCRE_EXTENDED\r
+can be changed from within the pattern by a sequence of Perl option letters\r
+enclosed between "(?" and ")". The option letters are\r
+\r
+  i  for PCRE_CASELESS\r
+  m  for PCRE_MULTILINE\r
+  s  for PCRE_DOTALL\r
+  x  for PCRE_EXTENDED\r
+\r
+For example, (?im) sets caseless, multiline matching. It is also possible to\r
+unset these options by preceding the letter with a hyphen, and a combined\r
+setting and unsetting such as (?im-sx), which sets PCRE_CASELESS and\r
+PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, is also\r
+permitted. If a letter appears both before and after the hyphen, the option is\r
+unset.\r
+\r
+The scope of these option changes depends on where in the pattern the setting\r
+occurs. For settings that are outside any subpattern (defined below), the\r
+effect is the same as if the options were set or unset at the start of\r
+matching. The following patterns all behave in exactly the same way:\r
+\r
+  (?i)abc\r
+  a(?i)bc\r
+  ab(?i)c\r
+  abc(?i)\r
+\r
+which in turn is the same as compiling the pattern abc with PCRE_CASELESS set.\r
+In other words, such "top level" settings apply to the whole pattern (unless\r
+there are other changes inside subpatterns). If there is more than one setting\r
+of the same option at top level, the rightmost setting is used.\r
+\r
+If an option change occurs inside a subpattern, the effect is different. This\r
+is a change of behaviour in Perl 5.005. An option change inside a subpattern\r
+affects only that part of the subpattern that follows it, so\r
+\r
+  (a(?i)b)c\r
+\r
+matches abc and aBc and no other strings (assuming PCRE_CASELESS is not used).\r
+By this means, options can be made to have different settings in different\r
+parts of the pattern. Any changes made in one alternative do carry on\r
+into subsequent branches within the same subpattern. For example,\r
+\r
+  (a(?i)b|c)\r
+\r
+matches "ab", "aB", "c", and "C", even though when matching "C" the first\r
+branch is abandoned before the option setting. This is because the effects of\r
+option settings happen at compile time. There would be some very weird\r
+behaviour otherwise.\r
+\r
+The PCRE-specific options PCRE_UNGREEDY and PCRE_EXTRA can be changed in the\r
+same way as the Perl-compatible options by using the characters U and X\r
+respectively. The (?X) flag setting is special in that it must always occur\r
+earlier in the pattern than any of the additional features it turns on, even\r
+when it is at top level. It is best put at the start.\r
+\r
+\r
+.SH SUBPATTERNS\r
+Subpatterns are delimited by parentheses (round brackets), which can be nested.\r
+Marking part of a pattern as a subpattern does two things:\r
+\r
+1. It localizes a set of alternatives. For example, the pattern\r
+\r
+  cat(aract|erpillar|)\r
+\r
+matches one of the words "cat", "cataract", or "caterpillar". Without the\r
+parentheses, it would match "cataract", "erpillar" or the empty string.\r
+\r
+2. It sets up the subpattern as a capturing subpattern (as defined above).\r
+When the whole pattern matches, that portion of the subject string that matched\r
+the subpattern is passed back to the caller via the \fIovector\fR argument of\r
+\fBpcre_exec()\fR. Opening parentheses are counted from left to right (starting\r
+from 1) to obtain the numbers of the capturing subpatterns.\r
+\r
+For example, if the string "the red king" is matched against the pattern\r
+\r
+  the ((red|white) (king|queen))\r
+\r
+the captured substrings are "red king", "red", and "king", and are numbered 1,\r
+2, and 3.\r
+\r
+The fact that plain parentheses fulfil two functions is not always helpful.\r
+There are often times when a grouping subpattern is required without a\r
+capturing requirement. If an opening parenthesis is followed by "?:", the\r
+subpattern does not do any capturing, and is not counted when computing the\r
+number of any subsequent capturing subpatterns. For example, if the string "the\r
+white queen" is matched against the pattern\r
+\r
+  the ((?:red|white) (king|queen))\r
+\r
+the captured substrings are "white queen" and "queen", and are numbered 1 and\r
+2. The maximum number of captured substrings is 99, and the maximum number of\r
+all subpatterns, both capturing and non-capturing, is 200.\r
+\r
+As a convenient shorthand, if any option settings are required at the start of\r
+a non-capturing subpattern, the option letters may appear between the "?" and\r
+the ":". Thus the two patterns\r
+\r
+  (?i:saturday|sunday)\r
+  (?:(?i)saturday|sunday)\r
+\r
+match exactly the same set of strings. Because alternative branches are tried\r
+from left to right, and options are not reset until the end of the subpattern\r
+is reached, an option setting in one branch does affect subsequent branches, so\r
+the above patterns match "SUNDAY" as well as "Saturday".\r
+\r
+\r
+.SH REPETITION\r
+Repetition is specified by quantifiers, which can follow any of the following\r
+items:\r
+\r
+  a single character, possibly escaped\r
+  the . metacharacter\r
+  a character class\r
+  a back reference (see next section)\r
+  a parenthesized subpattern (unless it is an assertion - see below)\r
+\r
+The general repetition quantifier specifies a minimum and maximum number of\r
+permitted matches, by giving the two numbers in curly brackets (braces),\r
+separated by a comma. The numbers must be less than 65536, and the first must\r
+be less than or equal to the second. For example:\r
+\r
+  z{2,4}\r
+\r
+matches "zz", "zzz", or "zzzz". A closing brace on its own is not a special\r
+character. If the second number is omitted, but the comma is present, there is\r
+no upper limit; if the second number and the comma are both omitted, the\r
+quantifier specifies an exact number of required matches. Thus\r
+\r
+  [aeiou]{3,}\r
+\r
+matches at least 3 successive vowels, but may match many more, while\r
+\r
+  \\d{8}\r
+\r
+matches exactly 8 digits. An opening curly bracket that appears in a position\r
+where a quantifier is not allowed, or one that does not match the syntax of a\r
+quantifier, is taken as a literal character. For example, {,6} is not a\r
+quantifier, but a literal string of four characters.\r
+\r
+The quantifier {0} is permitted, causing the expression to behave as if the\r
+previous item and the quantifier were not present.\r
+\r
+For convenience (and historical compatibility) the three most common\r
+quantifiers have single-character abbreviations:\r
+\r
+  *    is equivalent to {0,}\r
+  +    is equivalent to {1,}\r
+  ?    is equivalent to {0,1}\r
+\r
+It is possible to construct infinite loops by following a subpattern that can\r
+match no characters with a quantifier that has no upper limit, for example:\r
+\r
+  (a?)*\r
+\r
+Earlier versions of Perl and PCRE used to give an error at compile time for\r
+such patterns. However, because there are cases where this can be useful, such\r
+patterns are now accepted, but if any repetition of the subpattern does in fact\r
+match no characters, the loop is forcibly broken.\r
+\r
+By default, the quantifiers are "greedy", that is, they match as much as\r
+possible (up to the maximum number of permitted times), without causing the\r
+rest of the pattern to fail. The classic example of where this gives problems\r
+is in trying to match comments in C programs. These appear between the\r
+sequences /* and */ and within the sequence, individual * and / characters may\r
+appear. An attempt to match C comments by applying the pattern\r
+\r
+  /\\*.*\\*/\r
+\r
+to the string\r
+\r
+  /* first command */  not comment  /* second comment */\r
+\r
+fails, because it matches the entire string owing to the greediness of the .*\r
+item.\r
+\r
+However, if a quantifier is followed by a question mark, it ceases to be\r
+greedy, and instead matches the minimum number of times possible, so the\r
+pattern\r
+\r
+  /\\*.*?\\*/\r
+\r
+does the right thing with the C comments. The meaning of the various\r
+quantifiers is not otherwise changed, just the preferred number of matches.\r
+Do not confuse this use of question mark with its use as a quantifier in its\r
+own right. Because it has two uses, it can sometimes appear doubled, as in\r
+\r
+  \\d??\\d\r
+\r
+which matches one digit by preference, but can match two if that is the only\r
+way the rest of the pattern matches.\r
+\r
+If the PCRE_UNGREEDY option is set (an option which is not available in Perl),\r
+the quantifiers are not greedy by default, but individual ones can be made\r
+greedy by following them with a question mark. In other words, it inverts the\r
+default behaviour.\r
+\r
+When a parenthesized subpattern is quantified with a minimum repeat count that\r
+is greater than 1 or with a limited maximum, more store is required for the\r
+compiled pattern, in proportion to the size of the minimum or maximum.\r
+\r
+If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent\r
+to Perl's /s) is set, thus allowing the . to match newlines, the pattern is\r
+implicitly anchored, because whatever follows will be tried against every\r
+character position in the subject string, so there is no point in retrying the\r
+overall match at any position after the first. PCRE treats such a pattern as\r
+though it were preceded by \\A. In cases where it is known that the subject\r
+string contains no newlines, it is worth setting PCRE_DOTALL when the pattern\r
+begins with .* in order to obtain this optimization, or alternatively using ^\r
+to indicate anchoring explicitly.\r
+\r
+When a capturing subpattern is repeated, the value captured is the substring\r
+that matched the final iteration. For example, after\r
+\r
+  (tweedle[dume]{3}\\s*)+\r
+\r
+has matched "tweedledum tweedledee" the value of the captured substring is\r
+"tweedledee". However, if there are nested capturing subpatterns, the\r
+corresponding captured values may have been set in previous iterations. For\r
+example, after\r
+\r
+  /(a|(b))+/\r
+\r
+matches "aba" the value of the second captured substring is "b".\r
+\r
+\r
+.SH BACK REFERENCES\r
+Outside a character class, a backslash followed by a digit greater than 0 (and\r
+possibly further digits) is a back reference to a capturing subpattern earlier\r
+(i.e. to its left) in the pattern, provided there have been that many previous\r
+capturing left parentheses.\r
+\r
+However, if the decimal number following the backslash is less than 10, it is\r
+always taken as a back reference, and causes an error only if there are not\r
+that many capturing left parentheses in the entire pattern. In other words, the\r
+parentheses that are referenced need not be to the left of the reference for\r
+numbers less than 10. See the section entitled "Backslash" above for further\r
+details of the handling of digits following a backslash.\r
+\r
+A back reference matches whatever actually matched the capturing subpattern in\r
+the current subject string, rather than anything matching the subpattern\r
+itself. So the pattern\r
+\r
+  (sens|respons)e and \\1ibility\r
+\r
+matches "sense and sensibility" and "response and responsibility", but not\r
+"sense and responsibility". If caseful matching is in force at the time of the\r
+back reference, the case of letters is relevant. For example,\r
+\r
+  ((?i)rah)\\s+\\1\r
+\r
+matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original\r
+capturing subpattern is matched caselessly.\r
+\r
+There may be more than one back reference to the same subpattern. If a\r
+subpattern has not actually been used in a particular match, any back\r
+references to it always fail. For example, the pattern\r
+\r
+  (a|(bc))\\2\r
+\r
+always fails if it starts to match "a" rather than "bc". Because there may be\r
+up to 99 back references, all digits following the backslash are taken\r
+as part of a potential back reference number. If the pattern continues with a\r
+digit character, some delimiter must be used to terminate the back reference.\r
+If the PCRE_EXTENDED option is set, this can be whitespace. Otherwise an empty\r
+comment can be used.\r
+\r
+A back reference that occurs inside the parentheses to which it refers fails\r
+when the subpattern is first used, so, for example, (a\\1) never matches.\r
+However, such references can be useful inside repeated subpatterns. For\r
+example, the pattern\r
+\r
+  (a|b\\1)+\r
+\r
+matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of\r
+the subpattern, the back reference matches the character string corresponding\r
+to the previous iteration. In order for this to work, the pattern must be such\r
+that the first iteration does not need to match the back reference. This can be\r
+done using alternation, as in the example above, or by a quantifier with a\r
+minimum of zero.\r
+\r
+\r
+.SH ASSERTIONS\r
+An assertion is a test on the characters following or preceding the current\r
+matching point that does not actually consume any characters. The simple\r
+assertions coded as \\b, \\B, \\A, \\Z, \\z, ^ and $ are described above. More\r
+complicated assertions are coded as subpatterns. There are two kinds: those\r
+that look ahead of the current position in the subject string, and those that\r
+look behind it.\r
+\r
+An assertion subpattern is matched in the normal way, except that it does not\r
+cause the current matching position to be changed. Lookahead assertions start\r
+with (?= for positive assertions and (?! for negative assertions. For example,\r
+\r
+  \\w+(?=;)\r
+\r
+matches a word followed by a semicolon, but does not include the semicolon in\r
+the match, and\r
+\r
+  foo(?!bar)\r
+\r
+matches any occurrence of "foo" that is not followed by "bar". Note that the\r
+apparently similar pattern\r
+\r
+  (?!foo)bar\r
+\r
+does not find an occurrence of "bar" that is preceded by something other than\r
+"foo"; it finds any occurrence of "bar" whatsoever, because the assertion\r
+(?!foo) is always true when the next three characters are "bar". A\r
+lookbehind assertion is needed to achieve this effect.\r
+\r
+Lookbehind assertions start with (?<= for positive assertions and (?<! for\r
+negative assertions. For example,\r
+\r
+  (?<!foo)bar\r
+\r
+does find an occurrence of "bar" that is not preceded by "foo". The contents of\r
+a lookbehind assertion are restricted such that all the strings it matches must\r
+have a fixed length. However, if there are several alternatives, they do not\r
+all have to have the same fixed length. Thus\r
+\r
+  (?<=bullock|donkey)\r
+\r
+is permitted, but\r
+\r
+  (?<!dogs?|cats?)\r
+\r
+causes an error at compile time. Branches that match different length strings\r
+are permitted only at the top level of a lookbehind assertion. This is an\r
+extension compared with Perl 5.005, which requires all branches to match the\r
+same length of string. An assertion such as\r
+\r
+  (?<=ab(c|de))\r
+\r
+is not permitted, because its single top-level branch can match two different\r
+lengths, but it is acceptable if rewritten to use two top-level branches:\r
+\r
+  (?<=abc|abde)\r
+\r
+The implementation of lookbehind assertions is, for each alternative, to\r
+temporarily move the current position back by the fixed width and then try to\r
+match. If there are insufficient characters before the current position, the\r
+match is deemed to fail. Lookbehinds in conjunction with once-only subpatterns\r
+can be particularly useful for matching at the ends of strings; an example is\r
+given at the end of the section on once-only subpatterns.\r
+\r
+Several assertions (of any sort) may occur in succession. For example,\r
+\r
+  (?<=\\d{3})(?<!999)foo\r
+\r
+matches "foo" preceded by three digits that are not "999". Notice that each of\r
+the assertions is applied independently at the same point in the subject\r
+string. First there is a check that the previous three characters are all\r
+digits, and then there is a check that the same three characters are not "999".\r
+This pattern does \fInot\fR match "foo" preceded by six characters, the first\r
+of which are digits and the last three of which are not "999". For example, it\r
+doesn't match "123abcfoo". A pattern to do that is\r
+\r
+  (?<=\\d{3}...)(?<!999)foo\r
+\r
+This time the first assertion looks at the preceding six characters, checking\r
+that the first three are digits, and then the second assertion checks that the\r
+preceding three characters are not "999".\r
+\r
+Assertions can be nested in any combination. For example,\r
+\r
+  (?<=(?<!foo)bar)baz\r
+\r
+matches an occurrence of "baz" that is preceded by "bar" which in turn is not\r
+preceded by "foo", while\r
+\r
+  (?<=\\d{3}(?!999)...)foo\r
+\r
+is another pattern which matches "foo" preceded by three digits and any three\r
+characters that are not "999".\r
+\r
+Assertion subpatterns are not capturing subpatterns, and may not be repeated,\r
+because it makes no sense to assert the same thing several times. If any kind\r
+of assertion contains capturing subpatterns within it, these are counted for\r
+the purposes of numbering the capturing subpatterns in the whole pattern.\r
+However, substring capturing is carried out only for positive assertions,\r
+because it does not make sense for negative assertions.\r
+\r
+Assertions count towards the maximum of 200 parenthesized subpatterns.\r
+\r
+\r
+.SH ONCE-ONLY SUBPATTERNS\r
+With both maximizing and minimizing repetition, failure of what follows\r
+normally causes the repeated item to be re-evaluated to see if a different\r
+number of repeats allows the rest of the pattern to match. Sometimes it is\r
+useful to prevent this, either to change the nature of the match, or to cause\r
+it fail earlier than it otherwise might, when the author of the pattern knows\r
+there is no point in carrying on.\r
+\r
+Consider, for example, the pattern \\d+foo when applied to the subject line\r
+\r
+  123456bar\r
+\r
+After matching all 6 digits and then failing to match "foo", the normal\r
+action of the matcher is to try again with only 5 digits matching the \\d+\r
+item, and then with 4, and so on, before ultimately failing. Once-only\r
+subpatterns provide the means for specifying that once a portion of the pattern\r
+has matched, it is not to be re-evaluated in this way, so the matcher would\r
+give up immediately on failing to match "foo" the first time. The notation is\r
+another kind of special parenthesis, starting with (?> as in this example:\r
+\r
+  (?>\\d+)bar\r
+\r
+This kind of parenthesis "locks up" the  part of the pattern it contains once\r
+it has matched, and a failure further into the pattern is prevented from\r
+backtracking into it. Backtracking past it to previous items, however, works as\r
+normal.\r
+\r
+An alternative description is that a subpattern of this type matches the string\r
+of characters that an identical standalone pattern would match, if anchored at\r
+the current point in the subject string.\r
+\r
+Once-only subpatterns are not capturing subpatterns. Simple cases such as the\r
+above example can be thought of as a maximizing repeat that must swallow\r
+everything it can. So, while both \\d+ and \\d+? are prepared to adjust the\r
+number of digits they match in order to make the rest of the pattern match,\r
+(?>\\d+) can only match an entire sequence of digits.\r
+\r
+This construction can of course contain arbitrarily complicated subpatterns,\r
+and it can be nested.\r
+\r
+Once-only subpatterns can be used in conjunction with lookbehind assertions to\r
+specify efficient matching at the end of the subject string. Consider a simple\r
+pattern such as\r
+\r
+  abcd$\r
+\r
+when applied to a long string which does not match. Because matching proceeds\r
+from left to right, PCRE will look for each "a" in the subject and then see if\r
+what follows matches the rest of the pattern. If the pattern is specified as\r
+\r
+  ^.*abcd$\r
+\r
+the initial .* matches the entire string at first, but when this fails (because\r
+there is no following "a"), it backtracks to match all but the last character,\r
+then all but the last two characters, and so on. Once again the search for "a"\r
+covers the entire string, from right to left, so we are no better off. However,\r
+if the pattern is written as\r
+\r
+  ^(?>.*)(?<=abcd)\r
+\r
+there can be no backtracking for the .* item; it can match only the entire\r
+string. The subsequent lookbehind assertion does a single test on the last four\r
+characters. If it fails, the match fails immediately. For long strings, this\r
+approach makes a significant difference to the processing time.\r
+\r
+When a pattern contains an unlimited repeat inside a subpattern that can itself\r
+be repeated an unlimited number of times, the use of a once-only subpattern is\r
+the only way to avoid some failing matches taking a very long time indeed.\r
+The pattern\r
+\r
+  (\\D+|<\\d+>)*[!?]\r
+\r
+matches an unlimited number of substrings that either consist of non-digits, or\r
+digits enclosed in <>, followed by either ! or ?. When it matches, it runs\r
+quickly. However, if it is applied to\r
+\r
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r
+\r
+it takes a long time before reporting failure. This is because the string can\r
+be divided between the two repeats in a large number of ways, and all have to\r
+be tried. (The example used [!?] rather than a single character at the end,\r
+because both PCRE and Perl have an optimization that allows for fast failure\r
+when a single character is used. They remember the last single character that\r
+is required for a match, and fail early if it is not present in the string.)\r
+If the pattern is changed to\r
+\r
+  ((?>\\D+)|<\\d+>)*[!?]\r
+\r
+sequences of non-digits cannot be broken, and failure happens quickly.\r
+\r
+\r
+.SH CONDITIONAL SUBPATTERNS\r
+It is possible to cause the matching process to obey a subpattern\r
+conditionally or to choose between two alternative subpatterns, depending on\r
+the result of an assertion, or whether a previous capturing subpattern matched\r
+or not. The two possible forms of conditional subpattern are\r
+\r
+  (?(condition)yes-pattern)\r
+  (?(condition)yes-pattern|no-pattern)\r
+\r
+If the condition is satisfied, the yes-pattern is used; otherwise the\r
+no-pattern (if present) is used. If there are more than two alternatives in the\r
+subpattern, a compile-time error occurs.\r
+\r
+There are two kinds of condition. If the text between the parentheses consists\r
+of a sequence of digits, the condition is satisfied if the capturing subpattern\r
+of that number has previously matched. The number must be greater than zero.\r
+Consider the following pattern, which contains non-significant white space to\r
+make it more readable (assume the PCRE_EXTENDED option) and to divide it into\r
+three parts for ease of discussion:\r
+\r
+  ( \\( )?    [^()]+    (?(1) \\) )\r
+\r
+The first part matches an optional opening parenthesis, and if that\r
+character is present, sets it as the first captured substring. The second part\r
+matches one or more characters that are not parentheses. The third part is a\r
+conditional subpattern that tests whether the first set of parentheses matched\r
+or not. If they did, that is, if subject started with an opening parenthesis,\r
+the condition is true, and so the yes-pattern is executed and a closing\r
+parenthesis is required. Otherwise, since no-pattern is not present, the\r
+subpattern matches nothing. In other words, this pattern matches a sequence of\r
+non-parentheses, optionally enclosed in parentheses.\r
+\r
+If the condition is not a sequence of digits, it must be an assertion. This may\r
+be a positive or negative lookahead or lookbehind assertion. Consider this\r
+pattern, again containing non-significant white space, and with the two\r
+alternatives on the second line:\r
+\r
+  (?(?=[^a-z]*[a-z])\r
+  \\d{2}-[a-z]{3}-\\d{2}  |  \\d{2}-\\d{2}-\\d{2} )\r
+\r
+The condition is a positive lookahead assertion that matches an optional\r
+sequence of non-letters followed by a letter. In other words, it tests for the\r
+presence of at least one letter in the subject. If a letter is found, the\r
+subject is matched against the first alternative; otherwise it is matched\r
+against the second. This pattern matches strings in one of the two forms\r
+dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.\r
+\r
+\r
+.SH COMMENTS\r
+The sequence (?# marks the start of a comment which continues up to the next\r
+closing parenthesis. Nested parentheses are not permitted. The characters\r
+that make up a comment play no part in the pattern matching at all.\r
+\r
+If the PCRE_EXTENDED option is set, an unescaped # character outside a\r
+character class introduces a comment that continues up to the next newline\r
+character in the pattern.\r
+\r
+\r
+.SH RECURSIVE PATTERNS\r
+Consider the problem of matching a string in parentheses, allowing for\r
+unlimited nested parentheses. Without the use of recursion, the best that can\r
+be done is to use a pattern that matches up to some fixed depth of nesting. It\r
+is not possible to handle an arbitrary nesting depth. Perl 5.6 has provided an\r
+experimental facility that allows regular expressions to recurse (amongst other\r
+things). It does this by interpolating Perl code in the expression at run time,\r
+and the code can refer to the expression itself. A Perl pattern to solve the\r
+parentheses problem can be created like this:\r
+\r
+  $re = qr{\\( (?: (?>[^()]+) | (?p{$re}) )* \\)}x;\r
+\r
+The (?p{...}) item interpolates Perl code at run time, and in this case refers\r
+recursively to the pattern in which it appears. Obviously, PCRE cannot support\r
+the interpolation of Perl code. Instead, the special item (?R) is provided for\r
+the specific case of recursion. This PCRE pattern solves the parentheses\r
+problem (assume the PCRE_EXTENDED option is set so that white space is\r
+ignored):\r
+\r
+  \\( ( (?>[^()]+) | (?R) )* \\)\r
+\r
+First it matches an opening parenthesis. Then it matches any number of\r
+substrings which can either be a sequence of non-parentheses, or a recursive\r
+match of the pattern itself (i.e. a correctly parenthesized substring). Finally\r
+there is a closing parenthesis.\r
+\r
+This particular example pattern contains nested unlimited repeats, and so the\r
+use of a once-only subpattern for matching strings of non-parentheses is\r
+important when applying the pattern to strings that do not match. For example,\r
+when it is applied to\r
+\r
+  (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\r
+\r
+it yields "no match" quickly. However, if a once-only subpattern is not used,\r
+the match runs for a very long time indeed because there are so many different\r
+ways the + and * repeats can carve up the subject, and all have to be tested\r
+before failure can be reported.\r
+\r
+The values set for any capturing subpatterns are those from the outermost level\r
+of the recursion at which the subpattern value is set. If the pattern above is\r
+matched against\r
+\r
+  (ab(cd)ef)\r
+\r
+the value for the capturing parentheses is "ef", which is the last value taken\r
+on at the top level. If additional parentheses are added, giving\r
+\r
+  \\( ( ( (?>[^()]+) | (?R) )* ) \\)\r
+     ^                        ^\r
+     ^                        ^\r
+the string they capture is "ab(cd)ef", the contents of the top level\r
+parentheses. If there are more than 15 capturing parentheses in a pattern, PCRE\r
+has to obtain extra memory to store data during a recursion, which it does by\r
+using \fBpcre_malloc\fR, freeing it via \fBpcre_free\fR afterwards. If no\r
+memory can be obtained, it saves data for the first 15 capturing parentheses\r
+only, as there is no way to give an out-of-memory error from within a\r
+recursion.\r
+\r
+\r
+.SH PERFORMANCE\r
+Certain items that may appear in patterns are more efficient than others. It is\r
+more efficient to use a character class like [aeiou] than a set of alternatives\r
+such as (a|e|i|o|u). In general, the simplest construction that provides the\r
+required behaviour is usually the most efficient. Jeffrey Friedl's book\r
+contains a lot of discussion about optimizing regular expressions for efficient\r
+performance.\r
+\r
+When a pattern begins with .* and the PCRE_DOTALL option is set, the pattern is\r
+implicitly anchored by PCRE, since it can match only at the start of a subject\r
+string. However, if PCRE_DOTALL is not set, PCRE cannot make this optimization,\r
+because the . metacharacter does not then match a newline, and if the subject\r
+string contains newlines, the pattern may match from the character immediately\r
+following one of them instead of from the very start. For example, the pattern\r
+\r
+  (.*) second\r
+\r
+matches the subject "first\\nand second" (where \\n stands for a newline\r
+character) with the first captured substring being "and". In order to do this,\r
+PCRE has to retry the match starting after every newline in the subject.\r
+\r
+If you are using such a pattern with subject strings that do not contain\r
+newlines, the best performance is obtained by setting PCRE_DOTALL, or starting\r
+the pattern with ^.* to indicate explicit anchoring. That saves PCRE from\r
+having to scan along the subject looking for a newline to restart at.\r
+\r
+Beware of patterns that contain nested indefinite repeats. These can take a\r
+long time to run when applied to a string that does not match. Consider the\r
+pattern fragment\r
+\r
+  (a+)*\r
+\r
+This can match "aaaa" in 33 different ways, and this number increases very\r
+rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4\r
+times, and for each of those cases other than 0, the + repeats can match\r
+different numbers of times.) When the remainder of the pattern is such that the\r
+entire match is going to fail, PCRE has in principle to try every possible\r
+variation, and this can take an extremely long time.\r
+\r
+An optimization catches some of the more simple cases such as\r
+\r
+  (a+)*b\r
+\r
+where a literal character follows. Before embarking on the standard matching\r
+procedure, PCRE checks that there is a "b" later in the subject string, and if\r
+there is not, it fails the match immediately. However, when there is no\r
+following literal this optimization cannot be used. You can see the difference\r
+by comparing the behaviour of\r
+\r
+  (a+)*\\d\r
+\r
+with the pattern above. The former gives a failure almost instantly when\r
+applied to a whole line of "a" characters, whereas the latter takes an\r
+appreciable time with strings longer than about 20 characters.\r
+\r
+\r
+.SH UTF-8 SUPPORT\r
+Starting at release 3.3, PCRE has some support for character strings encoded\r
+in the UTF-8 format. This is incomplete, and is regarded as experimental. In\r
+order to use it, you must configure PCRE to include UTF-8 support in the code,\r
+and, in addition, you must call \fBpcre_compile()\fR with the PCRE_UTF8 option\r
+flag. When you do this, both the pattern and any subject strings that are\r
+matched against it are treated as UTF-8 strings instead of just strings of\r
+bytes, but only in the cases that are mentioned below.\r
+\r
+If you compile PCRE with UTF-8 support, but do not use it at run time, the\r
+library will be a bit bigger, but the additional run time overhead is limited\r
+to testing the PCRE_UTF8 flag in several places, so should not be very large.\r
+\r
+PCRE assumes that the strings it is given contain valid UTF-8 codes. It does\r
+not diagnose invalid UTF-8 strings. If you pass invalid UTF-8 strings to PCRE,\r
+the results are undefined.\r
+\r
+Running with PCRE_UTF8 set causes these changes in the way PCRE works:\r
+\r
+1. In a pattern, the escape sequence \\x{...}, where the contents of the braces\r
+is a string of hexadecimal digits, is interpreted as a UTF-8 character whose\r
+code number is the given hexadecimal number, for example: \\x{1234}. This\r
+inserts from one to six literal bytes into the pattern, using the UTF-8\r
+encoding. If a non-hexadecimal digit appears between the braces, the item is\r
+not recognized.\r
+\r
+2. The original hexadecimal escape sequence, \\xhh, generates a two-byte UTF-8\r
+character if its value is greater than 127.\r
+\r
+3. Repeat quantifiers are NOT correctly handled if they follow a multibyte\r
+character. For example, \\x{100}* and \\xc3+ do not work. If you want to\r
+repeat such characters, you must enclose them in non-capturing parentheses,\r
+for example (?:\\x{100}), at present.\r
+\r
+4. The dot metacharacter matches one UTF-8 character instead of a single byte.\r
+\r
+5. Unlike literal UTF-8 characters, the dot metacharacter followed by a\r
+repeat quantifier does operate correctly on UTF-8 characters instead of\r
+single bytes.\r
+\r
+4. Although the \\x{...} escape is permitted in a character class, characters\r
+whose values are greater than 255 cannot be included in a class.\r
+\r
+5. A class is matched against a UTF-8 character instead of just a single byte,\r
+but it can match only characters whose values are less than 256. Characters\r
+with greater values always fail to match a class.\r
+\r
+6. Repeated classes work correctly on multiple characters.\r
+\r
+7. Classes containing just a single character whose value is greater than 127\r
+(but less than 256), for example, [\\x80] or [^\\x{93}], do not work because\r
+these are optimized into single byte matches. In the first case, of course,\r
+the class brackets are just redundant.\r
+\r
+8. Lookbehind assertions move backwards in the subject by a fixed number of\r
+characters instead of a fixed number of bytes. Simple cases have been tested\r
+to work correctly, but there may be hidden gotchas herein.\r
+\r
+9. The character types such as \\d and \\w do not work correctly with UTF-8\r
+characters. They continue to test a single byte.\r
+\r
+10. Anything not explicitly mentioned here continues to work in bytes rather\r
+than in characters.\r
+\r
+The following UTF-8 features of Perl 5.6 are not implemented:\r
+\r
+1. The escape sequence \\C to match a single byte.\r
+\r
+2. The use of Unicode tables and properties and escapes \\p, \\P, and \\X.\r
+\r
+.SH AUTHOR\r
+Philip Hazel <ph10@cam.ac.uk>\r
+.br\r
+University Computing Service,\r
+.br\r
+New Museums Site,\r
+.br\r
+Cambridge CB2 3QG, England.\r
+.br\r
+Phone: +44 1223 334714\r
+\r
+Last updated: 28 August 2000,\r
+.br\r
+  the 250th anniversary of the death of J.S. Bach.\r
+.br\r
+Copyright (c) 1997-2000 University of Cambridge.\r
diff --git a/pcre/doc/pcre.html b/pcre/doc/pcre.html
new file mode 100644 (file)
index 0000000..b12b212
--- /dev/null
@@ -0,0 +1,2397 @@
+<HTML>\r
+<HEAD>\r
+<TITLE>pcre specification</TITLE>\r
+</HEAD>\r
+<body bgcolor="#FFFFFF" text="#00005A">\r
+<H1>pcre specification</H1>\r
+This HTML document has been generated automatically from the original man page.\r
+If there is any nonsense in it, please consult the man page in case the\r
+conversion went wrong.\r
+<UL>\r
+<LI><A NAME="TOC1" HREF="#SEC1">NAME</A>\r
+<LI><A NAME="TOC2" HREF="#SEC2">SYNOPSIS</A>\r
+<LI><A NAME="TOC3" HREF="#SEC3">DESCRIPTION</A>\r
+<LI><A NAME="TOC4" HREF="#SEC4">MULTI-THREADING</A>\r
+<LI><A NAME="TOC5" HREF="#SEC5">COMPILING A PATTERN</A>\r
+<LI><A NAME="TOC6" HREF="#SEC6">STUDYING A PATTERN</A>\r
+<LI><A NAME="TOC7" HREF="#SEC7">LOCALE SUPPORT</A>\r
+<LI><A NAME="TOC8" HREF="#SEC8">INFORMATION ABOUT A PATTERN</A>\r
+<LI><A NAME="TOC9" HREF="#SEC9">MATCHING A PATTERN</A>\r
+<LI><A NAME="TOC10" HREF="#SEC10">EXTRACTING CAPTURED SUBSTRINGS</A>\r
+<LI><A NAME="TOC11" HREF="#SEC11">LIMITATIONS</A>\r
+<LI><A NAME="TOC12" HREF="#SEC12">DIFFERENCES FROM PERL</A>\r
+<LI><A NAME="TOC13" HREF="#SEC13">REGULAR EXPRESSION DETAILS</A>\r
+<LI><A NAME="TOC14" HREF="#SEC14">BACKSLASH</A>\r
+<LI><A NAME="TOC15" HREF="#SEC15">CIRCUMFLEX AND DOLLAR</A>\r
+<LI><A NAME="TOC16" HREF="#SEC16">FULL STOP (PERIOD, DOT)</A>\r
+<LI><A NAME="TOC17" HREF="#SEC17">SQUARE BRACKETS</A>\r
+<LI><A NAME="TOC18" HREF="#SEC18">POSIX CHARACTER CLASSES</A>\r
+<LI><A NAME="TOC19" HREF="#SEC19">VERTICAL BAR</A>\r
+<LI><A NAME="TOC20" HREF="#SEC20">INTERNAL OPTION SETTING</A>\r
+<LI><A NAME="TOC21" HREF="#SEC21">SUBPATTERNS</A>\r
+<LI><A NAME="TOC22" HREF="#SEC22">REPETITION</A>\r
+<LI><A NAME="TOC23" HREF="#SEC23">BACK REFERENCES</A>\r
+<LI><A NAME="TOC24" HREF="#SEC24">ASSERTIONS</A>\r
+<LI><A NAME="TOC25" HREF="#SEC25">ONCE-ONLY SUBPATTERNS</A>\r
+<LI><A NAME="TOC26" HREF="#SEC26">CONDITIONAL SUBPATTERNS</A>\r
+<LI><A NAME="TOC27" HREF="#SEC27">COMMENTS</A>\r
+<LI><A NAME="TOC28" HREF="#SEC28">RECURSIVE PATTERNS</A>\r
+<LI><A NAME="TOC29" HREF="#SEC29">PERFORMANCE</A>\r
+<LI><A NAME="TOC30" HREF="#SEC30">UTF-8 SUPPORT</A>\r
+<LI><A NAME="TOC31" HREF="#SEC31">AUTHOR</A>\r
+</UL>\r
+<LI><A NAME="SEC1" HREF="#TOC1">NAME</A>\r
+<P>\r
+pcre - Perl-compatible regular expressions.\r
+</P>\r
+<LI><A NAME="SEC2" HREF="#TOC1">SYNOPSIS</A>\r
+<P>\r
+<B>#include &#60;pcre.h&#62;</B>\r
+</P>\r
+<P>\r
+<B>pcre *pcre_compile(const char *<I>pattern</I>, int <I>options</I>,</B>\r
+<B>const char **<I>errptr</I>, int *<I>erroffset</I>,</B>\r
+<B>const unsigned char *<I>tableptr</I>);</B>\r
+</P>\r
+<P>\r
+<B>pcre_extra *pcre_study(const pcre *<I>code</I>, int <I>options</I>,</B>\r
+<B>const char **<I>errptr</I>);</B>\r
+</P>\r
+<P>\r
+<B>int pcre_exec(const pcre *<I>code</I>, const pcre_extra *<I>extra</I>,</B>\r
+<B>const char *<I>subject</I>, int <I>length</I>, int <I>startoffset</I>,</B>\r
+<B>int <I>options</I>, int *<I>ovector</I>, int <I>ovecsize</I>);</B>\r
+</P>\r
+<P>\r
+<B>int pcre_copy_substring(const char *<I>subject</I>, int *<I>ovector</I>,</B>\r
+<B>int <I>stringcount</I>, int <I>stringnumber</I>, char *<I>buffer</I>,</B>\r
+<B>int <I>buffersize</I>);</B>\r
+</P>\r
+<P>\r
+<B>int pcre_get_substring(const char *<I>subject</I>, int *<I>ovector</I>,</B>\r
+<B>int <I>stringcount</I>, int <I>stringnumber</I>,</B>\r
+<B>const char **<I>stringptr</I>);</B>\r
+</P>\r
+<P>\r
+<B>int pcre_get_substring_list(const char *<I>subject</I>,</B>\r
+<B>int *<I>ovector</I>, int <I>stringcount</I>, const char ***<I>listptr</I>);</B>\r
+</P>\r
+<P>\r
+<B>void pcre_free_substring(const char *<I>stringptr</I>);</B>\r
+</P>\r
+<P>\r
+<B>void pcre_free_substring_list(const char **<I>stringptr</I>);</B>\r
+</P>\r
+<P>\r
+<B>const unsigned char *pcre_maketables(void);</B>\r
+</P>\r
+<P>\r
+<B>int pcre_fullinfo(const pcre *<I>code</I>, const pcre_extra *<I>extra</I>,</B>\r
+<B>int <I>what</I>, void *<I>where</I>);</B>\r
+</P>\r
+<P>\r
+<B>int pcre_info(const pcre *<I>code</I>, int *<I>optptr</I>, int</B>\r
+<B>*<I>firstcharptr</I>);</B>\r
+</P>\r
+<P>\r
+<B>char *pcre_version(void);</B>\r
+</P>\r
+<P>\r
+<B>void *(*pcre_malloc)(size_t);</B>\r
+</P>\r
+<P>\r
+<B>void (*pcre_free)(void *);</B>\r
+</P>\r
+<LI><A NAME="SEC3" HREF="#TOC1">DESCRIPTION</A>\r
+<P>\r
+The PCRE library is a set of functions that implement regular expression\r
+pattern matching using the same syntax and semantics as Perl 5, with just a few\r
+differences (see below). The current implementation corresponds to Perl 5.005,\r
+with some additional features from later versions. This includes some\r
+experimental, incomplete support for UTF-8 encoded strings. Details of exactly\r
+what is and what is not supported are given below.\r
+</P>\r
+<P>\r
+PCRE has its own native API, which is described in this document. There is also\r
+a set of wrapper functions that correspond to the POSIX regular expression API.\r
+These are described in the <B>pcreposix</B> documentation.\r
+</P>\r
+<P>\r
+The native API function prototypes are defined in the header file <B>pcre.h</B>,\r
+and on Unix systems the library itself is called <B>libpcre.a</B>, so can be\r
+accessed by adding <B>-lpcre</B> to the command for linking an application which\r
+calls it. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to\r
+contain the major and minor release numbers for the library. Applications can\r
+use these to include support for different releases.\r
+</P>\r
+<P>\r
+The functions <B>pcre_compile()</B>, <B>pcre_study()</B>, and <B>pcre_exec()</B>\r
+are used for compiling and matching regular expressions.\r
+</P>\r
+<P>\r
+The functions <B>pcre_copy_substring()</B>, <B>pcre_get_substring()</B>, and\r
+<B>pcre_get_substring_list()</B> are convenience functions for extracting\r
+captured substrings from a matched subject string; <B>pcre_free_substring()</B>\r
+and <B>pcre_free_substring_list()</B> are also provided, to free the memory used\r
+for extracted strings.\r
+</P>\r
+<P>\r
+The function <B>pcre_maketables()</B> is used (optionally) to build a set of\r
+character tables in the current locale for passing to <B>pcre_compile()</B>.\r
+</P>\r
+<P>\r
+The function <B>pcre_fullinfo()</B> is used to find out information about a\r
+compiled pattern; <B>pcre_info()</B> is an obsolete version which returns only\r
+some of the available information, but is retained for backwards compatibility.\r
+The function <B>pcre_version()</B> returns a pointer to a string containing the\r
+version of PCRE and its date of release.\r
+</P>\r
+<P>\r
+The global variables <B>pcre_malloc</B> and <B>pcre_free</B> initially contain\r
+the entry points of the standard <B>malloc()</B> and <B>free()</B> functions\r
+respectively. PCRE calls the memory management functions via these variables,\r
+so a calling program can replace them if it wishes to intercept the calls. This\r
+should be done before calling any PCRE functions.\r
+</P>\r
+<LI><A NAME="SEC4" HREF="#TOC1">MULTI-THREADING</A>\r
+<P>\r
+The PCRE functions can be used in multi-threading applications, with the\r
+proviso that the memory management functions pointed to by <B>pcre_malloc</B>\r
+and <B>pcre_free</B> are shared by all threads.\r
+</P>\r
+<P>\r
+The compiled form of a regular expression is not altered during matching, so\r
+the same compiled pattern can safely be used by several threads at once.\r
+</P>\r
+<LI><A NAME="SEC5" HREF="#TOC1">COMPILING A PATTERN</A>\r
+<P>\r
+The function <B>pcre_compile()</B> is called to compile a pattern into an\r
+internal form. The pattern is a C string terminated by a binary zero, and\r
+is passed in the argument <I>pattern</I>. A pointer to a single block of memory\r
+that is obtained via <B>pcre_malloc</B> is returned. This contains the\r
+compiled code and related data. The <B>pcre</B> type is defined for this for\r
+convenience, but in fact <B>pcre</B> is just a typedef for <B>void</B>, since the\r
+contents of the block are not externally defined. It is up to the caller to\r
+free the memory when it is no longer required.\r
+</P>\r
+<P>\r
+The size of a compiled pattern is roughly proportional to the length of the\r
+pattern string, except that each character class (other than those containing\r
+just a single character, negated or not) requires 33 bytes, and repeat\r
+quantifiers with a minimum greater than one or a bounded maximum cause the\r
+relevant portions of the compiled pattern to be replicated.\r
+</P>\r
+<P>\r
+The <I>options</I> argument contains independent bits that affect the\r
+compilation. It should be zero if no options are required. Some of the options,\r
+in particular, those that are compatible with Perl, can also be set and unset\r
+from within the pattern (see the detailed description of regular expressions\r
+below). For these options, the contents of the <I>options</I> argument specifies\r
+their initial settings at the start of compilation and execution. The\r
+PCRE_ANCHORED option can be set at the time of matching as well as at compile\r
+time.\r
+</P>\r
+<P>\r
+If <I>errptr</I> is NULL, <B>pcre_compile()</B> returns NULL immediately.\r
+Otherwise, if compilation of a pattern fails, <B>pcre_compile()</B> returns\r
+NULL, and sets the variable pointed to by <I>errptr</I> to point to a textual\r
+error message. The offset from the start of the pattern to the character where\r
+the error was discovered is placed in the variable pointed to by\r
+<I>erroffset</I>, which must not be NULL. If it is, an immediate error is given.\r
+</P>\r
+<P>\r
+If the final argument, <I>tableptr</I>, is NULL, PCRE uses a default set of\r
+character tables which are built when it is compiled, using the default C\r
+locale. Otherwise, <I>tableptr</I> must be the result of a call to\r
+<B>pcre_maketables()</B>. See the section on locale support below.\r
+</P>\r
+<P>\r
+The following option bits are defined in the header file:\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ANCHORED\r
+</PRE>\r
+</P>\r
+<P>\r
+If this bit is set, the pattern is forced to be "anchored", that is, it is\r
+constrained to match only at the start of the string which is being searched\r
+(the "subject string"). This effect can also be achieved by appropriate\r
+constructs in the pattern itself, which is the only way to do it in Perl.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_CASELESS\r
+</PRE>\r
+</P>\r
+<P>\r
+If this bit is set, letters in the pattern match both upper and lower case\r
+letters. It is equivalent to Perl's /i option.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_DOLLAR_ENDONLY\r
+</PRE>\r
+</P>\r
+<P>\r
+If this bit is set, a dollar metacharacter in the pattern matches only at the\r
+end of the subject string. Without this option, a dollar also matches\r
+immediately before the final character if it is a newline (but not before any\r
+other newlines). The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is\r
+set. There is no equivalent to this option in Perl.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_DOTALL\r
+</PRE>\r
+</P>\r
+<P>\r
+If this bit is set, a dot metacharater in the pattern matches all characters,\r
+including newlines. Without it, newlines are excluded. This option is\r
+equivalent to Perl's /s option. A negative class such as [^a] always matches a\r
+newline character, independent of the setting of this option.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_EXTENDED\r
+</PRE>\r
+</P>\r
+<P>\r
+If this bit is set, whitespace data characters in the pattern are totally\r
+ignored except when escaped or inside a character class, and characters between\r
+an unescaped # outside a character class and the next newline character,\r
+inclusive, are also ignored. This is equivalent to Perl's /x option, and makes\r
+it possible to include comments inside complicated patterns. Note, however,\r
+that this applies only to data characters. Whitespace characters may never\r
+appear within special character sequences in a pattern, for example within the\r
+sequence (?( which introduces a conditional subpattern.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_EXTRA\r
+</PRE>\r
+</P>\r
+<P>\r
+This option was invented in order to turn on additional functionality of PCRE\r
+that is incompatible with Perl, but it is currently of very little use. When\r
+set, any backslash in a pattern that is followed by a letter that has no\r
+special meaning causes an error, thus reserving these combinations for future\r
+expansion. By default, as in Perl, a backslash followed by a letter with no\r
+special meaning is treated as a literal. There are at present no other features\r
+controlled by this option. It can also be set by a (?X) option setting within a\r
+pattern.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_MULTILINE\r
+</PRE>\r
+</P>\r
+<P>\r
+By default, PCRE treats the subject string as consisting of a single "line" of\r
+characters (even if it actually contains several newlines). The "start of line"\r
+metacharacter (^) matches only at the start of the string, while the "end of\r
+line" metacharacter ($) matches only at the end of the string, or before a\r
+terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as\r
+Perl.\r
+</P>\r
+<P>\r
+When PCRE_MULTILINE it is set, the "start of line" and "end of line" constructs\r
+match immediately following or immediately before any newline in the subject\r
+string, respectively, as well as at the very start and end. This is equivalent\r
+to Perl's /m option. If there are no "\n" characters in a subject string, or\r
+no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no\r
+effect.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_UNGREEDY\r
+</PRE>\r
+</P>\r
+<P>\r
+This option inverts the "greediness" of the quantifiers so that they are not\r
+greedy by default, but become greedy if followed by "?". It is not compatible\r
+with Perl. It can also be set by a (?U) option setting within the pattern.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_UTF8\r
+</PRE>\r
+</P>\r
+<P>\r
+This option causes PCRE to regard both the pattern and the subject as strings\r
+of UTF-8 characters instead of just byte strings. However, it is available only\r
+if PCRE has been built to include UTF-8 support. If not, the use of this option\r
+provokes an error. Support for UTF-8 is new, experimental, and incomplete.\r
+Details of exactly what it entails are given below.\r
+</P>\r
+<LI><A NAME="SEC6" HREF="#TOC1">STUDYING A PATTERN</A>\r
+<P>\r
+When a pattern is going to be used several times, it is worth spending more\r
+time analyzing it in order to speed up the time taken for matching. The\r
+function <B>pcre_study()</B> takes a pointer to a compiled pattern as its first\r
+argument, and returns a pointer to a <B>pcre_extra</B> block (another <B>void</B>\r
+typedef) containing additional information about the pattern; this can be\r
+passed to <B>pcre_exec()</B>. If no additional information is available, NULL\r
+is returned.\r
+</P>\r
+<P>\r
+The second argument contains option bits. At present, no options are defined\r
+for <B>pcre_study()</B>, and this argument should always be zero.\r
+</P>\r
+<P>\r
+The third argument for <B>pcre_study()</B> is a pointer to an error message. If\r
+studying succeeds (even if no data is returned), the variable it points to is\r
+set to NULL. Otherwise it points to a textual error message.\r
+</P>\r
+<P>\r
+At present, studying a pattern is useful only for non-anchored patterns that do\r
+not have a single fixed starting character. A bitmap of possible starting\r
+characters is created.\r
+</P>\r
+<LI><A NAME="SEC7" HREF="#TOC1">LOCALE SUPPORT</A>\r
+<P>\r
+PCRE handles caseless matching, and determines whether characters are letters,\r
+digits, or whatever, by reference to a set of tables. The library contains a\r
+default set of tables which is created in the default C locale when PCRE is\r
+compiled. This is used when the final argument of <B>pcre_compile()</B> is NULL,\r
+and is sufficient for many applications.\r
+</P>\r
+<P>\r
+An alternative set of tables can, however, be supplied. Such tables are built\r
+by calling the <B>pcre_maketables()</B> function, which has no arguments, in the\r
+relevant locale. The result can then be passed to <B>pcre_compile()</B> as often\r
+as necessary. For example, to build and use tables that are appropriate for the\r
+French locale (where accented characters with codes greater than 128 are\r
+treated as letters), the following code could be used:\r
+</P>\r
+<P>\r
+<PRE>\r
+  setlocale(LC_CTYPE, "fr");\r
+  tables = pcre_maketables();\r
+  re = pcre_compile(..., tables);\r
+</PRE>\r
+</P>\r
+<P>\r
+The tables are built in memory that is obtained via <B>pcre_malloc</B>. The\r
+pointer that is passed to <B>pcre_compile</B> is saved with the compiled\r
+pattern, and the same tables are used via this pointer by <B>pcre_study()</B>\r
+and <B>pcre_exec()</B>. Thus for any single pattern, compilation, studying and\r
+matching all happen in the same locale, but different patterns can be compiled\r
+in different locales. It is the caller's responsibility to ensure that the\r
+memory containing the tables remains available for as long as it is needed.\r
+</P>\r
+<LI><A NAME="SEC8" HREF="#TOC1">INFORMATION ABOUT A PATTERN</A>\r
+<P>\r
+The <B>pcre_fullinfo()</B> function returns information about a compiled\r
+pattern. It replaces the obsolete <B>pcre_info()</B> function, which is\r
+nevertheless retained for backwards compability (and is documented below).\r
+</P>\r
+<P>\r
+The first argument for <B>pcre_fullinfo()</B> is a pointer to the compiled\r
+pattern. The second argument is the result of <B>pcre_study()</B>, or NULL if\r
+the pattern was not studied. The third argument specifies which piece of\r
+information is required, while the fourth argument is a pointer to a variable\r
+to receive the data. The yield of the function is zero for success, or one of\r
+the following negative numbers:\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NULL       the argument <I>code</I> was NULL\r
+                        the argument <I>where</I> was NULL\r
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found\r
+  PCRE_ERROR_BADOPTION  the value of <I>what</I> was invalid\r
+</PRE>\r
+</P>\r
+<P>\r
+The possible values for the third argument are defined in <B>pcre.h</B>, and are\r
+as follows:\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_INFO_OPTIONS\r
+</PRE>\r
+</P>\r
+<P>\r
+Return a copy of the options with which the pattern was compiled. The fourth\r
+argument should point to au <B>unsigned long int</B> variable. These option bits\r
+are those specified in the call to <B>pcre_compile()</B>, modified by any\r
+top-level option settings within the pattern itself, and with the PCRE_ANCHORED\r
+bit forcibly set if the form of the pattern implies that it can match only at\r
+the start of a subject string.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_INFO_SIZE\r
+</PRE>\r
+</P>\r
+<P>\r
+Return the size of the compiled pattern, that is, the value that was passed as\r
+the argument to <B>pcre_malloc()</B> when PCRE was getting memory in which to\r
+place the compiled data. The fourth argument should point to a <B>size_t</B>\r
+variable.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_INFO_CAPTURECOUNT\r
+</PRE>\r
+</P>\r
+<P>\r
+Return the number of capturing subpatterns in the pattern. The fourth argument\r
+should point to an \fbint\fR variable.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_INFO_BACKREFMAX\r
+</PRE>\r
+</P>\r
+<P>\r
+Return the number of the highest back reference in the pattern. The fourth\r
+argument should point to an <B>int</B> variable. Zero is returned if there are\r
+no back references.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_INFO_FIRSTCHAR\r
+</PRE>\r
+</P>\r
+<P>\r
+Return information about the first character of any matched string, for a\r
+non-anchored pattern. If there is a fixed first character, e.g. from a pattern\r
+such as (cat|cow|coyote), it is returned in the integer pointed to by\r
+<I>where</I>. Otherwise, if either\r
+</P>\r
+<P>\r
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch\r
+starts with "^", or\r
+</P>\r
+<P>\r
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set\r
+(if it were set, the pattern would be anchored),\r
+</P>\r
+<P>\r
+-1 is returned, indicating that the pattern matches only at the start of a\r
+subject string or after any "\n" within the string. Otherwise -2 is returned.\r
+For anchored patterns, -2 is returned.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_INFO_FIRSTTABLE\r
+</PRE>\r
+</P>\r
+<P>\r
+If the pattern was studied, and this resulted in the construction of a 256-bit\r
+table indicating a fixed set of characters for the first character in any\r
+matching string, a pointer to the table is returned. Otherwise NULL is\r
+returned. The fourth argument should point to an <B>unsigned char *</B>\r
+variable.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_INFO_LASTLITERAL\r
+</PRE>\r
+</P>\r
+<P>\r
+For a non-anchored pattern, return the value of the rightmost literal character\r
+which must exist in any matched string, other than at its start. The fourth\r
+argument should point to an <B>int</B> variable. If there is no such character,\r
+or if the pattern is anchored, -1 is returned. For example, for the pattern\r
+/a\d+z\d+/ the returned value is 'z'.\r
+</P>\r
+<P>\r
+The <B>pcre_info()</B> function is now obsolete because its interface is too\r
+restrictive to return all the available data about a compiled pattern. New\r
+programs should use <B>pcre_fullinfo()</B> instead. The yield of\r
+<B>pcre_info()</B> is the number of capturing subpatterns, or one of the\r
+following negative numbers:\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NULL       the argument <I>code</I> was NULL\r
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found\r
+</PRE>\r
+</P>\r
+<P>\r
+If the <I>optptr</I> argument is not NULL, a copy of the options with which the\r
+pattern was compiled is placed in the integer it points to (see\r
+PCRE_INFO_OPTIONS above).\r
+</P>\r
+<P>\r
+If the pattern is not anchored and the <I>firstcharptr</I> argument is not NULL,\r
+it is used to pass back information about the first character of any matched\r
+string (see PCRE_INFO_FIRSTCHAR above).\r
+</P>\r
+<LI><A NAME="SEC9" HREF="#TOC1">MATCHING A PATTERN</A>\r
+<P>\r
+The function <B>pcre_exec()</B> is called to match a subject string against a\r
+pre-compiled pattern, which is passed in the <I>code</I> argument. If the\r
+pattern has been studied, the result of the study should be passed in the\r
+<I>extra</I> argument. Otherwise this must be NULL.\r
+</P>\r
+<P>\r
+The PCRE_ANCHORED option can be passed in the <I>options</I> argument, whose\r
+unused bits must be zero. However, if a pattern was compiled with\r
+PCRE_ANCHORED, or turned out to be anchored by virtue of its contents, it\r
+cannot be made unachored at matching time.\r
+</P>\r
+<P>\r
+There are also three further options that can be set only at matching time:\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_NOTBOL\r
+</PRE>\r
+</P>\r
+<P>\r
+The first character of the string is not the beginning of a line, so the\r
+circumflex metacharacter should not match before it. Setting this without\r
+PCRE_MULTILINE (at compile time) causes circumflex never to match.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_NOTEOL\r
+</PRE>\r
+</P>\r
+<P>\r
+The end of the string is not the end of a line, so the dollar metacharacter\r
+should not match it nor (except in multiline mode) a newline immediately before\r
+it. Setting this without PCRE_MULTILINE (at compile time) causes dollar never\r
+to match.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_NOTEMPTY\r
+</PRE>\r
+</P>\r
+<P>\r
+An empty string is not considered to be a valid match if this option is set. If\r
+there are alternatives in the pattern, they are tried. If all the alternatives\r
+match the empty string, the entire match fails. For example, if the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  a?b?\r
+</PRE>\r
+</P>\r
+<P>\r
+is applied to a string not beginning with "a" or "b", it matches the empty\r
+string at the start of the subject. With PCRE_NOTEMPTY set, this match is not\r
+valid, so PCRE searches further into the string for occurrences of "a" or "b".\r
+</P>\r
+<P>\r
+Perl has no direct equivalent of PCRE_NOTEMPTY, but it does make a special case\r
+of a pattern match of the empty string within its <B>split()</B> function, and\r
+when using the /g modifier. It is possible to emulate Perl's behaviour after\r
+matching a null string by first trying the match again at the same offset with\r
+PCRE_NOTEMPTY set, and then if that fails by advancing the starting offset (see\r
+below) and trying an ordinary match again.\r
+</P>\r
+<P>\r
+The subject string is passed as a pointer in <I>subject</I>, a length in\r
+<I>length</I>, and a starting offset in <I>startoffset</I>. Unlike the pattern\r
+string, it may contain binary zero characters. When the starting offset is\r
+zero, the search for a match starts at the beginning of the subject, and this\r
+is by far the most common case.\r
+</P>\r
+<P>\r
+A non-zero starting offset is useful when searching for another match in the\r
+same subject by calling <B>pcre_exec()</B> again after a previous success.\r
+Setting <I>startoffset</I> differs from just passing over a shortened string and\r
+setting PCRE_NOTBOL in the case of a pattern that begins with any kind of\r
+lookbehind. For example, consider the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  \Biss\B\r
+</PRE>\r
+</P>\r
+<P>\r
+which finds occurrences of "iss" in the middle of words. (\B matches only if\r
+the current position in the subject is not a word boundary.) When applied to\r
+the string "Mississipi" the first call to <B>pcre_exec()</B> finds the first\r
+occurrence. If <B>pcre_exec()</B> is called again with just the remainder of the\r
+subject, namely "issipi", it does not match, because \B is always false at the\r
+start of the subject, which is deemed to be a word boundary. However, if\r
+<B>pcre_exec()</B> is passed the entire string again, but with <I>startoffset</I>\r
+set to 4, it finds the second occurrence of "iss" because it is able to look\r
+behind the starting point to discover that it is preceded by a letter.\r
+</P>\r
+<P>\r
+If a non-zero starting offset is passed when the pattern is anchored, one\r
+attempt to match at the given offset is tried. This can only succeed if the\r
+pattern does not require the match to be at the start of the subject.\r
+</P>\r
+<P>\r
+In general, a pattern matches a certain portion of the subject, and in\r
+addition, further substrings from the subject may be picked out by parts of the\r
+pattern. Following the usage in Jeffrey Friedl's book, this is called\r
+"capturing" in what follows, and the phrase "capturing subpattern" is used for\r
+a fragment of a pattern that picks out a substring. PCRE supports several other\r
+kinds of parenthesized subpattern that do not cause substrings to be captured.\r
+</P>\r
+<P>\r
+Captured substrings are returned to the caller via a vector of integer offsets\r
+whose address is passed in <I>ovector</I>. The number of elements in the vector\r
+is passed in <I>ovecsize</I>. The first two-thirds of the vector is used to pass\r
+back captured substrings, each substring using a pair of integers. The\r
+remaining third of the vector is used as workspace by <B>pcre_exec()</B> while\r
+matching capturing subpatterns, and is not available for passing back\r
+information. The length passed in <I>ovecsize</I> should always be a multiple of\r
+three. If it is not, it is rounded down.\r
+</P>\r
+<P>\r
+When a match has been successful, information about captured substrings is\r
+returned in pairs of integers, starting at the beginning of <I>ovector</I>, and\r
+continuing up to two-thirds of its length at the most. The first element of a\r
+pair is set to the offset of the first character in a substring, and the second\r
+is set to the offset of the first character after the end of a substring. The\r
+first pair, <I>ovector[0]</I> and <I>ovector[1]</I>, identify the portion of the\r
+subject string matched by the entire pattern. The next pair is used for the\r
+first capturing subpattern, and so on. The value returned by <B>pcre_exec()</B>\r
+is the number of pairs that have been set. If there are no capturing\r
+subpatterns, the return value from a successful match is 1, indicating that\r
+just the first pair of offsets has been set.\r
+</P>\r
+<P>\r
+Some convenience functions are provided for extracting the captured substrings\r
+as separate strings. These are described in the following section.\r
+</P>\r
+<P>\r
+It is possible for an capturing subpattern number <I>n+1</I> to match some\r
+part of the subject when subpattern <I>n</I> has not been used at all. For\r
+example, if the string "abc" is matched against the pattern (a|(z))(bc)\r
+subpatterns 1 and 3 are matched, but 2 is not. When this happens, both offset\r
+values corresponding to the unused subpattern are set to -1.\r
+</P>\r
+<P>\r
+If a capturing subpattern is matched repeatedly, it is the last portion of the\r
+string that it matched that gets returned.\r
+</P>\r
+<P>\r
+If the vector is too small to hold all the captured substrings, it is used as\r
+far as possible (up to two-thirds of its length), and the function returns a\r
+value of zero. In particular, if the substring offsets are not of interest,\r
+<B>pcre_exec()</B> may be called with <I>ovector</I> passed as NULL and\r
+<I>ovecsize</I> as zero. However, if the pattern contains back references and\r
+the <I>ovector</I> isn't big enough to remember the related substrings, PCRE has\r
+to get additional memory for use during matching. Thus it is usually advisable\r
+to supply an <I>ovector</I>.\r
+</P>\r
+<P>\r
+Note that <B>pcre_info()</B> can be used to find out how many capturing\r
+subpatterns there are in a compiled pattern. The smallest size for\r
+<I>ovector</I> that will allow for <I>n</I> captured substrings in addition to\r
+the offsets of the substring matched by the whole pattern is (<I>n</I>+1)*3.\r
+</P>\r
+<P>\r
+If <B>pcre_exec()</B> fails, it returns a negative number. The following are\r
+defined in the header file:\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NOMATCH        (-1)\r
+</PRE>\r
+</P>\r
+<P>\r
+The subject string did not match the pattern.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NULL           (-2)\r
+</PRE>\r
+</P>\r
+<P>\r
+Either <I>code</I> or <I>subject</I> was passed as NULL, or <I>ovector</I> was\r
+NULL and <I>ovecsize</I> was not zero.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_BADOPTION      (-3)\r
+</PRE>\r
+</P>\r
+<P>\r
+An unrecognized bit was set in the <I>options</I> argument.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_BADMAGIC       (-4)\r
+</PRE>\r
+</P>\r
+<P>\r
+PCRE stores a 4-byte "magic number" at the start of the compiled code, to catch\r
+the case when it is passed a junk pointer. This is the error it gives when the\r
+magic number isn't present.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_UNKNOWN_NODE   (-5)\r
+</PRE>\r
+</P>\r
+<P>\r
+While running the pattern match, an unknown item was encountered in the\r
+compiled pattern. This error could be caused by a bug in PCRE or by overwriting\r
+of the compiled pattern.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NOMEMORY       (-6)\r
+</PRE>\r
+</P>\r
+<P>\r
+If a pattern contains back references, but the <I>ovector</I> that is passed to\r
+<B>pcre_exec()</B> is not big enough to remember the referenced substrings, PCRE\r
+gets a block of memory at the start of matching to use for this purpose. If the\r
+call via <B>pcre_malloc()</B> fails, this error is given. The memory is freed at\r
+the end of matching.\r
+</P>\r
+<LI><A NAME="SEC10" HREF="#TOC1">EXTRACTING CAPTURED SUBSTRINGS</A>\r
+<P>\r
+Captured substrings can be accessed directly by using the offsets returned by\r
+<B>pcre_exec()</B> in <I>ovector</I>. For convenience, the functions\r
+<B>pcre_copy_substring()</B>, <B>pcre_get_substring()</B>, and\r
+<B>pcre_get_substring_list()</B> are provided for extracting captured substrings\r
+as new, separate, zero-terminated strings. A substring that contains a binary\r
+zero is correctly extracted and has a further zero added on the end, but the\r
+result does not, of course, function as a C string.\r
+</P>\r
+<P>\r
+The first three arguments are the same for all three functions: <I>subject</I>\r
+is the subject string which has just been successfully matched, <I>ovector</I>\r
+is a pointer to the vector of integer offsets that was passed to\r
+<B>pcre_exec()</B>, and <I>stringcount</I> is the number of substrings that\r
+were captured by the match, including the substring that matched the entire\r
+regular expression. This is the value returned by <B>pcre_exec</B> if it\r
+is greater than zero. If <B>pcre_exec()</B> returned zero, indicating that it\r
+ran out of space in <I>ovector</I>, the value passed as <I>stringcount</I> should\r
+be the size of the vector divided by three.\r
+</P>\r
+<P>\r
+The functions <B>pcre_copy_substring()</B> and <B>pcre_get_substring()</B>\r
+extract a single substring, whose number is given as <I>stringnumber</I>. A\r
+value of zero extracts the substring that matched the entire pattern, while\r
+higher values extract the captured substrings. For <B>pcre_copy_substring()</B>,\r
+the string is placed in <I>buffer</I>, whose length is given by\r
+<I>buffersize</I>, while for <B>pcre_get_substring()</B> a new block of memory is\r
+obtained via <B>pcre_malloc</B>, and its address is returned via\r
+<I>stringptr</I>. The yield of the function is the length of the string, not\r
+including the terminating zero, or one of\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NOMEMORY       (-6)\r
+</PRE>\r
+</P>\r
+<P>\r
+The buffer was too small for <B>pcre_copy_substring()</B>, or the attempt to get\r
+memory failed for <B>pcre_get_substring()</B>.\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NOSUBSTRING    (-7)\r
+</PRE>\r
+</P>\r
+<P>\r
+There is no substring whose number is <I>stringnumber</I>.\r
+</P>\r
+<P>\r
+The <B>pcre_get_substring_list()</B> function extracts all available substrings\r
+and builds a list of pointers to them. All this is done in a single block of\r
+memory which is obtained via <B>pcre_malloc</B>. The address of the memory block\r
+is returned via <I>listptr</I>, which is also the start of the list of string\r
+pointers. The end of the list is marked by a NULL pointer. The yield of the\r
+function is zero if all went well, or\r
+</P>\r
+<P>\r
+<PRE>\r
+  PCRE_ERROR_NOMEMORY       (-6)\r
+</PRE>\r
+</P>\r
+<P>\r
+if the attempt to get the memory block failed.\r
+</P>\r
+<P>\r
+When any of these functions encounter a substring that is unset, which can\r
+happen when capturing subpattern number <I>n+1</I> matches some part of the\r
+subject, but subpattern <I>n</I> has not been used at all, they return an empty\r
+string. This can be distinguished from a genuine zero-length substring by\r
+inspecting the appropriate offset in <I>ovector</I>, which is negative for unset\r
+substrings.\r
+</P>\r
+<P>\r
+The two convenience functions <B>pcre_free_substring()</B> and\r
+<B>pcre_free_substring_list()</B> can be used to free the memory returned by\r
+a previous call of <B>pcre_get_substring()</B> or\r
+<B>pcre_get_substring_list()</B>, respectively. They do nothing more than call\r
+the function pointed to by <B>pcre_free</B>, which of course could be called\r
+directly from a C program. However, PCRE is used in some situations where it is\r
+linked via a special interface to another programming language which cannot use\r
+<B>pcre_free</B> directly; it is for these cases that the functions are\r
+provided.\r
+</P>\r
+<LI><A NAME="SEC11" HREF="#TOC1">LIMITATIONS</A>\r
+<P>\r
+There are some size limitations in PCRE but it is hoped that they will never in\r
+practice be relevant.\r
+The maximum length of a compiled pattern is 65539 (sic) bytes.\r
+All values in repeating quantifiers must be less than 65536.\r
+The maximum number of capturing subpatterns is 99.\r
+The maximum number of all parenthesized subpatterns, including capturing\r
+subpatterns, assertions, and other types of subpattern, is 200.\r
+</P>\r
+<P>\r
+The maximum length of a subject string is the largest positive number that an\r
+integer variable can hold. However, PCRE uses recursion to handle subpatterns\r
+and indefinite repetition. This means that the available stack space may limit\r
+the size of a subject string that can be processed by certain patterns.\r
+</P>\r
+<LI><A NAME="SEC12" HREF="#TOC1">DIFFERENCES FROM PERL</A>\r
+<P>\r
+The differences described here are with respect to Perl 5.005.\r
+</P>\r
+<P>\r
+1. By default, a whitespace character is any character that the C library\r
+function <B>isspace()</B> recognizes, though it is possible to compile PCRE with\r
+alternative character type tables. Normally <B>isspace()</B> matches space,\r
+formfeed, newline, carriage return, horizontal tab, and vertical tab. Perl 5\r
+no longer includes vertical tab in its set of whitespace characters. The \v\r
+escape that was in the Perl documentation for a long time was never in fact\r
+recognized. However, the character itself was treated as whitespace at least\r
+up to 5.002. In 5.004 and 5.005 it does not match \s.\r
+</P>\r
+<P>\r
+2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl permits\r
+them, but they do not mean what you might think. For example, (?!a){3} does\r
+not assert that the next three characters are not "a". It just asserts that the\r
+next character is not "a" three times.\r
+</P>\r
+<P>\r
+3. Capturing subpatterns that occur inside negative lookahead assertions are\r
+counted, but their entries in the offsets vector are never set. Perl sets its\r
+numerical variables from any such patterns that are matched before the\r
+assertion fails to match something (thereby succeeding), but only if the\r
+negative lookahead assertion contains just one branch.\r
+</P>\r
+<P>\r
+4. Though binary zero characters are supported in the subject string, they are\r
+not allowed in a pattern string because it is passed as a normal C string,\r
+terminated by zero. The escape sequence "\0" can be used in the pattern to\r
+represent a binary zero.\r
+</P>\r
+<P>\r
+5. The following Perl escape sequences are not supported: \l, \u, \L, \U,\r
+\E, \Q. In fact these are implemented by Perl's general string-handling and\r
+are not part of its pattern matching engine.\r
+</P>\r
+<P>\r
+6. The Perl \G assertion is not supported as it is not relevant to single\r
+pattern matches.\r
+</P>\r
+<P>\r
+7. Fairly obviously, PCRE does not support the (?{code}) and (?p{code})\r
+constructions. However, there is some experimental support for recursive\r
+patterns using the non-Perl item (?R).\r
+</P>\r
+<P>\r
+8. There are at the time of writing some oddities in Perl 5.005_02 concerned\r
+with the settings of captured strings when part of a pattern is repeated. For\r
+example, matching "aba" against the pattern /^(a(b)?)+$/ sets $2 to the value\r
+"b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves $2 unset. However, if\r
+the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) are set.\r
+</P>\r
+<P>\r
+In Perl 5.004 $2 is set in both cases, and that is also true of PCRE. If in the\r
+future Perl changes to a consistent state that is different, PCRE may change to\r
+follow.\r
+</P>\r
+<P>\r
+9. Another as yet unresolved discrepancy is that in Perl 5.005_02 the pattern\r
+/^(a)?(?(1)a|b)+$/ matches the string "a", whereas in PCRE it does not.\r
+However, in both Perl and PCRE /^(a)?a/ matched against "a" leaves $1 unset.\r
+</P>\r
+<P>\r
+10. PCRE provides some extensions to the Perl regular expression facilities:\r
+</P>\r
+<P>\r
+(a) Although lookbehind assertions must match fixed length strings, each\r
+alternative branch of a lookbehind assertion can match a different length of\r
+string. Perl 5.005 requires them all to have the same length.\r
+</P>\r
+<P>\r
+(b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ meta-\r
+character matches only at the very end of the string.\r
+</P>\r
+<P>\r
+(c) If PCRE_EXTRA is set, a backslash followed by a letter with no special\r
+meaning is faulted.\r
+</P>\r
+<P>\r
+(d) If PCRE_UNGREEDY is set, the greediness of the repetition quantifiers is\r
+inverted, that is, by default they are not greedy, but if followed by a\r
+question mark they are.\r
+</P>\r
+<P>\r
+(e) PCRE_ANCHORED can be used to force a pattern to be tried only at the start\r
+of the subject.\r
+</P>\r
+<P>\r
+(f) The PCRE_NOTBOL, PCRE_NOTEOL, and PCRE_NOTEMPTY options for\r
+<B>pcre_exec()</B> have no Perl equivalents.\r
+</P>\r
+<P>\r
+(g) The (?R) construct allows for recursive pattern matching (Perl 5.6 can do\r
+this using the (?p{code}) construct, which PCRE cannot of course support.)\r
+</P>\r
+<LI><A NAME="SEC13" HREF="#TOC1">REGULAR EXPRESSION DETAILS</A>\r
+<P>\r
+The syntax and semantics of the regular expressions supported by PCRE are\r
+described below. Regular expressions are also described in the Perl\r
+documentation and in a number of other books, some of which have copious\r
+examples. Jeffrey Friedl's "Mastering Regular Expressions", published by\r
+O'Reilly (ISBN 1-56592-257), covers them in great detail.\r
+</P>\r
+<P>\r
+The description here is intended as reference documentation. The basic\r
+operation of PCRE is on strings of bytes. However, there is the beginnings of\r
+some support for UTF-8 character strings. To use this support you must\r
+configure PCRE to include it, and then call <B>pcre_compile()</B> with the\r
+PCRE_UTF8 option. How this affects the pattern matching is described in the\r
+final section of this document.\r
+</P>\r
+<P>\r
+A regular expression is a pattern that is matched against a subject string from\r
+left to right. Most characters stand for themselves in a pattern, and match the\r
+corresponding characters in the subject. As a trivial example, the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  The quick brown fox\r
+</PRE>\r
+</P>\r
+<P>\r
+matches a portion of a subject string that is identical to itself. The power of\r
+regular expressions comes from the ability to include alternatives and\r
+repetitions in the pattern. These are encoded in the pattern by the use of\r
+<I>meta-characters</I>, which do not stand for themselves but instead are\r
+interpreted in some special way.\r
+</P>\r
+<P>\r
+There are two different sets of meta-characters: those that are recognized\r
+anywhere in the pattern except within square brackets, and those that are\r
+recognized in square brackets. Outside square brackets, the meta-characters are\r
+as follows:\r
+</P>\r
+<P>\r
+<PRE>\r
+  \      general escape character with several uses\r
+  ^      assert start of subject (or line, in multiline mode)\r
+  $      assert end of subject (or line, in multiline mode)\r
+  .      match any character except newline (by default)\r
+  [      start character class definition\r
+  |      start of alternative branch\r
+  (      start subpattern\r
+  )      end subpattern\r
+  ?      extends the meaning of (\r
+         also 0 or 1 quantifier\r
+         also quantifier minimizer\r
+  *      0 or more quantifier\r
+  +      1 or more quantifier\r
+  {      start min/max quantifier\r
+</PRE>\r
+</P>\r
+<P>\r
+Part of a pattern that is in square brackets is called a "character class". In\r
+a character class the only meta-characters are:\r
+</P>\r
+<P>\r
+<PRE>\r
+  \      general escape character\r
+  ^      negate the class, but only if the first character\r
+  -      indicates character range\r
+  ]      terminates the character class\r
+</PRE>\r
+</P>\r
+<P>\r
+The following sections describe the use of each of the meta-characters.\r
+</P>\r
+<LI><A NAME="SEC14" HREF="#TOC1">BACKSLASH</A>\r
+<P>\r
+The backslash character has several uses. Firstly, if it is followed by a\r
+non-alphameric character, it takes away any special meaning that character may\r
+have. This use of backslash as an escape character applies both inside and\r
+outside character classes.\r
+</P>\r
+<P>\r
+For example, if you want to match a "*" character, you write "\*" in the\r
+pattern. This applies whether or not the following character would otherwise be\r
+interpreted as a meta-character, so it is always safe to precede a\r
+non-alphameric with "\" to specify that it stands for itself. In particular,\r
+if you want to match a backslash, you write "\\".\r
+</P>\r
+<P>\r
+If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the\r
+pattern (other than in a character class) and characters between a "#" outside\r
+a character class and the next newline character are ignored. An escaping\r
+backslash can be used to include a whitespace or "#" character as part of the\r
+pattern.\r
+</P>\r
+<P>\r
+A second use of backslash provides a way of encoding non-printing characters\r
+in patterns in a visible manner. There is no restriction on the appearance of\r
+non-printing characters, apart from the binary zero that terminates a pattern,\r
+but when a pattern is being prepared by text editing, it is usually easier to\r
+use one of the following escape sequences than the binary character it\r
+represents:\r
+</P>\r
+<P>\r
+<PRE>\r
+  \a     alarm, that is, the BEL character (hex 07)\r
+  \cx    "control-x", where x is any character\r
+  \e     escape (hex 1B)\r
+  \f     formfeed (hex 0C)\r
+  \n     newline (hex 0A)\r
+  \r     carriage return (hex 0D)\r
+  \t     tab (hex 09)\r
+  \xhh   character with hex code hh\r
+  \ddd   character with octal code ddd, or backreference\r
+</PRE>\r
+</P>\r
+<P>\r
+The precise effect of "\cx" is as follows: if "x" is a lower case letter, it\r
+is converted to upper case. Then bit 6 of the character (hex 40) is inverted.\r
+Thus "\cz" becomes hex 1A, but "\c{" becomes hex 3B, while "\c;" becomes hex\r
+7B.\r
+</P>\r
+<P>\r
+After "\x", up to two hexadecimal digits are read (letters can be in upper or\r
+lower case).\r
+</P>\r
+<P>\r
+After "\0" up to two further octal digits are read. In both cases, if there\r
+are fewer than two digits, just those that are present are used. Thus the\r
+sequence "\0\x\07" specifies two binary zeros followed by a BEL character.\r
+Make sure you supply two digits after the initial zero if the character that\r
+follows is itself an octal digit.\r
+</P>\r
+<P>\r
+The handling of a backslash followed by a digit other than 0 is complicated.\r
+Outside a character class, PCRE reads it and any following digits as a decimal\r
+number. If the number is less than 10, or if there have been at least that many\r
+previous capturing left parentheses in the expression, the entire sequence is\r
+taken as a <I>back reference</I>. A description of how this works is given\r
+later, following the discussion of parenthesized subpatterns.\r
+</P>\r
+<P>\r
+Inside a character class, or if the decimal number is greater than 9 and there\r
+have not been that many capturing subpatterns, PCRE re-reads up to three octal\r
+digits following the backslash, and generates a single byte from the least\r
+significant 8 bits of the value. Any subsequent digits stand for themselves.\r
+For example:\r
+</P>\r
+<P>\r
+<PRE>\r
+  \040   is another way of writing a space\r
+  \40    is the same, provided there are fewer than 40\r
+            previous capturing subpatterns\r
+  \7     is always a back reference\r
+  \11    might be a back reference, or another way of\r
+            writing a tab\r
+  \011   is always a tab\r
+  \0113  is a tab followed by the character "3"\r
+  \113   is the character with octal code 113 (since there\r
+            can be no more than 99 back references)\r
+  \377   is a byte consisting entirely of 1 bits\r
+  \81    is either a back reference, or a binary zero\r
+            followed by the two characters "8" and "1"\r
+</PRE>\r
+</P>\r
+<P>\r
+Note that octal values of 100 or greater must not be introduced by a leading\r
+zero, because no more than three octal digits are ever read.\r
+</P>\r
+<P>\r
+All the sequences that define a single byte value can be used both inside and\r
+outside character classes. In addition, inside a character class, the sequence\r
+"\b" is interpreted as the backspace character (hex 08). Outside a character\r
+class it has a different meaning (see below).\r
+</P>\r
+<P>\r
+The third use of backslash is for specifying generic character types:\r
+</P>\r
+<P>\r
+<PRE>\r
+  \d     any decimal digit\r
+  \D     any character that is not a decimal digit\r
+  \s     any whitespace character\r
+  \S     any character that is not a whitespace character\r
+  \w     any "word" character\r
+  \W     any "non-word" character\r
+</PRE>\r
+</P>\r
+<P>\r
+Each pair of escape sequences partitions the complete set of characters into\r
+two disjoint sets. Any given character matches one, and only one, of each pair.\r
+</P>\r
+<P>\r
+A "word" character is any letter or digit or the underscore character, that is,\r
+any character which can be part of a Perl "word". The definition of letters and\r
+digits is controlled by PCRE's character tables, and may vary if locale-\r
+specific matching is taking place (see "Locale support" above). For example, in\r
+the "fr" (French) locale, some character codes greater than 128 are used for\r
+accented letters, and these are matched by \w.\r
+</P>\r
+<P>\r
+These character type sequences can appear both inside and outside character\r
+classes. They each match one character of the appropriate type. If the current\r
+matching point is at the end of the subject string, all of them fail, since\r
+there is no character to match.\r
+</P>\r
+<P>\r
+The fourth use of backslash is for certain simple assertions. An assertion\r
+specifies a condition that has to be met at a particular point in a match,\r
+without consuming any characters from the subject string. The use of\r
+subpatterns for more complicated assertions is described below. The backslashed\r
+assertions are\r
+</P>\r
+<P>\r
+<PRE>\r
+  \b     word boundary\r
+  \B     not a word boundary\r
+  \A     start of subject (independent of multiline mode)\r
+  \Z     end of subject or newline at end (independent of multiline mode)\r
+  \z     end of subject (independent of multiline mode)\r
+</PRE>\r
+</P>\r
+<P>\r
+These assertions may not appear in character classes (but note that "\b" has a\r
+different meaning, namely the backspace character, inside a character class).\r
+</P>\r
+<P>\r
+A word boundary is a position in the subject string where the current character\r
+and the previous character do not both match \w or \W (i.e. one matches\r
+\w and the other matches \W), or the start or end of the string if the\r
+first or last character matches \w, respectively.\r
+</P>\r
+<P>\r
+The \A, \Z, and \z assertions differ from the traditional circumflex and\r
+dollar (described below) in that they only ever match at the very start and end\r
+of the subject string, whatever options are set. They are not affected by the\r
+PCRE_NOTBOL or PCRE_NOTEOL options. If the <I>startoffset</I> argument of\r
+<B>pcre_exec()</B> is non-zero, \A can never match. The difference between \Z\r
+and \z is that \Z matches before a newline that is the last character of the\r
+string as well as at the end of the string, whereas \z matches only at the\r
+end.\r
+</P>\r
+<LI><A NAME="SEC15" HREF="#TOC1">CIRCUMFLEX AND DOLLAR</A>\r
+<P>\r
+Outside a character class, in the default matching mode, the circumflex\r
+character is an assertion which is true only if the current matching point is\r
+at the start of the subject string. If the <I>startoffset</I> argument of\r
+<B>pcre_exec()</B> is non-zero, circumflex can never match. Inside a character\r
+class, circumflex has an entirely different meaning (see below).\r
+</P>\r
+<P>\r
+Circumflex need not be the first character of the pattern if a number of\r
+alternatives are involved, but it should be the first thing in each alternative\r
+in which it appears if the pattern is ever to match that branch. If all\r
+possible alternatives start with a circumflex, that is, if the pattern is\r
+constrained to match only at the start of the subject, it is said to be an\r
+"anchored" pattern. (There are also other constructs that can cause a pattern\r
+to be anchored.)\r
+</P>\r
+<P>\r
+A dollar character is an assertion which is true only if the current matching\r
+point is at the end of the subject string, or immediately before a newline\r
+character that is the last character in the string (by default). Dollar need\r
+not be the last character of the pattern if a number of alternatives are\r
+involved, but it should be the last item in any branch in which it appears.\r
+Dollar has no special meaning in a character class.\r
+</P>\r
+<P>\r
+The meaning of dollar can be changed so that it matches only at the very end of\r
+the string, by setting the PCRE_DOLLAR_ENDONLY option at compile or matching\r
+time. This does not affect the \Z assertion.\r
+</P>\r
+<P>\r
+The meanings of the circumflex and dollar characters are changed if the\r
+PCRE_MULTILINE option is set. When this is the case, they match immediately\r
+after and immediately before an internal "\n" character, respectively, in\r
+addition to matching at the start and end of the subject string. For example,\r
+the pattern /^abc$/ matches the subject string "def\nabc" in multiline mode,\r
+but not otherwise. Consequently, patterns that are anchored in single line mode\r
+because all branches start with "^" are not anchored in multiline mode, and a\r
+match for circumflex is possible when the <I>startoffset</I> argument of\r
+<B>pcre_exec()</B> is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if\r
+PCRE_MULTILINE is set.\r
+</P>\r
+<P>\r
+Note that the sequences \A, \Z, and \z can be used to match the start and\r
+end of the subject in both modes, and if all branches of a pattern start with\r
+\A is it always anchored, whether PCRE_MULTILINE is set or not.\r
+</P>\r
+<LI><A NAME="SEC16" HREF="#TOC1">FULL STOP (PERIOD, DOT)</A>\r
+<P>\r
+Outside a character class, a dot in the pattern matches any one character in\r
+the subject, including a non-printing character, but not (by default) newline.\r
+If the PCRE_DOTALL option is set, dots match newlines as well. The handling of\r
+dot is entirely independent of the handling of circumflex and dollar, the only\r
+relationship being that they both involve newline characters. Dot has no\r
+special meaning in a character class.\r
+</P>\r
+<LI><A NAME="SEC17" HREF="#TOC1">SQUARE BRACKETS</A>\r
+<P>\r
+An opening square bracket introduces a character class, terminated by a closing\r
+square bracket. A closing square bracket on its own is not special. If a\r
+closing square bracket is required as a member of the class, it should be the\r
+first data character in the class (after an initial circumflex, if present) or\r
+escaped with a backslash.\r
+</P>\r
+<P>\r
+A character class matches a single character in the subject; the character must\r
+be in the set of characters defined by the class, unless the first character in\r
+the class is a circumflex, in which case the subject character must not be in\r
+the set defined by the class. If a circumflex is actually required as a member\r
+of the class, ensure it is not the first character, or escape it with a\r
+backslash.\r
+</P>\r
+<P>\r
+For example, the character class [aeiou] matches any lower case vowel, while\r
+[^aeiou] matches any character that is not a lower case vowel. Note that a\r
+circumflex is just a convenient notation for specifying the characters which\r
+are in the class by enumerating those that are not. It is not an assertion: it\r
+still consumes a character from the subject string, and fails if the current\r
+pointer is at the end of the string.\r
+</P>\r
+<P>\r
+When caseless matching is set, any letters in a class represent both their\r
+upper case and lower case versions, so for example, a caseless [aeiou] matches\r
+"A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a\r
+caseful version would.\r
+</P>\r
+<P>\r
+The newline character is never treated in any special way in character classes,\r
+whatever the setting of the PCRE_DOTALL or PCRE_MULTILINE options is. A class\r
+such as [^a] will always match a newline.\r
+</P>\r
+<P>\r
+The minus (hyphen) character can be used to specify a range of characters in a\r
+character class. For example, [d-m] matches any letter between d and m,\r
+inclusive. If a minus character is required in a class, it must be escaped with\r
+a backslash or appear in a position where it cannot be interpreted as\r
+indicating a range, typically as the first or last character in the class.\r
+</P>\r
+<P>\r
+It is not possible to have the literal character "]" as the end character of a\r
+range. A pattern such as [W-]46] is interpreted as a class of two characters\r
+("W" and "-") followed by a literal string "46]", so it would match "W46]" or\r
+"-46]". However, if the "]" is escaped with a backslash it is interpreted as\r
+the end of range, so [W-\]46] is interpreted as a single class containing a\r
+range followed by two separate characters. The octal or hexadecimal\r
+representation of "]" can also be used to end a range.\r
+</P>\r
+<P>\r
+Ranges operate in ASCII collating sequence. They can also be used for\r
+characters specified numerically, for example [\000-\037]. If a range that\r
+includes letters is used when caseless matching is set, it matches the letters\r
+in either case. For example, [W-c] is equivalent to [][\^_`wxyzabc], matched\r
+caselessly, and if character tables for the "fr" locale are in use,\r
+[\xc8-\xcb] matches accented E characters in both cases.\r
+</P>\r
+<P>\r
+The character types \d, \D, \s, \S, \w, and \W may also appear in a\r
+character class, and add the characters that they match to the class. For\r
+example, [\dABCDEF] matches any hexadecimal digit. A circumflex can\r
+conveniently be used with the upper case character types to specify a more\r
+restricted set of characters than the matching lower case type. For example,\r
+the class [^\W_] matches any letter or digit, but not underscore.\r
+</P>\r
+<P>\r
+All non-alphameric characters other than \, -, ^ (at the start) and the\r
+terminating ] are non-special in character classes, but it does no harm if they\r
+are escaped.\r
+</P>\r
+<LI><A NAME="SEC18" HREF="#TOC1">POSIX CHARACTER CLASSES</A>\r
+<P>\r
+Perl 5.6 (not yet released at the time of writing) is going to support the\r
+POSIX notation for character classes, which uses names enclosed by [: and :]\r
+within the enclosing square brackets. PCRE supports this notation. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  [01[:alpha:]%]\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "0", "1", any alphabetic character, or "%". The supported class names\r
+are\r
+</P>\r
+<P>\r
+<PRE>\r
+  alnum    letters and digits\r
+  alpha    letters\r
+  ascii    character codes 0 - 127\r
+  cntrl    control characters\r
+  digit    decimal digits (same as \d)\r
+  graph    printing characters, excluding space\r
+  lower    lower case letters\r
+  print    printing characters, including space\r
+  punct    printing characters, excluding letters and digits\r
+  space    white space (same as \s)\r
+  upper    upper case letters\r
+  word     "word" characters (same as \w)\r
+  xdigit   hexadecimal digits\r
+</PRE>\r
+</P>\r
+<P>\r
+The names "ascii" and "word" are Perl extensions. Another Perl extension is\r
+negation, which is indicated by a ^ character after the colon. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  [12[:^digit:]]\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "1", "2", or any non-digit. PCRE (and Perl) also recogize the POSIX\r
+syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not\r
+supported, and an error is given if they are encountered.\r
+</P>\r
+<LI><A NAME="SEC19" HREF="#TOC1">VERTICAL BAR</A>\r
+<P>\r
+Vertical bar characters are used to separate alternative patterns. For example,\r
+the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  gilbert|sullivan\r
+</PRE>\r
+</P>\r
+<P>\r
+matches either "gilbert" or "sullivan". Any number of alternatives may appear,\r
+and an empty alternative is permitted (matching the empty string).\r
+The matching process tries each alternative in turn, from left to right,\r
+and the first one that succeeds is used. If the alternatives are within a\r
+subpattern (defined below), "succeeds" means matching the rest of the main\r
+pattern as well as the alternative in the subpattern.\r
+</P>\r
+<LI><A NAME="SEC20" HREF="#TOC1">INTERNAL OPTION SETTING</A>\r
+<P>\r
+The settings of PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and PCRE_EXTENDED\r
+can be changed from within the pattern by a sequence of Perl option letters\r
+enclosed between "(?" and ")". The option letters are\r
+</P>\r
+<P>\r
+<PRE>\r
+  i  for PCRE_CASELESS\r
+  m  for PCRE_MULTILINE\r
+  s  for PCRE_DOTALL\r
+  x  for PCRE_EXTENDED\r
+</PRE>\r
+</P>\r
+<P>\r
+For example, (?im) sets caseless, multiline matching. It is also possible to\r
+unset these options by preceding the letter with a hyphen, and a combined\r
+setting and unsetting such as (?im-sx), which sets PCRE_CASELESS and\r
+PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, is also\r
+permitted. If a letter appears both before and after the hyphen, the option is\r
+unset.\r
+</P>\r
+<P>\r
+The scope of these option changes depends on where in the pattern the setting\r
+occurs. For settings that are outside any subpattern (defined below), the\r
+effect is the same as if the options were set or unset at the start of\r
+matching. The following patterns all behave in exactly the same way:\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?i)abc\r
+  a(?i)bc\r
+  ab(?i)c\r
+  abc(?i)\r
+</PRE>\r
+</P>\r
+<P>\r
+which in turn is the same as compiling the pattern abc with PCRE_CASELESS set.\r
+In other words, such "top level" settings apply to the whole pattern (unless\r
+there are other changes inside subpatterns). If there is more than one setting\r
+of the same option at top level, the rightmost setting is used.\r
+</P>\r
+<P>\r
+If an option change occurs inside a subpattern, the effect is different. This\r
+is a change of behaviour in Perl 5.005. An option change inside a subpattern\r
+affects only that part of the subpattern that follows it, so\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a(?i)b)c\r
+</PRE>\r
+</P>\r
+<P>\r
+matches abc and aBc and no other strings (assuming PCRE_CASELESS is not used).\r
+By this means, options can be made to have different settings in different\r
+parts of the pattern. Any changes made in one alternative do carry on\r
+into subsequent branches within the same subpattern. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a(?i)b|c)\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "ab", "aB", "c", and "C", even though when matching "C" the first\r
+branch is abandoned before the option setting. This is because the effects of\r
+option settings happen at compile time. There would be some very weird\r
+behaviour otherwise.\r
+</P>\r
+<P>\r
+The PCRE-specific options PCRE_UNGREEDY and PCRE_EXTRA can be changed in the\r
+same way as the Perl-compatible options by using the characters U and X\r
+respectively. The (?X) flag setting is special in that it must always occur\r
+earlier in the pattern than any of the additional features it turns on, even\r
+when it is at top level. It is best put at the start.\r
+</P>\r
+<LI><A NAME="SEC21" HREF="#TOC1">SUBPATTERNS</A>\r
+<P>\r
+Subpatterns are delimited by parentheses (round brackets), which can be nested.\r
+Marking part of a pattern as a subpattern does two things:\r
+</P>\r
+<P>\r
+1. It localizes a set of alternatives. For example, the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  cat(aract|erpillar|)\r
+</PRE>\r
+</P>\r
+<P>\r
+matches one of the words "cat", "cataract", or "caterpillar". Without the\r
+parentheses, it would match "cataract", "erpillar" or the empty string.\r
+</P>\r
+<P>\r
+2. It sets up the subpattern as a capturing subpattern (as defined above).\r
+When the whole pattern matches, that portion of the subject string that matched\r
+the subpattern is passed back to the caller via the <I>ovector</I> argument of\r
+<B>pcre_exec()</B>. Opening parentheses are counted from left to right (starting\r
+from 1) to obtain the numbers of the capturing subpatterns.\r
+</P>\r
+<P>\r
+For example, if the string "the red king" is matched against the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  the ((red|white) (king|queen))\r
+</PRE>\r
+</P>\r
+<P>\r
+the captured substrings are "red king", "red", and "king", and are numbered 1,\r
+2, and 3.\r
+</P>\r
+<P>\r
+The fact that plain parentheses fulfil two functions is not always helpful.\r
+There are often times when a grouping subpattern is required without a\r
+capturing requirement. If an opening parenthesis is followed by "?:", the\r
+subpattern does not do any capturing, and is not counted when computing the\r
+number of any subsequent capturing subpatterns. For example, if the string "the\r
+white queen" is matched against the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  the ((?:red|white) (king|queen))\r
+</PRE>\r
+</P>\r
+<P>\r
+the captured substrings are "white queen" and "queen", and are numbered 1 and\r
+2. The maximum number of captured substrings is 99, and the maximum number of\r
+all subpatterns, both capturing and non-capturing, is 200.\r
+</P>\r
+<P>\r
+As a convenient shorthand, if any option settings are required at the start of\r
+a non-capturing subpattern, the option letters may appear between the "?" and\r
+the ":". Thus the two patterns\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?i:saturday|sunday)\r
+  (?:(?i)saturday|sunday)\r
+</PRE>\r
+</P>\r
+<P>\r
+match exactly the same set of strings. Because alternative branches are tried\r
+from left to right, and options are not reset until the end of the subpattern\r
+is reached, an option setting in one branch does affect subsequent branches, so\r
+the above patterns match "SUNDAY" as well as "Saturday".\r
+</P>\r
+<LI><A NAME="SEC22" HREF="#TOC1">REPETITION</A>\r
+<P>\r
+Repetition is specified by quantifiers, which can follow any of the following\r
+items:\r
+</P>\r
+<P>\r
+<PRE>\r
+  a single character, possibly escaped\r
+  the . metacharacter\r
+  a character class\r
+  a back reference (see next section)\r
+  a parenthesized subpattern (unless it is an assertion - see below)\r
+</PRE>\r
+</P>\r
+<P>\r
+The general repetition quantifier specifies a minimum and maximum number of\r
+permitted matches, by giving the two numbers in curly brackets (braces),\r
+separated by a comma. The numbers must be less than 65536, and the first must\r
+be less than or equal to the second. For example:\r
+</P>\r
+<P>\r
+<PRE>\r
+  z{2,4}\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "zz", "zzz", or "zzzz". A closing brace on its own is not a special\r
+character. If the second number is omitted, but the comma is present, there is\r
+no upper limit; if the second number and the comma are both omitted, the\r
+quantifier specifies an exact number of required matches. Thus\r
+</P>\r
+<P>\r
+<PRE>\r
+  [aeiou]{3,}\r
+</PRE>\r
+</P>\r
+<P>\r
+matches at least 3 successive vowels, but may match many more, while\r
+</P>\r
+<P>\r
+<PRE>\r
+  \d{8}\r
+</PRE>\r
+</P>\r
+<P>\r
+matches exactly 8 digits. An opening curly bracket that appears in a position\r
+where a quantifier is not allowed, or one that does not match the syntax of a\r
+quantifier, is taken as a literal character. For example, {,6} is not a\r
+quantifier, but a literal string of four characters.\r
+</P>\r
+<P>\r
+The quantifier {0} is permitted, causing the expression to behave as if the\r
+previous item and the quantifier were not present.\r
+</P>\r
+<P>\r
+For convenience (and historical compatibility) the three most common\r
+quantifiers have single-character abbreviations:\r
+</P>\r
+<P>\r
+<PRE>\r
+  *    is equivalent to {0,}\r
+  +    is equivalent to {1,}\r
+  ?    is equivalent to {0,1}\r
+</PRE>\r
+</P>\r
+<P>\r
+It is possible to construct infinite loops by following a subpattern that can\r
+match no characters with a quantifier that has no upper limit, for example:\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a?)*\r
+</PRE>\r
+</P>\r
+<P>\r
+Earlier versions of Perl and PCRE used to give an error at compile time for\r
+such patterns. However, because there are cases where this can be useful, such\r
+patterns are now accepted, but if any repetition of the subpattern does in fact\r
+match no characters, the loop is forcibly broken.\r
+</P>\r
+<P>\r
+By default, the quantifiers are "greedy", that is, they match as much as\r
+possible (up to the maximum number of permitted times), without causing the\r
+rest of the pattern to fail. The classic example of where this gives problems\r
+is in trying to match comments in C programs. These appear between the\r
+sequences /* and */ and within the sequence, individual * and / characters may\r
+appear. An attempt to match C comments by applying the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  /\*.*\*/\r
+</PRE>\r
+</P>\r
+<P>\r
+to the string\r
+</P>\r
+<P>\r
+<PRE>\r
+  /* first command */  not comment  /* second comment */\r
+</PRE>\r
+</P>\r
+<P>\r
+fails, because it matches the entire string owing to the greediness of the .*\r
+item.\r
+</P>\r
+<P>\r
+However, if a quantifier is followed by a question mark, it ceases to be\r
+greedy, and instead matches the minimum number of times possible, so the\r
+pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  /\*.*?\*/\r
+</PRE>\r
+</P>\r
+<P>\r
+does the right thing with the C comments. The meaning of the various\r
+quantifiers is not otherwise changed, just the preferred number of matches.\r
+Do not confuse this use of question mark with its use as a quantifier in its\r
+own right. Because it has two uses, it can sometimes appear doubled, as in\r
+</P>\r
+<P>\r
+<PRE>\r
+  \d??\d\r
+</PRE>\r
+</P>\r
+<P>\r
+which matches one digit by preference, but can match two if that is the only\r
+way the rest of the pattern matches.\r
+</P>\r
+<P>\r
+If the PCRE_UNGREEDY option is set (an option which is not available in Perl),\r
+the quantifiers are not greedy by default, but individual ones can be made\r
+greedy by following them with a question mark. In other words, it inverts the\r
+default behaviour.\r
+</P>\r
+<P>\r
+When a parenthesized subpattern is quantified with a minimum repeat count that\r
+is greater than 1 or with a limited maximum, more store is required for the\r
+compiled pattern, in proportion to the size of the minimum or maximum.\r
+</P>\r
+<P>\r
+If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent\r
+to Perl's /s) is set, thus allowing the . to match newlines, the pattern is\r
+implicitly anchored, because whatever follows will be tried against every\r
+character position in the subject string, so there is no point in retrying the\r
+overall match at any position after the first. PCRE treats such a pattern as\r
+though it were preceded by \A. In cases where it is known that the subject\r
+string contains no newlines, it is worth setting PCRE_DOTALL when the pattern\r
+begins with .* in order to obtain this optimization, or alternatively using ^\r
+to indicate anchoring explicitly.\r
+</P>\r
+<P>\r
+When a capturing subpattern is repeated, the value captured is the substring\r
+that matched the final iteration. For example, after\r
+</P>\r
+<P>\r
+<PRE>\r
+  (tweedle[dume]{3}\s*)+\r
+</PRE>\r
+</P>\r
+<P>\r
+has matched "tweedledum tweedledee" the value of the captured substring is\r
+"tweedledee". However, if there are nested capturing subpatterns, the\r
+corresponding captured values may have been set in previous iterations. For\r
+example, after\r
+</P>\r
+<P>\r
+<PRE>\r
+  /(a|(b))+/\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "aba" the value of the second captured substring is "b".\r
+</P>\r
+<LI><A NAME="SEC23" HREF="#TOC1">BACK REFERENCES</A>\r
+<P>\r
+Outside a character class, a backslash followed by a digit greater than 0 (and\r
+possibly further digits) is a back reference to a capturing subpattern earlier\r
+(i.e. to its left) in the pattern, provided there have been that many previous\r
+capturing left parentheses.\r
+</P>\r
+<P>\r
+However, if the decimal number following the backslash is less than 10, it is\r
+always taken as a back reference, and causes an error only if there are not\r
+that many capturing left parentheses in the entire pattern. In other words, the\r
+parentheses that are referenced need not be to the left of the reference for\r
+numbers less than 10. See the section entitled "Backslash" above for further\r
+details of the handling of digits following a backslash.\r
+</P>\r
+<P>\r
+A back reference matches whatever actually matched the capturing subpattern in\r
+the current subject string, rather than anything matching the subpattern\r
+itself. So the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  (sens|respons)e and \1ibility\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "sense and sensibility" and "response and responsibility", but not\r
+"sense and responsibility". If caseful matching is in force at the time of the\r
+back reference, the case of letters is relevant. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  ((?i)rah)\s+\1\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original\r
+capturing subpattern is matched caselessly.\r
+</P>\r
+<P>\r
+There may be more than one back reference to the same subpattern. If a\r
+subpattern has not actually been used in a particular match, any back\r
+references to it always fail. For example, the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a|(bc))\2\r
+</PRE>\r
+</P>\r
+<P>\r
+always fails if it starts to match "a" rather than "bc". Because there may be\r
+up to 99 back references, all digits following the backslash are taken\r
+as part of a potential back reference number. If the pattern continues with a\r
+digit character, some delimiter must be used to terminate the back reference.\r
+If the PCRE_EXTENDED option is set, this can be whitespace. Otherwise an empty\r
+comment can be used.\r
+</P>\r
+<P>\r
+A back reference that occurs inside the parentheses to which it refers fails\r
+when the subpattern is first used, so, for example, (a\1) never matches.\r
+However, such references can be useful inside repeated subpatterns. For\r
+example, the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a|b\1)+\r
+</PRE>\r
+</P>\r
+<P>\r
+matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of\r
+the subpattern, the back reference matches the character string corresponding\r
+to the previous iteration. In order for this to work, the pattern must be such\r
+that the first iteration does not need to match the back reference. This can be\r
+done using alternation, as in the example above, or by a quantifier with a\r
+minimum of zero.\r
+</P>\r
+<LI><A NAME="SEC24" HREF="#TOC1">ASSERTIONS</A>\r
+<P>\r
+An assertion is a test on the characters following or preceding the current\r
+matching point that does not actually consume any characters. The simple\r
+assertions coded as \b, \B, \A, \Z, \z, ^ and $ are described above. More\r
+complicated assertions are coded as subpatterns. There are two kinds: those\r
+that look ahead of the current position in the subject string, and those that\r
+look behind it.\r
+</P>\r
+<P>\r
+An assertion subpattern is matched in the normal way, except that it does not\r
+cause the current matching position to be changed. Lookahead assertions start\r
+with (?= for positive assertions and (?! for negative assertions. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  \w+(?=;)\r
+</PRE>\r
+</P>\r
+<P>\r
+matches a word followed by a semicolon, but does not include the semicolon in\r
+the match, and\r
+</P>\r
+<P>\r
+<PRE>\r
+  foo(?!bar)\r
+</PRE>\r
+</P>\r
+<P>\r
+matches any occurrence of "foo" that is not followed by "bar". Note that the\r
+apparently similar pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?!foo)bar\r
+</PRE>\r
+</P>\r
+<P>\r
+does not find an occurrence of "bar" that is preceded by something other than\r
+"foo"; it finds any occurrence of "bar" whatsoever, because the assertion\r
+(?!foo) is always true when the next three characters are "bar". A\r
+lookbehind assertion is needed to achieve this effect.\r
+</P>\r
+<P>\r
+Lookbehind assertions start with (?&#60;= for positive assertions and (?&#60;! for\r
+negative assertions. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;!foo)bar\r
+</PRE>\r
+</P>\r
+<P>\r
+does find an occurrence of "bar" that is not preceded by "foo". The contents of\r
+a lookbehind assertion are restricted such that all the strings it matches must\r
+have a fixed length. However, if there are several alternatives, they do not\r
+all have to have the same fixed length. Thus\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;=bullock|donkey)\r
+</PRE>\r
+</P>\r
+<P>\r
+is permitted, but\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;!dogs?|cats?)\r
+</PRE>\r
+</P>\r
+<P>\r
+causes an error at compile time. Branches that match different length strings\r
+are permitted only at the top level of a lookbehind assertion. This is an\r
+extension compared with Perl 5.005, which requires all branches to match the\r
+same length of string. An assertion such as\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;=ab(c|de))\r
+</PRE>\r
+</P>\r
+<P>\r
+is not permitted, because its single top-level branch can match two different\r
+lengths, but it is acceptable if rewritten to use two top-level branches:\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;=abc|abde)\r
+</PRE>\r
+</P>\r
+<P>\r
+The implementation of lookbehind assertions is, for each alternative, to\r
+temporarily move the current position back by the fixed width and then try to\r
+match. If there are insufficient characters before the current position, the\r
+match is deemed to fail. Lookbehinds in conjunction with once-only subpatterns\r
+can be particularly useful for matching at the ends of strings; an example is\r
+given at the end of the section on once-only subpatterns.\r
+</P>\r
+<P>\r
+Several assertions (of any sort) may occur in succession. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;=\d{3})(?&#60;!999)foo\r
+</PRE>\r
+</P>\r
+<P>\r
+matches "foo" preceded by three digits that are not "999". Notice that each of\r
+the assertions is applied independently at the same point in the subject\r
+string. First there is a check that the previous three characters are all\r
+digits, and then there is a check that the same three characters are not "999".\r
+This pattern does <I>not</I> match "foo" preceded by six characters, the first\r
+of which are digits and the last three of which are not "999". For example, it\r
+doesn't match "123abcfoo". A pattern to do that is\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;=\d{3}...)(?&#60;!999)foo\r
+</PRE>\r
+</P>\r
+<P>\r
+This time the first assertion looks at the preceding six characters, checking\r
+that the first three are digits, and then the second assertion checks that the\r
+preceding three characters are not "999".\r
+</P>\r
+<P>\r
+Assertions can be nested in any combination. For example,\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;=(?&#60;!foo)bar)baz\r
+</PRE>\r
+</P>\r
+<P>\r
+matches an occurrence of "baz" that is preceded by "bar" which in turn is not\r
+preceded by "foo", while\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#60;=\d{3}(?!999)...)foo\r
+</PRE>\r
+</P>\r
+<P>\r
+is another pattern which matches "foo" preceded by three digits and any three\r
+characters that are not "999".\r
+</P>\r
+<P>\r
+Assertion subpatterns are not capturing subpatterns, and may not be repeated,\r
+because it makes no sense to assert the same thing several times. If any kind\r
+of assertion contains capturing subpatterns within it, these are counted for\r
+the purposes of numbering the capturing subpatterns in the whole pattern.\r
+However, substring capturing is carried out only for positive assertions,\r
+because it does not make sense for negative assertions.\r
+</P>\r
+<P>\r
+Assertions count towards the maximum of 200 parenthesized subpatterns.\r
+</P>\r
+<LI><A NAME="SEC25" HREF="#TOC1">ONCE-ONLY SUBPATTERNS</A>\r
+<P>\r
+With both maximizing and minimizing repetition, failure of what follows\r
+normally causes the repeated item to be re-evaluated to see if a different\r
+number of repeats allows the rest of the pattern to match. Sometimes it is\r
+useful to prevent this, either to change the nature of the match, or to cause\r
+it fail earlier than it otherwise might, when the author of the pattern knows\r
+there is no point in carrying on.\r
+</P>\r
+<P>\r
+Consider, for example, the pattern \d+foo when applied to the subject line\r
+</P>\r
+<P>\r
+<PRE>\r
+  123456bar\r
+</PRE>\r
+</P>\r
+<P>\r
+After matching all 6 digits and then failing to match "foo", the normal\r
+action of the matcher is to try again with only 5 digits matching the \d+\r
+item, and then with 4, and so on, before ultimately failing. Once-only\r
+subpatterns provide the means for specifying that once a portion of the pattern\r
+has matched, it is not to be re-evaluated in this way, so the matcher would\r
+give up immediately on failing to match "foo" the first time. The notation is\r
+another kind of special parenthesis, starting with (?&#62; as in this example:\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?&#62;\d+)bar\r
+</PRE>\r
+</P>\r
+<P>\r
+This kind of parenthesis "locks up" the  part of the pattern it contains once\r
+it has matched, and a failure further into the pattern is prevented from\r
+backtracking into it. Backtracking past it to previous items, however, works as\r
+normal.\r
+</P>\r
+<P>\r
+An alternative description is that a subpattern of this type matches the string\r
+of characters that an identical standalone pattern would match, if anchored at\r
+the current point in the subject string.\r
+</P>\r
+<P>\r
+Once-only subpatterns are not capturing subpatterns. Simple cases such as the\r
+above example can be thought of as a maximizing repeat that must swallow\r
+everything it can. So, while both \d+ and \d+? are prepared to adjust the\r
+number of digits they match in order to make the rest of the pattern match,\r
+(?&#62;\d+) can only match an entire sequence of digits.\r
+</P>\r
+<P>\r
+This construction can of course contain arbitrarily complicated subpatterns,\r
+and it can be nested.\r
+</P>\r
+<P>\r
+Once-only subpatterns can be used in conjunction with lookbehind assertions to\r
+specify efficient matching at the end of the subject string. Consider a simple\r
+pattern such as\r
+</P>\r
+<P>\r
+<PRE>\r
+  abcd$\r
+</PRE>\r
+</P>\r
+<P>\r
+when applied to a long string which does not match. Because matching proceeds\r
+from left to right, PCRE will look for each "a" in the subject and then see if\r
+what follows matches the rest of the pattern. If the pattern is specified as\r
+</P>\r
+<P>\r
+<PRE>\r
+  ^.*abcd$\r
+</PRE>\r
+</P>\r
+<P>\r
+the initial .* matches the entire string at first, but when this fails (because\r
+there is no following "a"), it backtracks to match all but the last character,\r
+then all but the last two characters, and so on. Once again the search for "a"\r
+covers the entire string, from right to left, so we are no better off. However,\r
+if the pattern is written as\r
+</P>\r
+<P>\r
+<PRE>\r
+  ^(?&#62;.*)(?&#60;=abcd)\r
+</PRE>\r
+</P>\r
+<P>\r
+there can be no backtracking for the .* item; it can match only the entire\r
+string. The subsequent lookbehind assertion does a single test on the last four\r
+characters. If it fails, the match fails immediately. For long strings, this\r
+approach makes a significant difference to the processing time.\r
+</P>\r
+<P>\r
+When a pattern contains an unlimited repeat inside a subpattern that can itself\r
+be repeated an unlimited number of times, the use of a once-only subpattern is\r
+the only way to avoid some failing matches taking a very long time indeed.\r
+The pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  (\D+|&#60;\d+&#62;)*[!?]\r
+</PRE>\r
+</P>\r
+<P>\r
+matches an unlimited number of substrings that either consist of non-digits, or\r
+digits enclosed in &#60;&#62;, followed by either ! or ?. When it matches, it runs\r
+quickly. However, if it is applied to\r
+</P>\r
+<P>\r
+<PRE>\r
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r
+</PRE>\r
+</P>\r
+<P>\r
+it takes a long time before reporting failure. This is because the string can\r
+be divided between the two repeats in a large number of ways, and all have to\r
+be tried. (The example used [!?] rather than a single character at the end,\r
+because both PCRE and Perl have an optimization that allows for fast failure\r
+when a single character is used. They remember the last single character that\r
+is required for a match, and fail early if it is not present in the string.)\r
+If the pattern is changed to\r
+</P>\r
+<P>\r
+<PRE>\r
+  ((?&#62;\D+)|&#60;\d+&#62;)*[!?]\r
+</PRE>\r
+</P>\r
+<P>\r
+sequences of non-digits cannot be broken, and failure happens quickly.\r
+</P>\r
+<LI><A NAME="SEC26" HREF="#TOC1">CONDITIONAL SUBPATTERNS</A>\r
+<P>\r
+It is possible to cause the matching process to obey a subpattern\r
+conditionally or to choose between two alternative subpatterns, depending on\r
+the result of an assertion, or whether a previous capturing subpattern matched\r
+or not. The two possible forms of conditional subpattern are\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?(condition)yes-pattern)\r
+  (?(condition)yes-pattern|no-pattern)\r
+</PRE>\r
+</P>\r
+<P>\r
+If the condition is satisfied, the yes-pattern is used; otherwise the\r
+no-pattern (if present) is used. If there are more than two alternatives in the\r
+subpattern, a compile-time error occurs.\r
+</P>\r
+<P>\r
+There are two kinds of condition. If the text between the parentheses consists\r
+of a sequence of digits, the condition is satisfied if the capturing subpattern\r
+of that number has previously matched. The number must be greater than zero.\r
+Consider the following pattern, which contains non-significant white space to\r
+make it more readable (assume the PCRE_EXTENDED option) and to divide it into\r
+three parts for ease of discussion:\r
+</P>\r
+<P>\r
+<PRE>\r
+  ( \( )?    [^()]+    (?(1) \) )\r
+</PRE>\r
+</P>\r
+<P>\r
+The first part matches an optional opening parenthesis, and if that\r
+character is present, sets it as the first captured substring. The second part\r
+matches one or more characters that are not parentheses. The third part is a\r
+conditional subpattern that tests whether the first set of parentheses matched\r
+or not. If they did, that is, if subject started with an opening parenthesis,\r
+the condition is true, and so the yes-pattern is executed and a closing\r
+parenthesis is required. Otherwise, since no-pattern is not present, the\r
+subpattern matches nothing. In other words, this pattern matches a sequence of\r
+non-parentheses, optionally enclosed in parentheses.\r
+</P>\r
+<P>\r
+If the condition is not a sequence of digits, it must be an assertion. This may\r
+be a positive or negative lookahead or lookbehind assertion. Consider this\r
+pattern, again containing non-significant white space, and with the two\r
+alternatives on the second line:\r
+</P>\r
+<P>\r
+<PRE>\r
+  (?(?=[^a-z]*[a-z])\r
+  \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )\r
+</PRE>\r
+</P>\r
+<P>\r
+The condition is a positive lookahead assertion that matches an optional\r
+sequence of non-letters followed by a letter. In other words, it tests for the\r
+presence of at least one letter in the subject. If a letter is found, the\r
+subject is matched against the first alternative; otherwise it is matched\r
+against the second. This pattern matches strings in one of the two forms\r
+dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.\r
+</P>\r
+<LI><A NAME="SEC27" HREF="#TOC1">COMMENTS</A>\r
+<P>\r
+The sequence (?# marks the start of a comment which continues up to the next\r
+closing parenthesis. Nested parentheses are not permitted. The characters\r
+that make up a comment play no part in the pattern matching at all.\r
+</P>\r
+<P>\r
+If the PCRE_EXTENDED option is set, an unescaped # character outside a\r
+character class introduces a comment that continues up to the next newline\r
+character in the pattern.\r
+</P>\r
+<LI><A NAME="SEC28" HREF="#TOC1">RECURSIVE PATTERNS</A>\r
+<P>\r
+Consider the problem of matching a string in parentheses, allowing for\r
+unlimited nested parentheses. Without the use of recursion, the best that can\r
+be done is to use a pattern that matches up to some fixed depth of nesting. It\r
+is not possible to handle an arbitrary nesting depth. Perl 5.6 has provided an\r
+experimental facility that allows regular expressions to recurse (amongst other\r
+things). It does this by interpolating Perl code in the expression at run time,\r
+and the code can refer to the expression itself. A Perl pattern to solve the\r
+parentheses problem can be created like this:\r
+</P>\r
+<P>\r
+<PRE>\r
+  $re = qr{\( (?: (?&#62;[^()]+) | (?p{$re}) )* \)}x;\r
+</PRE>\r
+</P>\r
+<P>\r
+The (?p{...}) item interpolates Perl code at run time, and in this case refers\r
+recursively to the pattern in which it appears. Obviously, PCRE cannot support\r
+the interpolation of Perl code. Instead, the special item (?R) is provided for\r
+the specific case of recursion. This PCRE pattern solves the parentheses\r
+problem (assume the PCRE_EXTENDED option is set so that white space is\r
+ignored):\r
+</P>\r
+<P>\r
+<PRE>\r
+  \( ( (?&#62;[^()]+) | (?R) )* \)\r
+</PRE>\r
+</P>\r
+<P>\r
+First it matches an opening parenthesis. Then it matches any number of\r
+substrings which can either be a sequence of non-parentheses, or a recursive\r
+match of the pattern itself (i.e. a correctly parenthesized substring). Finally\r
+there is a closing parenthesis.\r
+</P>\r
+<P>\r
+This particular example pattern contains nested unlimited repeats, and so the\r
+use of a once-only subpattern for matching strings of non-parentheses is\r
+important when applying the pattern to strings that do not match. For example,\r
+when it is applied to\r
+</P>\r
+<P>\r
+<PRE>\r
+  (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\r
+</PRE>\r
+</P>\r
+<P>\r
+it yields "no match" quickly. However, if a once-only subpattern is not used,\r
+the match runs for a very long time indeed because there are so many different\r
+ways the + and * repeats can carve up the subject, and all have to be tested\r
+before failure can be reported.\r
+</P>\r
+<P>\r
+The values set for any capturing subpatterns are those from the outermost level\r
+of the recursion at which the subpattern value is set. If the pattern above is\r
+matched against\r
+</P>\r
+<P>\r
+<PRE>\r
+  (ab(cd)ef)\r
+</PRE>\r
+</P>\r
+<P>\r
+the value for the capturing parentheses is "ef", which is the last value taken\r
+on at the top level. If additional parentheses are added, giving\r
+</P>\r
+<P>\r
+<PRE>\r
+  \( ( ( (?&#62;[^()]+) | (?R) )* ) \)\r
+     ^                        ^\r
+     ^                        ^\r
+</PRE>\r
+the string they capture is "ab(cd)ef", the contents of the top level\r
+parentheses. If there are more than 15 capturing parentheses in a pattern, PCRE\r
+has to obtain extra memory to store data during a recursion, which it does by\r
+using <B>pcre_malloc</B>, freeing it via <B>pcre_free</B> afterwards. If no\r
+memory can be obtained, it saves data for the first 15 capturing parentheses\r
+only, as there is no way to give an out-of-memory error from within a\r
+recursion.\r
+</P>\r
+<LI><A NAME="SEC29" HREF="#TOC1">PERFORMANCE</A>\r
+<P>\r
+Certain items that may appear in patterns are more efficient than others. It is\r
+more efficient to use a character class like [aeiou] than a set of alternatives\r
+such as (a|e|i|o|u). In general, the simplest construction that provides the\r
+required behaviour is usually the most efficient. Jeffrey Friedl's book\r
+contains a lot of discussion about optimizing regular expressions for efficient\r
+performance.\r
+</P>\r
+<P>\r
+When a pattern begins with .* and the PCRE_DOTALL option is set, the pattern is\r
+implicitly anchored by PCRE, since it can match only at the start of a subject\r
+string. However, if PCRE_DOTALL is not set, PCRE cannot make this optimization,\r
+because the . metacharacter does not then match a newline, and if the subject\r
+string contains newlines, the pattern may match from the character immediately\r
+following one of them instead of from the very start. For example, the pattern\r
+</P>\r
+<P>\r
+<PRE>\r
+  (.*) second\r
+</PRE>\r
+</P>\r
+<P>\r
+matches the subject "first\nand second" (where \n stands for a newline\r
+character) with the first captured substring being "and". In order to do this,\r
+PCRE has to retry the match starting after every newline in the subject.\r
+</P>\r
+<P>\r
+If you are using such a pattern with subject strings that do not contain\r
+newlines, the best performance is obtained by setting PCRE_DOTALL, or starting\r
+the pattern with ^.* to indicate explicit anchoring. That saves PCRE from\r
+having to scan along the subject looking for a newline to restart at.\r
+</P>\r
+<P>\r
+Beware of patterns that contain nested indefinite repeats. These can take a\r
+long time to run when applied to a string that does not match. Consider the\r
+pattern fragment\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a+)*\r
+</PRE>\r
+</P>\r
+<P>\r
+This can match "aaaa" in 33 different ways, and this number increases very\r
+rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4\r
+times, and for each of those cases other than 0, the + repeats can match\r
+different numbers of times.) When the remainder of the pattern is such that the\r
+entire match is going to fail, PCRE has in principle to try every possible\r
+variation, and this can take an extremely long time.\r
+</P>\r
+<P>\r
+An optimization catches some of the more simple cases such as\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a+)*b\r
+</PRE>\r
+</P>\r
+<P>\r
+where a literal character follows. Before embarking on the standard matching\r
+procedure, PCRE checks that there is a "b" later in the subject string, and if\r
+there is not, it fails the match immediately. However, when there is no\r
+following literal this optimization cannot be used. You can see the difference\r
+by comparing the behaviour of\r
+</P>\r
+<P>\r
+<PRE>\r
+  (a+)*\d\r
+</PRE>\r
+</P>\r
+<P>\r
+with the pattern above. The former gives a failure almost instantly when\r
+applied to a whole line of "a" characters, whereas the latter takes an\r
+appreciable time with strings longer than about 20 characters.\r
+</P>\r
+<LI><A NAME="SEC30" HREF="#TOC1">UTF-8 SUPPORT</A>\r
+<P>\r
+Starting at release 3.3, PCRE has some support for character strings encoded\r
+in the UTF-8 format. This is incomplete, and is regarded as experimental. In\r
+order to use it, you must configure PCRE to include UTF-8 support in the code,\r
+and, in addition, you must call <B>pcre_compile()</B> with the PCRE_UTF8 option\r
+flag. When you do this, both the pattern and any subject strings that are\r
+matched against it are treated as UTF-8 strings instead of just strings of\r
+bytes, but only in the cases that are mentioned below.\r
+</P>\r
+<P>\r
+If you compile PCRE with UTF-8 support, but do not use it at run time, the\r
+library will be a bit bigger, but the additional run time overhead is limited\r
+to testing the PCRE_UTF8 flag in several places, so should not be very large.\r
+</P>\r
+<P>\r
+PCRE assumes that the strings it is given contain valid UTF-8 codes. It does\r
+not diagnose invalid UTF-8 strings. If you pass invalid UTF-8 strings to PCRE,\r
+the results are undefined.\r
+</P>\r
+<P>\r
+Running with PCRE_UTF8 set causes these changes in the way PCRE works:\r
+</P>\r
+<P>\r
+1. In a pattern, the escape sequence \x{...}, where the contents of the braces\r
+is a string of hexadecimal digits, is interpreted as a UTF-8 character whose\r
+code number is the given hexadecimal number, for example: \x{1234}. This\r
+inserts from one to six literal bytes into the pattern, using the UTF-8\r
+encoding. If a non-hexadecimal digit appears between the braces, the item is\r
+not recognized.\r
+</P>\r
+<P>\r
+2. The original hexadecimal escape sequence, \xhh, generates a two-byte UTF-8\r
+character if its value is greater than 127.\r
+</P>\r
+<P>\r
+3. Repeat quantifiers are NOT correctly handled if they follow a multibyte\r
+character. For example, \x{100}* and \xc3+ do not work. If you want to\r
+repeat such characters, you must enclose them in non-capturing parentheses,\r
+for example (?:\x{100}), at present.\r
+</P>\r
+<P>\r
+4. The dot metacharacter matches one UTF-8 character instead of a single byte.\r
+</P>\r
+<P>\r
+5. Unlike literal UTF-8 characters, the dot metacharacter followed by a\r
+repeat quantifier does operate correctly on UTF-8 characters instead of\r
+single bytes.\r
+</P>\r
+<P>\r
+4. Although the \x{...} escape is permitted in a character class, characters\r
+whose values are greater than 255 cannot be included in a class.\r
+</P>\r
+<P>\r
+5. A class is matched against a UTF-8 character instead of just a single byte,\r
+but it can match only characters whose values are less than 256. Characters\r
+with greater values always fail to match a class.\r
+</P>\r
+<P>\r
+6. Repeated classes work correctly on multiple characters.\r
+</P>\r
+<P>\r
+7. Classes containing just a single character whose value is greater than 127\r
+(but less than 256), for example, [\x80] or [^\x{93}], do not work because\r
+these are optimized into single byte matches. In the first case, of course,\r
+the class brackets are just redundant.\r
+</P>\r
+<P>\r
+8. Lookbehind assertions move backwards in the subject by a fixed number of\r
+characters instead of a fixed number of bytes. Simple cases have been tested\r
+to work correctly, but there may be hidden gotchas herein.\r
+</P>\r
+<P>\r
+9. The character types such as \d and \w do not work correctly with UTF-8\r
+characters. They continue to test a single byte.\r
+</P>\r
+<P>\r
+10. Anything not explicitly mentioned here continues to work in bytes rather\r
+than in characters.\r
+</P>\r
+<P>\r
+The following UTF-8 features of Perl 5.6 are not implemented:\r
+</P>\r
+<P>\r
+1. The escape sequence \C to match a single byte.\r
+</P>\r
+<P>\r
+2. The use of Unicode tables and properties and escapes \p, \P, and \X.\r
+</P>\r
+<LI><A NAME="SEC31" HREF="#TOC1">AUTHOR</A>\r
+<P>\r
+Philip Hazel &#60;ph10@cam.ac.uk&#62;\r
+<BR>\r
+University Computing Service,\r
+<BR>\r
+New Museums Site,\r
+<BR>\r
+Cambridge CB2 3QG, England.\r
+<BR>\r
+Phone: +44 1223 334714\r
+</P>\r
+<P>\r
+Last updated: 28 August 2000,\r
+<BR>\r
+<PRE>\r
+  the 250th anniversary of the death of J.S. Bach.\r
+<BR>\r
+</PRE>\r
+Copyright (c) 1997-2000 University of Cambridge.\r
diff --git a/pcre/doc/pcre.txt b/pcre/doc/pcre.txt
new file mode 100644 (file)
index 0000000..1db4b53
--- /dev/null
@@ -0,0 +1,2125 @@
+NAME
+     pcre - Perl-compatible regular expressions.
+
+
+
+SYNOPSIS
+     #include <pcre.h>
+
+     pcre *pcre_compile(const char *pattern, int options,
+          const char **errptr, int *erroffset,
+          const unsigned char *tableptr);
+
+     pcre_extra *pcre_study(const pcre *code, int options,
+          const char **errptr);
+
+     int pcre_exec(const pcre *code, const pcre_extra *extra,
+          const char *subject, int length, int startoffset,
+          int options, int *ovector, int ovecsize);
+
+     int pcre_copy_substring(const char *subject, int *ovector,
+          int stringcount, int stringnumber, char *buffer,
+          int buffersize);
+
+     int pcre_get_substring(const char *subject, int *ovector,
+          int stringcount, int stringnumber,
+          const char **stringptr);
+
+     int pcre_get_substring_list(const char *subject,
+          int *ovector, int stringcount, const char ***listptr);
+
+     void pcre_free_substring(const char *stringptr);
+
+     void pcre_free_substring_list(const char **stringptr);
+
+     const unsigned char *pcre_maketables(void);
+
+     int pcre_fullinfo(const pcre *code, const pcre_extra *extra,
+          int what, void *where);
+
+     int pcre_info(const pcre *code, int *optptr, *firstcharptr);
+
+     char *pcre_version(void);
+
+     void *(*pcre_malloc)(size_t);
+
+     void (*pcre_free)(void *);
+
+
+
+
+DESCRIPTION
+     The PCRE library is a set of functions that implement  regu-
+     lar  expression  pattern  matching using the same syntax and
+     semantics as Perl  5,  with  just  a  few  differences  (see
+
+     below).  The  current  implementation  corresponds  to  Perl
+     5.005, with some additional features  from  later  versions.
+     This  includes  some  experimental,  incomplete  support for
+     UTF-8 encoded strings. Details of exactly what is  and  what
+     is not supported are given below.
+
+     PCRE has its own native API,  which  is  described  in  this
+     document.  There  is  also  a  set of wrapper functions that
+     correspond to the POSIX regular expression API.   These  are
+     described in the pcreposix documentation.
+
+     The native API function prototypes are defined in the header
+     file  pcre.h,  and  on  Unix  systems  the library itself is
+     called libpcre.a, so can be accessed by adding -lpcre to the
+     command  for  linking  an  application  which  calls it. The
+     header file defines the macros PCRE_MAJOR and PCRE_MINOR  to
+     contain the major and minor release numbers for the library.
+     Applications can use these to include support for  different
+     releases.
+
+     The functions pcre_compile(), pcre_study(), and  pcre_exec()
+     are used for compiling and matching regular expressions.
+
+     The functions  pcre_copy_substring(),  pcre_get_substring(),
+     and  pcre_get_substring_list() are convenience functions for
+     extracting  captured  substrings  from  a  matched   subject
+     string; pcre_free_substring() and pcre_free_substring_list()
+     are also provided, to free the  memory  used  for  extracted
+     strings.
+
+     The function pcre_maketables() is used (optionally) to build
+     a  set of character tables in the current locale for passing
+     to pcre_compile().
+
+     The function pcre_fullinfo() is used to find out information
+     about a compiled pattern; pcre_info() is an obsolete version
+     which returns only some of the available information, but is
+     retained   for   backwards   compatibility.    The  function
+     pcre_version() returns a pointer to a string containing  the
+     version of PCRE and its date of release.
+
+     The global variables  pcre_malloc  and  pcre_free  initially
+     contain the entry points of the standard malloc() and free()
+     functions respectively. PCRE  calls  the  memory  management
+     functions  via  these  variables,  so  a calling program can
+     replace them if it  wishes  to  intercept  the  calls.  This
+     should be done before calling any PCRE functions.
+
+
+
+MULTI-THREADING
+     The  PCRE  functions  can   be   used   in   multi-threading
+
+
+
+
+
+SunOS 5.8                 Last change:                          2
+
+
+
+     applications,  with  the  proviso that the memory management
+     functions pointed to by pcre_malloc and pcre_free are shared
+     by all threads.
+
+     The compiled form of a regular  expression  is  not  altered
+     during  matching, so the same compiled pattern can safely be
+     used by several threads at once.
+
+
+
+COMPILING A PATTERN
+     The function pcre_compile() is called to compile  a  pattern
+     into  an internal form. The pattern is a C string terminated
+     by a binary zero, and is passed in the argument  pattern.  A
+     pointer  to  a  single  block of memory that is obtained via
+     pcre_malloc is returned. This contains the compiled code and
+     related data. The pcre type is defined for this for conveni-
+     ence, but in fact pcre is just a typedef for void, since the
+     contents  of  the block are not externally defined. It is up
+     to the caller to free  the  memory  when  it  is  no  longer
+     required.
+
+     The size of a compiled pattern is  roughly  proportional  to
+     the length of the pattern string, except that each character
+     class (other than those containing just a single  character,
+     negated  or  not)  requires 33 bytes, and repeat quantifiers
+     with a minimum greater than one or a bounded  maximum  cause
+     the  relevant  portions of the compiled pattern to be repli-
+     cated.
+
+     The options argument contains independent bits  that  affect
+     the  compilation.  It  should  be  zero  if  no  options are
+     required. Some of the options, in particular, those that are
+     compatible  with Perl, can also be set and unset from within
+     the pattern (see the detailed description of regular expres-
+     sions below). For these options, the contents of the options
+     argument specifies their initial settings at  the  start  of
+     compilation  and  execution. The PCRE_ANCHORED option can be
+     set at the time of matching as well as at compile time.
+
+     If errptr is NULL, pcre_compile() returns NULL  immediately.
+     Otherwise, if compilation of a pattern fails, pcre_compile()
+     returns NULL, and sets the variable pointed to by errptr  to
+     point  to a textual error message. The offset from the start
+     of  the  pattern  to  the  character  where  the  error  was
+     discovered   is   placed  in  the  variable  pointed  to  by
+     erroffset, which must not be NULL. If it  is,  an  immediate
+     error is given.
+
+     If the final  argument,  tableptr,  is  NULL,  PCRE  uses  a
+     default  set  of character tables which are built when it is
+     compiled, using the default C  locale.  Otherwise,  tableptr
+     must  be  the result of a call to pcre_maketables(). See the
+     section on locale support below.
+
+     The following option bits are defined in the header file:
+
+       PCRE_ANCHORED
+
+     If this bit is set, the pattern is forced to be  "anchored",
+     that is, it is constrained to match only at the start of the
+     string which is being searched (the "subject string").  This
+     effect can also be achieved by appropriate constructs in the
+     pattern itself, which is the only way to do it in Perl.
+
+       PCRE_CASELESS
+
+     If this bit is set, letters in the pattern match both  upper
+     and  lower  case  letters.  It  is  equivalent  to Perl's /i
+     option.
+
+       PCRE_DOLLAR_ENDONLY
+
+     If this bit is set, a dollar metacharacter  in  the  pattern
+     matches  only at the end of the subject string. Without this
+     option, a dollar also matches immediately before  the  final
+     character  if it is a newline (but not before any other new-
+     lines).  The  PCRE_DOLLAR_ENDONLY  option  is   ignored   if
+     PCRE_MULTILINE is set. There is no equivalent to this option
+     in Perl.
+
+       PCRE_DOTALL
+
+     If this bit is  set,  a  dot  metacharater  in  the  pattern
+     matches all characters, including newlines. Without it, new-
+     lines are excluded. This option is equivalent to  Perl's  /s
+     option.  A negative class such as [^a] always matches a new-
+     line character, independent of the setting of this option.
+
+       PCRE_EXTENDED
+
+     If this bit is set, whitespace data characters in  the  pat-
+     tern  are  totally  ignored  except when escaped or inside a
+     character class, and characters between an unescaped #  out-
+     side  a  character  class  and  the  next newline character,
+     inclusive, are also ignored. This is equivalent to Perl's /x
+     option,  and  makes  it  possible to include comments inside
+     complicated patterns. Note, however, that this applies  only
+     to  data  characters. Whitespace characters may never appear
+     within special character sequences in a pattern, for example
+     within  the sequence (?( which introduces a conditional sub-
+     pattern.
+
+       PCRE_EXTRA
+
+     This option was invented in  order  to  turn  on  additional
+     functionality of PCRE that is incompatible with Perl, but it
+     is currently of very little use. When set, any backslash  in
+     a  pattern  that is followed by a letter that has no special
+     meaning causes an error, thus reserving  these  combinations
+     for  future  expansion.  By default, as in Perl, a backslash
+     followed by a letter with no special meaning is treated as a
+     literal.  There  are at present no other features controlled
+     by this option. It can also be set by a (?X) option  setting
+     within a pattern.
+
+       PCRE_MULTILINE
+
+     By default, PCRE treats the subject string as consisting  of
+     a  single "line" of characters (even if it actually contains
+     several newlines). The "start  of  line"  metacharacter  (^)
+     matches  only  at the start of the string, while the "end of
+     line" metacharacter ($) matches  only  at  the  end  of  the
+     string,    or   before   a   terminating   newline   (unless
+     PCRE_DOLLAR_ENDONLY is set). This is the same as Perl.
+
+     When PCRE_MULTILINE it is set, the "start of line" and  "end
+     of  line"  constructs match immediately following or immedi-
+     ately before any newline  in  the  subject  string,  respec-
+     tively,  as  well  as  at  the  very  start and end. This is
+     equivalent to Perl's /m option. If there are no "\n" charac-
+     ters  in  a subject string, or no occurrences of ^ or $ in a
+     pattern, setting PCRE_MULTILINE has no effect.
+
+       PCRE_UNGREEDY
+
+     This option inverts the "greediness" of the  quantifiers  so
+     that  they  are  not greedy by default, but become greedy if
+     followed by "?". It is not compatible with Perl. It can also
+     be set by a (?U) option setting within the pattern.
+
+       PCRE_UTF8
+
+     This option causes PCRE to regard both the pattern  and  the
+     subject  as strings of UTF-8 characters instead of just byte
+     strings. However, it is available  only  if  PCRE  has  been
+     built  to  include  UTF-8  support.  If not, the use of this
+     option provokes an error. Support for UTF-8 is new,  experi-
+     mental,  and incomplete.  Details of exactly what it entails
+     are given below.
+
+
+
+STUDYING A PATTERN
+     When a pattern is going to be  used  several  times,  it  is
+     worth  spending  more time analyzing it in order to speed up
+     the time taken for matching. The function pcre_study() takes
+
+     a  pointer  to a compiled pattern as its first argument, and
+     returns a  pointer  to  a  pcre_extra  block  (another  void
+     typedef)  containing  additional  information about the pat-
+     tern; this can be passed to pcre_exec().  If  no  additional
+     information is available, NULL is returned.
+
+     The second argument contains option  bits.  At  present,  no
+     options  are  defined  for  pcre_study(),  and this argument
+     should always be zero.
+
+     The third argument for pcre_study() is a pointer to an error
+     message. If studying succeeds (even if no data is returned),
+     the variable it points to  is  set  to  NULL.  Otherwise  it
+     points to a textual error message.
+
+     At present, studying a  pattern  is  useful  only  for  non-
+     anchored  patterns  that do not have a single fixed starting
+     character. A  bitmap  of  possible  starting  characters  is
+     created.
+
+
+
+LOCALE SUPPORT
+     PCRE handles caseless matching, and determines whether char-
+     acters  are  letters, digits, or whatever, by reference to a
+     set of tables. The library contains a default set of  tables
+     which  is  created in the default C locale when PCRE is com-
+     piled.  This  is   used   when   the   final   argument   of
+     pcre_compile()  is NULL, and is sufficient for many applica-
+     tions.
+
+     An alternative set of tables can, however, be supplied. Such
+     tables  are built by calling the pcre_maketables() function,
+     which has no arguments, in the relevant locale.  The  result
+     can  then be passed to pcre_compile() as often as necessary.
+     For example, to build and use tables  that  are  appropriate
+     for  the French locale (where accented characters with codes
+     greater than 128 are treated as letters), the following code
+     could be used:
+
+       setlocale(LC_CTYPE, "fr");
+       tables = pcre_maketables();
+       re = pcre_compile(..., tables);
+
+     The  tables  are  built  in  memory  that  is  obtained  via
+     pcre_malloc.  The  pointer that is passed to pcre_compile is
+     saved with the compiled pattern, and  the  same  tables  are
+     used  via this pointer by pcre_study() and pcre_exec(). Thus
+     for any single pattern, compilation, studying  and  matching
+     all happen in the same locale, but different patterns can be
+     compiled in different locales. It is the caller's  responsi-
+     bility  to  ensure  that  the  memory  containing the tables
+     remains available for as long as it is needed.
+
+
+
+INFORMATION ABOUT A PATTERN
+     The pcre_fullinfo() function  returns  information  about  a
+     compiled pattern. It replaces the obsolete pcre_info() func-
+     tion, which is nevertheless retained for backwards compabil-
+     ity (and is documented below).
+
+     The first argument for pcre_fullinfo() is a pointer  to  the
+     compiled  pattern.  The  second  argument  is  the result of
+     pcre_study(), or NULL if the pattern was  not  studied.  The
+     third  argument  specifies  which  piece  of  information is
+     required, while the fourth argument is a pointer to a  vari-
+     able  to receive the data. The yield of the function is zero
+     for success, or one of the following negative numbers:
+
+       PCRE_ERROR_NULL       the argument code was NULL
+                             the argument where was NULL
+       PCRE_ERROR_BADMAGIC   the "magic number" was not found
+       PCRE_ERROR_BADOPTION  the value of what was invalid
+
+     The possible values for the third argument  are  defined  in
+     pcre.h, and are as follows:
+
+       PCRE_INFO_OPTIONS
+
+     Return a copy of the options with which the pattern was com-
+     piled.  The fourth argument should point to au unsigned long
+     int variable. These option bits are those specified  in  the
+     call  to  pcre_compile(),  modified  by any top-level option
+     settings  within  the   pattern   itself,   and   with   the
+     PCRE_ANCHORED  bit  forcibly  set if the form of the pattern
+     implies that it can match only at the  start  of  a  subject
+     string.
+
+       PCRE_INFO_SIZE
+
+     Return the size of the compiled pattern, that is, the  value
+     that  was  passed as the argument to pcre_malloc() when PCRE
+     was getting memory in which to place the compiled data.  The
+     fourth argument should point to a size_t variable.
+
+       PCRE_INFO_CAPTURECOUNT
+
+     Return the number of capturing subpatterns in  the  pattern.
+     The fourth argument should point to an int variable.
+
+       PCRE_INFO_BACKREFMAX
+
+     Return the number of  the  highest  back  reference  in  the
+     pattern.  The  fourth  argument should point to an int vari-
+     able. Zero is returned if there are no back references.
+
+       PCRE_INFO_FIRSTCHAR
+
+     Return information about the first character of any  matched
+     string,  for  a  non-anchored  pattern.  If there is a fixed
+     first   character,   e.g.   from   a   pattern    such    as
+     (cat|cow|coyote),  it  is returned in the integer pointed to
+     by where. Otherwise, if either
+
+     (a) the pattern was compiled with the PCRE_MULTILINE option,
+     and every branch starts with "^", or
+
+     (b) every  branch  of  the  pattern  starts  with  ".*"  and
+     PCRE_DOTALL is not set (if it were set, the pattern would be
+     anchored),
+
+     -1 is returned, indicating that the pattern matches only  at
+     the  start  of a subject string or after any "\n" within the
+     string. Otherwise -2 is returned.  For anchored patterns, -2
+     is returned.
+
+       PCRE_INFO_FIRSTTABLE
+
+     If the pattern was studied, and this resulted  in  the  con-
+     struction of a 256-bit table indicating a fixed set of char-
+     acters for the first character in  any  matching  string,  a
+     pointer   to  the  table  is  returned.  Otherwise  NULL  is
+     returned. The fourth argument should point  to  an  unsigned
+     char * variable.
+
+       PCRE_INFO_LASTLITERAL
+
+     For a non-anchored pattern, return the value of  the  right-
+     most  literal  character  which  must  exist  in any matched
+     string, other than at its start. The fourth argument  should
+     point  to an int variable. If there is no such character, or
+     if the pattern is anchored, -1 is returned. For example, for
+     the pattern /a\d+z\d+/ the returned value is 'z'.
+
+     The pcre_info() function is now obsolete because its  inter-
+     face  is  too  restrictive  to return all the available data
+     about  a  compiled  pattern.   New   programs   should   use
+     pcre_fullinfo()  instead.  The  yield  of pcre_info() is the
+     number of capturing subpatterns, or  one  of  the  following
+     negative numbers:
+
+       PCRE_ERROR_NULL       the argument code was NULL
+       PCRE_ERROR_BADMAGIC   the "magic number" was not found
+
+     If the optptr argument is not NULL, a copy  of  the  options
+     with which the pattern was compiled is placed in the integer
+     it points to (see PCRE_INFO_OPTIONS above).
+
+     If the pattern is not anchored and the firstcharptr argument
+     is  not  NULL, it is used to pass back information about the
+     first    character    of    any    matched    string    (see
+     PCRE_INFO_FIRSTCHAR above).
+
+
+
+MATCHING A PATTERN
+     The function pcre_exec() is called to match a subject string
+     against  a pre-compiled pattern, which is passed in the code
+     argument. If the pattern has been studied, the result of the
+     study should be passed in the extra argument. Otherwise this
+     must be NULL.
+
+     The PCRE_ANCHORED option can be passed in the options  argu-
+     ment,  whose unused bits must be zero. However, if a pattern
+     was  compiled  with  PCRE_ANCHORED,  or  turned  out  to  be
+     anchored  by  virtue  of  its  contents,  it  cannot be made
+     unachored at matching time.
+
+     There are also three further options that can be set only at
+     matching time:
+
+       PCRE_NOTBOL
+
+     The first character of the string is not the beginning of  a
+     line,  so  the  circumflex  metacharacter  should  not match
+     before it. Setting this without PCRE_MULTILINE  (at  compile
+     time) causes circumflex never to match.
+
+       PCRE_NOTEOL
+
+     The end of the string is not the end of a line, so the  dol-
+     lar  metacharacter should not match it nor (except in multi-
+     line mode) a newline immediately  before  it.  Setting  this
+     without PCRE_MULTILINE (at compile time) causes dollar never
+     to match.
+
+       PCRE_NOTEMPTY
+
+     An empty string is not considered to be  a  valid  match  if
+     this  option  is  set. If there are alternatives in the pat-
+     tern, they are tried. If  all  the  alternatives  match  the
+     empty  string,  the  entire match fails. For example, if the
+     pattern
+
+       a?b?
+
+     is applied to a string not beginning with  "a"  or  "b",  it
+     matches  the  empty string at the start of the subject. With
+     PCRE_NOTEMPTY set, this match is not valid, so PCRE searches
+     further into the string for occurrences of "a" or "b".
+
+     Perl has no direct equivalent of PCRE_NOTEMPTY, but it  does
+     make  a  special case of a pattern match of the empty string
+     within its split() function, and when using the /g modifier.
+     It  is possible to emulate Perl's behaviour after matching a
+     null string by first trying the  match  again  at  the  same
+     offset  with  PCRE_NOTEMPTY  set,  and then if that fails by
+     advancing the starting offset  (see  below)  and  trying  an
+     ordinary match again.
+
+     The subject string is passed as  a  pointer  in  subject,  a
+     length  in  length,  and  a  starting offset in startoffset.
+     Unlike the pattern string, it may contain binary zero  char-
+     acters.  When  the starting offset is zero, the search for a
+     match starts at the beginning of the subject, and this is by
+     far the most common case.
+
+     A non-zero starting offset  is  useful  when  searching  for
+     another  match  in  the  same subject by calling pcre_exec()
+     again after a previous success.  Setting startoffset differs
+     from  just  passing  over  a  shortened  string  and setting
+     PCRE_NOTBOL in the case of a pattern that  begins  with  any
+     kind of lookbehind. For example, consider the pattern
+
+       \Biss\B
+
+     which finds occurrences of "iss" in the middle of words. (\B
+     matches only if the current position in the subject is not a
+     word boundary.) When applied to the string "Mississipi"  the
+     first  call  to  pcre_exec()  finds the first occurrence. If
+     pcre_exec() is called again with just the remainder  of  the
+     subject,  namely  "issipi", it does not match, because \B is
+     always false at the start of the subject, which is deemed to
+     be  a  word  boundary. However, if pcre_exec() is passed the
+     entire string again, but with startoffset set to 4, it finds
+     the  second  occurrence  of "iss" because it is able to look
+     behind the starting point to discover that it is preceded by
+     a letter.
+
+     If a non-zero starting offset is passed when the pattern  is
+     anchored, one attempt to match at the given offset is tried.
+     This can only succeed if the pattern does  not  require  the
+     match to be at the start of the subject.
+
+     In general, a pattern matches a certain portion of the  sub-
+     ject,  and  in addition, further substrings from the subject
+     may be picked out by parts of  the  pattern.  Following  the
+     usage  in  Jeffrey Friedl's book, this is called "capturing"
+     in what follows, and the phrase  "capturing  subpattern"  is
+     used for a fragment of a pattern that picks out a substring.
+     PCRE supports several other kinds of  parenthesized  subpat-
+     tern that do not cause substrings to be captured.
+
+     Captured substrings are returned to the caller via a  vector
+     of  integer  offsets whose address is passed in ovector. The
+     number of elements in the vector is passed in ovecsize.  The
+     first two-thirds of the vector is used to pass back captured
+     substrings, each substring using a  pair  of  integers.  The
+     remaining  third  of  the  vector  is  used  as workspace by
+     pcre_exec() while matching capturing subpatterns, and is not
+     available for passing back information. The length passed in
+     ovecsize should always be a multiple of three. If it is not,
+     it is rounded down.
+
+     When a match has been successful, information about captured
+     substrings is returned in pairs of integers, starting at the
+     beginning of ovector, and continuing up to two-thirds of its
+     length  at  the  most. The first element of a pair is set to
+     the offset of the first character in a  substring,  and  the
+     second is set to the offset of the first character after the
+     end of a substring. The first  pair,  ovector[0]  and  ovec-
+     tor[1],  identify  the portion of the subject string matched
+     by the entire pattern. The next pair is used for  the  first
+     capturing  subpattern,  and  so  on.  The  value returned by
+     pcre_exec() is the number of pairs that have  been  set.  If
+     there  are no capturing subpatterns, the return value from a
+     successful match is 1, indicating that just the  first  pair
+     of offsets has been set.
+
+     Some convenience functions are provided for  extracting  the
+     captured substrings as separate strings. These are described
+     in the following section.
+
+     It is possible for an capturing  subpattern  number  n+1  to
+     match  some  part  of  the subject when subpattern n has not
+     been used at all.  For  example,  if  the  string  "abc"  is
+     matched  against the pattern (a|(z))(bc) subpatterns 1 and 3
+     are matched, but 2 is not. When this  happens,  both  offset
+     values corresponding to the unused subpattern are set to -1.
+
+     If a capturing subpattern is matched repeatedly, it  is  the
+     last  portion  of  the  string  that  it  matched  that gets
+     returned.
+
+     If the vector is too small to hold  all  the  captured  sub-
+     strings,  it is used as far as possible (up to two-thirds of
+     its length), and the function returns a value  of  zero.  In
+     particular,  if  the  substring offsets are not of interest,
+     pcre_exec() may be called with ovector passed  as  NULL  and
+     ovecsize  as  zero.  However,  if  the pattern contains back
+     references and the ovector isn't big enough to remember  the
+     related  substrings,  PCRE  has to get additional memory for
+     use during matching. Thus it is usually advisable to  supply
+     an ovector.
+
+     Note that pcre_info() can be used to find out how many  cap-
+     turing  subpatterns  there  are  in  a compiled pattern. The
+     smallest size for ovector that will  allow  for  n  captured
+     substrings  in  addition  to  the  offsets  of the substring
+     matched by the whole pattern is (n+1)*3.
+
+     If pcre_exec() fails, it returns a negative number. The fol-
+     lowing are defined in the header file:
+
+       PCRE_ERROR_NOMATCH        (-1)
+
+     The subject string did not match the pattern.
+
+       PCRE_ERROR_NULL           (-2)
+
+     Either code or subject was passed as NULL,  or  ovector  was
+     NULL and ovecsize was not zero.
+
+       PCRE_ERROR_BADOPTION      (-3)
+
+     An unrecognized bit was set in the options argument.
+
+       PCRE_ERROR_BADMAGIC       (-4)
+
+     PCRE stores a 4-byte "magic number" at the start of the com-
+     piled  code,  to  catch  the  case  when it is passed a junk
+     pointer. This is the error it gives when  the  magic  number
+     isn't present.
+
+       PCRE_ERROR_UNKNOWN_NODE   (-5)
+
+     While running the pattern match, an unknown item was encoun-
+     tered in the compiled pattern. This error could be caused by
+     a bug in PCRE or by overwriting of the compiled pattern.
+
+       PCRE_ERROR_NOMEMORY       (-6)
+
+     If a pattern contains back references, but the ovector  that
+     is  passed  to pcre_exec() is not big enough to remember the
+     referenced substrings, PCRE gets a block of  memory  at  the
+     start  of  matching to use for this purpose. If the call via
+     pcre_malloc() fails, this error  is  given.  The  memory  is
+     freed at the end of matching.
+
+
+
+EXTRACTING CAPTURED SUBSTRINGS
+     Captured substrings can be accessed directly  by  using  the
+
+
+
+
+
+SunOS 5.8                 Last change:                         12
+
+
+
+     offsets returned by pcre_exec() in ovector. For convenience,
+     the functions  pcre_copy_substring(),  pcre_get_substring(),
+     and  pcre_get_substring_list()  are  provided for extracting
+     captured  substrings  as  new,   separate,   zero-terminated
+     strings.   A  substring  that  contains  a  binary  zero  is
+     correctly extracted and has a further zero added on the end,
+     but the result does not, of course, function as a C string.
+
+     The first three arguments are the same for all  three  func-
+     tions:  subject  is  the  subject string which has just been
+     successfully matched, ovector is a pointer to the vector  of
+     integer   offsets   that  was  passed  to  pcre_exec(),  and
+     stringcount is the number of substrings that  were  captured
+     by  the  match,  including  the  substring  that matched the
+     entire regular expression. This is  the  value  returned  by
+     pcre_exec  if  it  is  greater  than  zero.  If  pcre_exec()
+     returned zero, indicating that it ran out of space in  ovec-
+     tor,  the  value passed as stringcount should be the size of
+     the vector divided by three.
+
+     The functions pcre_copy_substring() and pcre_get_substring()
+     extract a single substring, whose number is given as string-
+     number. A value of zero extracts the substring that  matched
+     the entire pattern, while higher values extract the captured
+     substrings. For pcre_copy_substring(), the string is  placed
+     in  buffer,  whose  length is given by buffersize, while for
+     pcre_get_substring() a new block of memory is  obtained  via
+     pcre_malloc,  and its address is returned via stringptr. The
+     yield of the function is  the  length  of  the  string,  not
+     including the terminating zero, or one of
+
+       PCRE_ERROR_NOMEMORY       (-6)
+
+     The buffer was too small for pcre_copy_substring(),  or  the
+     attempt to get memory failed for pcre_get_substring().
+
+       PCRE_ERROR_NOSUBSTRING    (-7)
+
+     There is no substring whose number is stringnumber.
+
+     The pcre_get_substring_list() function extracts  all  avail-
+     able  substrings  and builds a list of pointers to them. All
+     this is done in a single block of memory which  is  obtained
+     via pcre_malloc. The address of the memory block is returned
+     via listptr, which is also the start of the list  of  string
+     pointers.  The  end of the list is marked by a NULL pointer.
+     The yield of the function is zero if all went well, or
+
+       PCRE_ERROR_NOMEMORY       (-6)
+
+     if the attempt to get the memory block failed.
+
+     When any of these functions encounter a  substring  that  is
+     unset, which can happen when capturing subpattern number n+1
+     matches some part of the subject, but subpattern n  has  not
+     been  used  at all, they return an empty string. This can be
+     distinguished  from  a  genuine  zero-length  substring   by
+     inspecting the appropriate offset in ovector, which is nega-
+     tive for unset substrings.
+
+     The  two  convenience  functions  pcre_free_substring()  and
+     pcre_free_substring_list()  can  be  used to free the memory
+     returned by  a  previous  call  of  pcre_get_substring()  or
+     pcre_get_substring_list(),  respectively.  They  do  nothing
+     more than call the function pointed to by  pcre_free,  which
+     of  course  could  be called directly from a C program. How-
+     ever, PCRE is used in some situations where it is linked via
+     a  special  interface  to another programming language which
+     cannot use pcre_free directly; it is for  these  cases  that
+     the functions are provided.
+
+
+
+LIMITATIONS
+     There are some size limitations in PCRE but it is hoped that
+     they will never in practice be relevant.  The maximum length
+     of a compiled pattern is 65539 (sic) bytes.  All  values  in
+     repeating  quantifiers must be less than 65536.  The maximum
+     number of capturing subpatterns is 99.  The  maximum  number
+     of  all  parenthesized subpatterns, including capturing sub-
+     patterns, assertions, and other types of subpattern, is 200.
+
+     The maximum length of a subject string is the largest  posi-
+     tive number that an integer variable can hold. However, PCRE
+     uses recursion to handle subpatterns and indefinite  repeti-
+     tion.  This  means  that the available stack space may limit
+     the size of a subject string that can be processed  by  cer-
+     tain patterns.
+
+
+
+DIFFERENCES FROM PERL
+     The differences described here  are  with  respect  to  Perl
+     5.005.
+
+     1. By default, a whitespace character is any character  that
+     the  C  library  function isspace() recognizes, though it is
+     possible to compile PCRE  with  alternative  character  type
+     tables. Normally isspace() matches space, formfeed, newline,
+     carriage return, horizontal tab, and vertical tab. Perl 5 no
+     longer  includes vertical tab in its set of whitespace char-
+     acters. The \v escape that was in the Perl documentation for
+     a long time was never in fact recognized. However, the char-
+     acter itself was treated as whitespace at least up to 5.002.
+     In 5.004 and 5.005 it does not match \s.
+
+     2. PCRE does  not  allow  repeat  quantifiers  on  lookahead
+     assertions. Perl permits them, but they do not mean what you
+     might think. For example, (?!a){3} does not assert that  the
+     next  three characters are not "a". It just asserts that the
+     next character is not "a" three times.
+
+     3. Capturing subpatterns that occur inside  negative  looka-
+     head  assertions  are  counted,  but  their  entries  in the
+     offsets vector are never set. Perl sets its numerical  vari-
+     ables  from  any  such  patterns that are matched before the
+     assertion fails to match something (thereby succeeding), but
+     only  if  the negative lookahead assertion contains just one
+     branch.
+
+     4. Though binary zero characters are supported in  the  sub-
+     ject  string,  they  are  not  allowed  in  a pattern string
+     because it is passed as a normal  C  string,  terminated  by
+     zero. The escape sequence "\0" can be used in the pattern to
+     represent a binary zero.
+
+     5. The following Perl escape sequences  are  not  supported:
+     \l,  \u,  \L,  \U,  \E, \Q. In fact these are implemented by
+     Perl's general string-handling and are not part of its  pat-
+     tern matching engine.
+
+     6. The Perl \G assertion is  not  supported  as  it  is  not
+     relevant to single pattern matches.
+
+     7. Fairly obviously, PCRE does not support the (?{code}) and
+     (?p{code})  constructions. However, there is some experimen-
+     tal support for recursive patterns using the  non-Perl  item
+     (?R).
+
+     8. There are at the time of writing some  oddities  in  Perl
+     5.005_02  concerned  with  the  settings of captured strings
+     when part of a pattern is repeated.  For  example,  matching
+     "aba"  against the pattern /^(a(b)?)+$/ sets $2 to the value
+     "b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves  $2
+     unset.    However,    if   the   pattern   is   changed   to
+     /^(aa(b(b))?)+$/ then $2 (and $3) are set.
+
+     In Perl 5.004 $2 is set in both cases, and that is also true
+     of PCRE. If in the future Perl changes to a consistent state
+     that is different, PCRE may change to follow.
+
+     9. Another as yet unresolved discrepancy  is  that  in  Perl
+     5.005_02  the  pattern /^(a)?(?(1)a|b)+$/ matches the string
+     "a", whereas in PCRE it does not.  However, in both Perl and
+     PCRE /^(a)?a/ matched against "a" leaves $1 unset.
+
+     10. PCRE  provides  some  extensions  to  the  Perl  regular
+     expression facilities:
+
+     (a) Although lookbehind assertions must match  fixed  length
+     strings,  each  alternative branch of a lookbehind assertion
+     can match a different length of string. Perl 5.005  requires
+     them all to have the same length.
+
+     (b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is  not
+     set,  the  $ meta- character matches only at the very end of
+     the string.
+
+     (c) If PCRE_EXTRA is set, a backslash followed by  a  letter
+     with no special meaning is faulted.
+
+     (d) If PCRE_UNGREEDY is set, the greediness of  the  repeti-
+     tion  quantifiers  is inverted, that is, by default they are
+     not greedy, but if followed by a question mark they are.
+
+     (e) PCRE_ANCHORED can be used to force a pattern to be tried
+     only at the start of the subject.
+
+     (f) The PCRE_NOTBOL, PCRE_NOTEOL, and PCRE_NOTEMPTY  options
+     for pcre_exec() have no Perl equivalents.
+
+     (g) The (?R) construct allows for recursive pattern matching
+     (Perl  5.6 can do this using the (?p{code}) construct, which
+     PCRE cannot of course support.)
+
+
+
+REGULAR EXPRESSION DETAILS
+     The syntax and semantics of  the  regular  expressions  sup-
+     ported  by PCRE are described below. Regular expressions are
+     also described in the Perl documentation and in a number  of
+     other  books,  some  of which have copious examples. Jeffrey
+     Friedl's  "Mastering  Regular  Expressions",  published   by
+     O'Reilly (ISBN 1-56592-257), covers them in great detail.
+
+     The description here is intended as reference documentation.
+     The basic operation of PCRE is on strings of bytes. However,
+     there is the beginnings of some support for UTF-8  character
+     strings.  To  use  this  support  you must configure PCRE to
+     include it, and then call pcre_compile() with the  PCRE_UTF8
+     option.  How  this affects the pattern matching is described
+     in the final section of this document.
+
+     A regular expression is a pattern that is matched against  a
+     subject string from left to right. Most characters stand for
+     themselves in a pattern, and match the corresponding charac-
+     ters in the subject. As a trivial example, the pattern
+
+       The quick brown fox
+
+     matches a portion of a subject string that is  identical  to
+     itself.  The  power  of  regular  expressions comes from the
+     ability to include alternatives and repetitions in the  pat-
+     tern.  These  are encoded in the pattern by the use of meta-
+     characters, which do not stand for  themselves  but  instead
+     are interpreted in some special way.
+
+     There are two different sets of meta-characters: those  that
+     are  recognized anywhere in the pattern except within square
+     brackets, and those that are recognized in square  brackets.
+     Outside square brackets, the meta-characters are as follows:
+
+       \      general escape character with several uses
+       ^      assert start of  subject  (or  line,  in  multiline
+     mode)
+       $      assert end of subject (or line, in multiline mode)
+       .      match any character except newline (by default)
+       [      start character class definition
+       |      start of alternative branch
+       (      start subpattern
+       )      end subpattern
+       ?      extends the meaning of (
+              also 0 or 1 quantifier
+              also quantifier minimizer
+       *      0 or more quantifier
+       +      1 or more quantifier
+       {      start min/max quantifier
+
+     Part of a pattern that is in square  brackets  is  called  a
+     "character  class".  In  a  character  class  the only meta-
+     characters are:
+
+       \      general escape character
+       ^      negate the class, but only if the first character
+       -      indicates character range
+       ]      terminates the character class
+
+     The following sections describe  the  use  of  each  of  the
+     meta-characters.
+
+
+
+BACKSLASH
+     The backslash character has several uses. Firstly, if it  is
+     followed  by  a  non-alphameric character, it takes away any
+     special  meaning  that  character  may  have.  This  use  of
+     backslash  as  an  escape  character applies both inside and
+     outside character classes.
+
+     For example, if you want to match a "*" character, you write
+     "\*" in the pattern. This applies whether or not the follow-
+     ing character would otherwise  be  interpreted  as  a  meta-
+     character,  so it is always safe to precede a non-alphameric
+     with "\" to specify that it stands for itself.  In  particu-
+     lar, if you want to match a backslash, you write "\\".
+
+     If a pattern is compiled with the PCRE_EXTENDED option, whi-
+     tespace in the pattern (other than in a character class) and
+     characters between a "#" outside a character class  and  the
+     next  newline  character  are ignored. An escaping backslash
+     can be used to include a whitespace or "#" character as part
+     of the pattern.
+
+     A second use of backslash provides a way  of  encoding  non-
+     printing  characters  in patterns in a visible manner. There
+     is no restriction on the appearance of non-printing  charac-
+     ters,  apart from the binary zero that terminates a pattern,
+     but when a pattern is being prepared by text editing, it  is
+     usually  easier to use one of the following escape sequences
+     than the binary character it represents:
+
+       \a     alarm, that is, the BEL character (hex 07)
+       \cx    "control-x", where x is any character
+       \e     escape (hex 1B)
+       \f     formfeed (hex 0C)
+       \n     newline (hex 0A)
+       \r     carriage return (hex 0D)
+       \t     tab (hex 09)
+       \xhh   character with hex code hh
+       \ddd   character with octal code ddd, or backreference
+
+     The precise effect of "\cx" is as follows: if "x" is a lower
+     case  letter,  it  is converted to upper case. Then bit 6 of
+     the character (hex 40) is inverted.  Thus "\cz" becomes  hex
+     1A, but "\c{" becomes hex 3B, while "\c;" becomes hex 7B.
+
+     After "\x", up to two hexadecimal digits are  read  (letters
+     can be in upper or lower case).
+
+     After "\0" up to two further octal digits are read. In  both
+     cases,  if  there are fewer than two digits, just those that
+     are present are used. Thus the sequence "\0\x\07"  specifies
+     two binary zeros followed by a BEL character.  Make sure you
+     supply two digits after the initial zero  if  the  character
+     that follows is itself an octal digit.
+
+     The handling of a backslash followed by a digit other than 0
+     is  complicated.   Outside  a character class, PCRE reads it
+     and any following digits as a decimal number. If the  number
+     is  less  than  10, or if there have been at least that many
+     previous capturing left parentheses in the  expression,  the
+     entire  sequence is taken as a back reference. A description
+     of how this works is given later, following  the  discussion
+     of parenthesized subpatterns.
+
+     Inside a character  class,  or  if  the  decimal  number  is
+     greater  than  9 and there have not been that many capturing
+     subpatterns, PCRE re-reads up to three octal digits  follow-
+     ing  the  backslash,  and  generates  a single byte from the
+     least significant 8 bits of the value. Any subsequent digits
+     stand for themselves.  For example:
+
+       \040   is another way of writing a space
+       \40    is the same, provided there are fewer than 40
+                 previous capturing subpatterns
+       \7     is always a back reference
+       \11    might be a back reference, or another way of
+                 writing a tab
+       \011   is always a tab
+       \0113  is a tab followed by the character "3"
+       \113   is the character with octal code 113 (since there
+                 can be no more than 99 back references)
+       \377   is a byte consisting entirely of 1 bits
+       \81    is either a back reference, or a binary zero
+                 followed by the two characters "8" and "1"
+
+     Note that octal values of 100 or greater must not be  intro-
+     duced  by  a  leading zero, because no more than three octal
+     digits are ever read.
+
+     All the sequences that define a single  byte  value  can  be
+     used both inside and outside character classes. In addition,
+     inside a character class, the sequence "\b"  is  interpreted
+     as  the  backspace  character  (hex 08). Outside a character
+     class it has a different meaning (see below).
+
+     The third use of backslash is for specifying generic charac-
+     ter types:
+
+       \d     any decimal digit
+       \D     any character that is not a decimal digit
+       \s     any whitespace character
+       \S     any character that is not a whitespace character
+       \w     any "word" character
+       \W     any "non-word" character
+
+     Each pair of escape sequences partitions the complete set of
+     characters  into  two  disjoint  sets.  Any  given character
+     matches one, and only one, of each pair.
+
+     A "word" character is any letter or digit or the  underscore
+     character,  that  is,  any  character which can be part of a
+     Perl "word". The definition of letters and  digits  is  con-
+     trolled  by PCRE's character tables, and may vary if locale-
+     specific matching is  taking  place  (see  "Locale  support"
+     above). For example, in the "fr" (French) locale, some char-
+     acter codes greater than 128 are used for accented  letters,
+     and these are matched by \w.
+
+     These character type sequences can appear  both  inside  and
+     outside  character classes. They each match one character of
+     the appropriate type. If the current matching  point  is  at
+     the end of the subject string, all of them fail, since there
+     is no character to match.
+
+     The fourth use of backslash is  for  certain  simple  asser-
+     tions. An assertion specifies a condition that has to be met
+     at a particular point in  a  match,  without  consuming  any
+     characters  from  the subject string. The use of subpatterns
+     for more complicated  assertions  is  described  below.  The
+     backslashed assertions are
+
+       \b     word boundary
+       \B     not a word boundary
+       \A     start of subject (independent of multiline mode)
+       \Z     end of subject or newline at  end  (independent  of
+     multiline mode)
+       \z     end of subject (independent of multiline mode)
+
+     These assertions may not appear in  character  classes  (but
+     note that "\b" has a different meaning, namely the backspace
+     character, inside a character class).
+
+     A word boundary is a position in the  subject  string  where
+     the current character and the previous character do not both
+     match \w or \W (i.e. one matches \w and  the  other  matches
+     \W),  or the start or end of the string if the first or last
+     character matches \w, respectively.
+
+     The \A, \Z, and \z assertions differ  from  the  traditional
+     circumflex  and  dollar  (described below) in that they only
+     ever match at the very start and end of the subject  string,
+     whatever  options  are  set.  They  are  not affected by the
+     PCRE_NOTBOL or PCRE_NOTEOL options. If the startoffset argu-
+     ment  of  pcre_exec()  is  non-zero, \A can never match. The
+     difference between \Z and \z is that  \Z  matches  before  a
+     newline  that is the last character of the string as well as
+     at the end of the string, whereas \z  matches  only  at  the
+     end.
+
+
+
+CIRCUMFLEX AND DOLLAR
+     Outside a character class, in the default matching mode, the
+     circumflex  character  is an assertion which is true only if
+     the current matching point is at the start  of  the  subject
+
+     string.  If  the startoffset argument of pcre_exec() is non-
+     zero, circumflex can never match. Inside a character  class,
+     circumflex has an entirely different meaning (see below).
+
+     Circumflex need not be the first character of the pattern if
+     a  number of alternatives are involved, but it should be the
+     first thing in each alternative in which it appears  if  the
+     pattern is ever to match that branch. If all possible alter-
+     natives start with a circumflex, that is, if the pattern  is
+     constrained to match only at the start of the subject, it is
+     said to be an "anchored" pattern. (There are also other con-
+     structs that can cause a pattern to be anchored.)
+
+     A dollar character is an assertion which is true only if the
+     current  matching point is at the end of the subject string,
+     or immediately before a newline character that is  the  last
+     character in the string (by default). Dollar need not be the
+     last character of the pattern if a  number  of  alternatives
+     are  involved,  but it should be the last item in any branch
+     in which it appears.  Dollar has no  special  meaning  in  a
+     character class.
+
+     The meaning of dollar can be changed so that it matches only
+     at   the   very   end   of   the   string,  by  setting  the
+     PCRE_DOLLAR_ENDONLY option at compile or matching time. This
+     does not affect the \Z assertion.
+
+     The meanings of the circumflex  and  dollar  characters  are
+     changed  if  the  PCRE_MULTILINE option is set. When this is
+     the case,  they  match  immediately  after  and  immediately
+     before an internal "\n" character, respectively, in addition
+     to matching at the start and end of the subject string.  For
+     example,  the  pattern  /^abc$/  matches  the subject string
+     "def\nabc" in multiline  mode,  but  not  otherwise.  Conse-
+     quently,  patterns  that  are  anchored  in single line mode
+     because all branches start with "^" are not anchored in mul-
+     tiline mode, and a match for circumflex is possible when the
+     startoffset  argument  of  pcre_exec()  is   non-zero.   The
+     PCRE_DOLLAR_ENDONLY  option  is ignored if PCRE_MULTILINE is
+     set.
+
+     Note that the sequences \A, \Z, and \z can be used to  match
+     the  start  and end of the subject in both modes, and if all
+     branches of a pattern start with \A is it  always  anchored,
+     whether PCRE_MULTILINE is set or not.
+
+
+
+FULL STOP (PERIOD, DOT)
+     Outside a character class, a dot in the pattern matches  any
+     one character in the subject, including a non-printing char-
+     acter, but not (by default)  newline.   If  the  PCRE_DOTALL
+
+     option  is set, dots match newlines as well. The handling of
+     dot is entirely independent of the  handling  of  circumflex
+     and  dollar,  the  only  relationship  being  that they both
+     involve newline characters. Dot has no special meaning in  a
+     character class.
+
+
+
+SQUARE BRACKETS
+     An opening square bracket introduces a character class, ter-
+     minated  by  a  closing  square  bracket.  A  closing square
+     bracket on its own is  not  special.  If  a  closing  square
+     bracket  is  required as a member of the class, it should be
+     the first data character in the class (after an initial cir-
+     cumflex, if present) or escaped with a backslash.
+
+     A character class matches a single character in the subject;
+     the  character  must  be in the set of characters defined by
+     the class, unless the first character in the class is a cir-
+     cumflex,  in which case the subject character must not be in
+     the set defined by the class. If a  circumflex  is  actually
+     required  as  a  member  of  the class, ensure it is not the
+     first character, or escape it with a backslash.
+
+     For example, the character class [aeiou] matches  any  lower
+     case vowel, while [^aeiou] matches any character that is not
+     a lower case vowel. Note that a circumflex is  just  a  con-
+     venient  notation for specifying the characters which are in
+     the class by enumerating those that are not. It  is  not  an
+     assertion:  it  still  consumes a character from the subject
+     string, and fails if the current pointer is at  the  end  of
+     the string.
+
+     When caseless matching  is  set,  any  letters  in  a  class
+     represent  both their upper case and lower case versions, so
+     for example, a caseless [aeiou] matches "A" as well as  "a",
+     and  a caseless [^aeiou] does not match "A", whereas a case-
+     ful version would.
+
+     The newline character is never treated in any special way in
+     character  classes,  whatever the setting of the PCRE_DOTALL
+     or PCRE_MULTILINE options is. A  class  such  as  [^a]  will
+     always match a newline.
+
+     The minus (hyphen) character can be used to specify a  range
+     of  characters  in  a  character  class.  For example, [d-m]
+     matches any letter between d and m, inclusive.  If  a  minus
+     character  is required in a class, it must be escaped with a
+     backslash or appear in a position where it cannot be  inter-
+     preted as indicating a range, typically as the first or last
+     character in the class.
+
+     It is not possible to have the literal character "]" as  the
+     end  character  of  a  range.  A  pattern such as [W-]46] is
+     interpreted as a class of two characters ("W" and "-")  fol-
+     lowed by a literal string "46]", so it would match "W46]" or
+     "-46]". However, if the "]" is escaped with a  backslash  it
+     is  interpreted  as  the end of range, so [W-\]46] is inter-
+     preted as a single class containing a range followed by  two
+     separate characters. The octal or hexadecimal representation
+     of "]" can also be used to end a range.
+
+     Ranges operate in ASCII collating sequence. They can also be
+     used  for  characters  specified  numerically,  for  example
+     [\000-\037]. If a range that includes letters is  used  when
+     caseless  matching  is set, it matches the letters in either
+     case. For example, [W-c] is equivalent  to  [][\^_`wxyzabc],
+     matched  caselessly,  and  if  character tables for the "fr"
+     locale are in use, [\xc8-\xcb] matches accented E characters
+     in both cases.
+
+     The character types \d, \D, \s, \S,  \w,  and  \W  may  also
+     appear  in  a  character  class, and add the characters that
+     they match to the class. For example, [\dABCDEF] matches any
+     hexadecimal  digit.  A  circumflex  can conveniently be used
+     with the upper case character types to specify a  more  res-
+     tricted set of characters than the matching lower case type.
+     For example, the class [^\W_] matches any letter  or  digit,
+     but not underscore.
+
+     All non-alphameric characters other than \,  -,  ^  (at  the
+     start)  and  the  terminating ] are non-special in character
+     classes, but it does no harm if they are escaped.
+
+
+
+POSIX CHARACTER CLASSES
+     Perl 5.6 (not yet released at the time of writing) is  going
+     to  support  the POSIX notation for character classes, which
+     uses names enclosed by  [:  and  :]   within  the  enclosing
+     square brackets. PCRE supports this notation. For example,
+
+       [01[:alpha:]%]
+
+     matches "0", "1", any alphabetic character, or "%". The sup-
+     ported class names are
+
+       alnum    letters and digits
+       alpha    letters
+       ascii    character codes 0 - 127
+       cntrl    control characters
+       digit    decimal digits (same as \d)
+       graph    printing characters, excluding space
+       lower    lower case letters
+       print    printing characters, including space
+       punct    printing characters, excluding letters and digits
+       space    white space (same as \s)
+       upper    upper case letters
+       word     "word" characters (same as \w)
+       xdigit   hexadecimal digits
+
+     The names "ascii" and "word" are  Perl  extensions.  Another
+     Perl  extension is negation, which is indicated by a ^ char-
+     acter after the colon. For example,
+
+       [12[:^digit:]]
+
+     matches "1", "2", or any non-digit.  PCRE  (and  Perl)  also
+     recogize  the POSIX syntax [.ch.] and [=ch=] where "ch" is a
+     "collating element", but these are  not  supported,  and  an
+     error is given if they are encountered.
+
+
+
+VERTICAL BAR
+     Vertical bar characters are  used  to  separate  alternative
+     patterns. For example, the pattern
+
+       gilbert|sullivan
+
+     matches either "gilbert" or "sullivan". Any number of alter-
+     natives  may  appear,  and an empty alternative is permitted
+     (matching the empty string).   The  matching  process  tries
+     each  alternative in turn, from left to right, and the first
+     one that succeeds is used. If the alternatives are within  a
+     subpattern  (defined  below),  "succeeds" means matching the
+     rest of the main pattern as well as the alternative  in  the
+     subpattern.
+
+
+
+INTERNAL OPTION SETTING
+     The settings of PCRE_CASELESS, PCRE_MULTILINE,  PCRE_DOTALL,
+     and  PCRE_EXTENDED can be changed from within the pattern by
+     a sequence of Perl option letters enclosed between "(?"  and
+     ")". The option letters are
+
+       i  for PCRE_CASELESS
+       m  for PCRE_MULTILINE
+       s  for PCRE_DOTALL
+       x  for PCRE_EXTENDED
+
+     For example, (?im) sets caseless, multiline matching. It  is
+     also possible to unset these options by preceding the letter
+     with a hyphen, and a combined setting and unsetting such  as
+     (?im-sx),  which sets PCRE_CASELESS and PCRE_MULTILINE while
+     unsetting PCRE_DOTALL and PCRE_EXTENDED, is also  permitted.
+     If  a  letter  appears both before and after the hyphen, the
+     option is unset.
+
+     The scope of these option changes depends on  where  in  the
+     pattern  the  setting  occurs. For settings that are outside
+     any subpattern (defined below), the effect is the same as if
+     the  options were set or unset at the start of matching. The
+     following patterns all behave in exactly the same way:
+
+       (?i)abc
+       a(?i)bc
+       ab(?i)c
+       abc(?i)
+
+     which in turn is the same as compiling the pattern abc  with
+     PCRE_CASELESS  set.   In  other words, such "top level" set-
+     tings apply to the whole pattern  (unless  there  are  other
+     changes  inside subpatterns). If there is more than one set-
+     ting of the same option at top level, the rightmost  setting
+     is used.
+
+     If an option change occurs inside a subpattern,  the  effect
+     is  different.  This is a change of behaviour in Perl 5.005.
+     An option change inside a subpattern affects only that  part
+     of the subpattern that follows it, so
+
+       (a(?i)b)c
+
+     matches  abc  and  aBc  and  no  other   strings   (assuming
+     PCRE_CASELESS  is  not used).  By this means, options can be
+     made to have different settings in different  parts  of  the
+     pattern.  Any  changes  made  in one alternative do carry on
+     into subsequent branches within  the  same  subpattern.  For
+     example,
+
+       (a(?i)b|c)
+
+     matches "ab", "aB", "c", and "C", even though when  matching
+     "C" the first branch is abandoned before the option setting.
+     This is because the effects of  option  settings  happen  at
+     compile  time. There would be some very weird behaviour oth-
+     erwise.
+
+     The PCRE-specific options PCRE_UNGREEDY and  PCRE_EXTRA  can
+     be changed in the same way as the Perl-compatible options by
+     using the characters U and X  respectively.  The  (?X)  flag
+     setting  is  special in that it must always occur earlier in
+     the pattern than any of the additional features it turns on,
+     even when it is at top level. It is best put at the start.
+
+
+
+SUBPATTERNS
+     Subpatterns are delimited by parentheses  (round  brackets),
+     which can be nested.  Marking part of a pattern as a subpat-
+     tern does two things:
+
+     1. It localizes a set of alternatives. For example, the pat-
+     tern
+
+       cat(aract|erpillar|)
+
+     matches one of the words "cat",  "cataract",  or  "caterpil-
+     lar".  Without  the  parentheses, it would match "cataract",
+     "erpillar" or the empty string.
+
+     2. It sets up the subpattern as a capturing  subpattern  (as
+     defined  above).   When the whole pattern matches, that por-
+     tion of the subject string that matched  the  subpattern  is
+     passed  back  to  the  caller  via  the  ovector argument of
+     pcre_exec(). Opening parentheses are counted  from  left  to
+     right (starting from 1) to obtain the numbers of the captur-
+     ing subpatterns.
+
+     For example, if the string "the red king" is matched against
+     the pattern
+
+       the ((red|white) (king|queen))
+
+     the captured substrings are "red king", "red",  and  "king",
+     and are numbered 1, 2, and 3.
+
+     The fact that plain parentheses fulfil two functions is  not
+     always  helpful.  There are often times when a grouping sub-
+     pattern is required without a capturing requirement.  If  an
+     opening parenthesis is followed by "?:", the subpattern does
+     not do any capturing, and is not counted when computing  the
+     number of any subsequent capturing subpatterns. For example,
+     if the string "the white queen" is matched against the  pat-
+     tern
+
+       the ((?:red|white) (king|queen))
+
+     the captured substrings are "white queen" and  "queen",  and
+     are  numbered  1  and 2. The maximum number of captured sub-
+     strings is 99, and the maximum number  of  all  subpatterns,
+     both capturing and non-capturing, is 200.
+
+     As a  convenient  shorthand,  if  any  option  settings  are
+     required  at  the  start  of a non-capturing subpattern, the
+     option letters may appear between the "?" and the ":".  Thus
+     the two patterns
+
+       (?i:saturday|sunday)
+       (?:(?i)saturday|sunday)
+
+     match exactly the same set of strings.  Because  alternative
+     branches  are  tried from left to right, and options are not
+     reset until the end of the subpattern is reached, an  option
+     setting  in  one  branch does affect subsequent branches, so
+     the above patterns match "SUNDAY" as well as "Saturday".
+
+
+
+REPETITION
+     Repetition is specified by quantifiers, which can follow any
+     of the following items:
+
+       a single character, possibly escaped
+       the . metacharacter
+       a character class
+       a back reference (see next section)
+       a parenthesized subpattern (unless it is  an  assertion  -
+     see below)
+
+     The general repetition quantifier specifies  a  minimum  and
+     maximum  number  of  permitted  matches,  by  giving the two
+     numbers in curly brackets (braces), separated  by  a  comma.
+     The  numbers  must be less than 65536, and the first must be
+     less than or equal to the second. For example:
+
+       z{2,4}
+
+     matches "zz", "zzz", or "zzzz". A closing brace on  its  own
+     is not a special character. If the second number is omitted,
+     but the comma is present, there is no upper  limit;  if  the
+     second number and the comma are both omitted, the quantifier
+     specifies an exact number of required matches. Thus
+
+       [aeiou]{3,}
+
+     matches at least 3 successive vowels,  but  may  match  many
+     more, while
+
+       \d{8}
+
+     matches exactly 8 digits.  An  opening  curly  bracket  that
+     appears  in a position where a quantifier is not allowed, or
+     one that does not match the syntax of a quantifier, is taken
+     as  a literal character. For example, {,6} is not a quantif-
+     ier, but a literal string of four characters.
+
+     The quantifier {0} is permitted, causing the  expression  to
+     behave  as  if the previous item and the quantifier were not
+     present.
+
+     For convenience (and  historical  compatibility)  the  three
+     most common quantifiers have single-character abbreviations:
+
+       *    is equivalent to {0,}
+       +    is equivalent to {1,}
+       ?    is equivalent to {0,1}
+
+     It is possible to construct infinite loops  by  following  a
+     subpattern  that  can  match no characters with a quantifier
+     that has no upper limit, for example:
+
+       (a?)*
+
+     Earlier versions of Perl and PCRE used to give an  error  at
+     compile  time  for such patterns. However, because there are
+     cases where this  can  be  useful,  such  patterns  are  now
+     accepted,  but  if  any repetition of the subpattern does in
+     fact match no characters, the loop is forcibly broken.
+
+     By default, the quantifiers  are  "greedy",  that  is,  they
+     match  as much as possible (up to the maximum number of per-
+     mitted times), without causing the rest of  the  pattern  to
+     fail. The classic example of where this gives problems is in
+     trying to match comments in C programs. These appear between
+     the  sequences /* and */ and within the sequence, individual
+     * and / characters may appear. An attempt to  match  C  com-
+     ments by applying the pattern
+
+       /\*.*\*/
+
+     to the string
+
+       /* first command */  not comment  /* second comment */
+
+     fails, because it matches the entire  string  owing  to  the
+     greediness of the .*  item.
+
+     However, if a quantifier is followed by a question mark,  it
+     ceases  to be greedy, and instead matches the minimum number
+     of times possible, so the pattern
+
+       /\*.*?\*/
+
+     does the right thing with the C comments. The meaning of the
+     various  quantifiers is not otherwise changed, just the pre-
+     ferred number of matches.  Do not confuse this use of  ques-
+     tion  mark  with  its  use as a quantifier in its own right.
+     Because it has two uses, it can sometimes appear doubled, as
+     in
+
+       \d??\d
+
+     which matches one digit by preference, but can match two  if
+     that is the only way the rest of the pattern matches.
+
+     If the PCRE_UNGREEDY option is set (an option which  is  not
+     available  in  Perl),  the  quantifiers  are  not  greedy by
+     default, but individual ones can be made greedy by following
+     them  with  a  question mark. In other words, it inverts the
+     default behaviour.
+
+     When a parenthesized subpattern is quantified with a minimum
+     repeat  count  that is greater than 1 or with a limited max-
+     imum, more store is required for the  compiled  pattern,  in
+     proportion to the size of the minimum or maximum.
+
+     If a pattern starts with .* or  .{0,}  and  the  PCRE_DOTALL
+     option (equivalent to Perl's /s) is set, thus allowing the .
+     to match  newlines,  the  pattern  is  implicitly  anchored,
+     because whatever follows will be tried against every charac-
+     ter position in the subject string, so there is no point  in
+     retrying  the overall match at any position after the first.
+     PCRE treats such a pattern as though it were preceded by \A.
+     In  cases where it is known that the subject string contains
+     no newlines, it is worth setting PCRE_DOTALL when  the  pat-
+     tern begins with .* in order to obtain this optimization, or
+     alternatively using ^ to indicate anchoring explicitly.
+
+     When a capturing subpattern is repeated, the value  captured
+     is the substring that matched the final iteration. For exam-
+     ple, after
+
+       (tweedle[dume]{3}\s*)+
+
+     has matched "tweedledum tweedledee" the value  of  the  cap-
+     tured  substring  is  "tweedledee".  However,  if  there are
+     nested capturing  subpatterns,  the  corresponding  captured
+     values  may  have been set in previous iterations. For exam-
+     ple, after
+
+       /(a|(b))+/
+
+     matches "aba" the value of the second captured substring  is
+     "b".
+
+
+
+BACK REFERENCES
+     Outside a character class, a backslash followed by  a  digit
+     greater  than  0  (and  possibly  further  digits) is a back
+     reference to a capturing subpattern  earlier  (i.e.  to  its
+     left)  in  the  pattern,  provided there have been that many
+     previous capturing left parentheses.
+
+     However, if the decimal number following  the  backslash  is
+     less  than  10,  it is always taken as a back reference, and
+     causes an error only if there are not  that  many  capturing
+     left  parentheses in the entire pattern. In other words, the
+     parentheses that are referenced need not be to the  left  of
+     the  reference  for  numbers  less  than 10. See the section
+     entitled "Backslash" above for further details of  the  han-
+     dling of digits following a backslash.
+
+     A back reference matches whatever actually matched the  cap-
+     turing subpattern in the current subject string, rather than
+     anything matching the subpattern itself. So the pattern
+
+       (sens|respons)e and \1ibility
+
+     matches "sense and sensibility" and "response and  responsi-
+     bility",  but  not  "sense  and  responsibility". If caseful
+     matching is in force at the time of the back reference,  the
+     case of letters is relevant. For example,
+
+       ((?i)rah)\s+\1
+
+     matches "rah rah" and "RAH RAH", but  not  "RAH  rah",  even
+     though  the  original  capturing subpattern is matched case-
+     lessly.
+
+     There may be more than one back reference to the  same  sub-
+     pattern.  If  a  subpattern  has not actually been used in a
+     particular match, any back references to it always fail. For
+     example, the pattern
+
+       (a|(bc))\2
+
+     always fails if it starts to match  "a"  rather  than  "bc".
+     Because  there  may  be up to 99 back references, all digits
+     following the backslash are taken as  part  of  a  potential
+     back reference number. If the pattern continues with a digit
+     character, some delimiter must be used to terminate the back
+     reference.   If the PCRE_EXTENDED option is set, this can be
+     whitespace. Otherwise an empty comment can be used.
+
+     A back reference that occurs inside the parentheses to which
+     it  refers  fails when the subpattern is first used, so, for
+     example, (a\1) never matches.  However, such references  can
+     be useful inside repeated subpatterns. For example, the pat-
+     tern
+
+       (a|b\1)+
+
+     matches any number of "a"s and also "aba", "ababbaa" etc. At
+     each iteration of the subpattern, the back reference matches
+     the  character  string   corresponding   to   the   previous
+     iteration.  In  order  for this to work, the pattern must be
+     such that the first iteration does not  need  to  match  the
+     back  reference.  This  can be done using alternation, as in
+     the example above, or by a  quantifier  with  a  minimum  of
+     zero.
+
+
+
+ASSERTIONS
+     An assertion is  a  test  on  the  characters  following  or
+     preceding  the current matching point that does not actually
+     consume any characters. The simple assertions coded  as  \b,
+     \B,  \A,  \Z,  \z, ^ and $ are described above. More compli-
+     cated assertions are coded as  subpatterns.  There  are  two
+     kinds:  those that look ahead of the current position in the
+     subject string, and those that look behind it.
+
+     An assertion subpattern is matched in the normal way, except
+     that  it  does not cause the current matching position to be
+     changed. Lookahead assertions start with  (?=  for  positive
+     assertions and (?! for negative assertions. For example,
+
+       \w+(?=;)
+
+     matches a word followed by a semicolon, but does not include
+     the semicolon in the match, and
+
+       foo(?!bar)
+
+     matches any occurrence of "foo"  that  is  not  followed  by
+     "bar". Note that the apparently similar pattern
+
+       (?!foo)bar
+
+     does not find an occurrence of "bar"  that  is  preceded  by
+     something other than "foo"; it finds any occurrence of "bar"
+     whatsoever, because the assertion  (?!foo)  is  always  true
+     when  the  next  three  characters  are  "bar". A lookbehind
+     assertion is needed to achieve this effect.
+
+     Lookbehind assertions start with (?<=  for  positive  asser-
+     tions and (?<! for negative assertions. For example,
+
+       (?<!foo)bar
+
+     does find an occurrence of "bar" that  is  not  preceded  by
+     "foo". The contents of a lookbehind assertion are restricted
+     such that all the strings  it  matches  must  have  a  fixed
+     length.  However, if there are several alternatives, they do
+     not all have to have the same fixed length. Thus
+
+       (?<=bullock|donkey)
+
+     is permitted, but
+
+       (?<!dogs?|cats?)
+
+     causes an error at compile time. Branches  that  match  dif-
+     ferent length strings are permitted only at the top level of
+     a lookbehind assertion. This is an extension  compared  with
+     Perl  5.005,  which  requires all branches to match the same
+     length of string. An assertion such as
+
+       (?<=ab(c|de))
+
+     is not permitted, because its single  top-level  branch  can
+     match two different lengths, but it is acceptable if rewrit-
+     ten to use two top-level branches:
+
+       (?<=abc|abde)
+
+     The implementation of lookbehind  assertions  is,  for  each
+     alternative,  to  temporarily move the current position back
+     by the fixed width and then  try  to  match.  If  there  are
+     insufficient  characters  before  the  current position, the
+     match is deemed to fail.  Lookbehinds  in  conjunction  with
+     once-only  subpatterns can be particularly useful for match-
+     ing at the ends of strings; an example is given at  the  end
+     of the section on once-only subpatterns.
+
+     Several assertions (of any sort) may  occur  in  succession.
+     For example,
+
+       (?<=\d{3})(?<!999)foo
+
+     matches "foo" preceded by three digits that are  not  "999".
+     Notice  that each of the assertions is applied independently
+     at the same point in the subject string. First  there  is  a
+     check that the previous three characters are all digits, and
+     then there is a check that the same three characters are not
+     "999".   This  pattern  does not match "foo" preceded by six
+     characters, the first of which are digits and the last three
+     of  which  are  not  "999".  For  example,  it doesn't match
+     "123abcfoo". A pattern to do that is
+
+       (?<=\d{3}...)(?<!999)foo
+
+     This time the first assertion looks  at  the  preceding  six
+     characters,  checking  that  the first three are digits, and
+     then the second assertion checks that  the  preceding  three
+     characters are not "999".
+
+     Assertions can be nested in any combination. For example,
+
+       (?<=(?<!foo)bar)baz
+
+     matches an occurrence of "baz" that  is  preceded  by  "bar"
+     which in turn is not preceded by "foo", while
+
+       (?<=\d{3}(?!999)...)foo
+
+     is another pattern which matches  "foo"  preceded  by  three
+     digits and any three characters that are not "999".
+
+     Assertion subpatterns are not capturing subpatterns, and may
+     not  be  repeated,  because  it makes no sense to assert the
+     same thing several times. If any kind of assertion  contains
+     capturing  subpatterns  within it, these are counted for the
+     purposes of numbering the capturing subpatterns in the whole
+     pattern.   However,  substring capturing is carried out only
+     for positive assertions, because it does not make sense  for
+     negative assertions.
+
+     Assertions count towards the maximum  of  200  parenthesized
+     subpatterns.
+
+
+
+ONCE-ONLY SUBPATTERNS
+     With both maximizing and minimizing repetition,  failure  of
+     what  follows  normally  causes  the repeated item to be re-
+     evaluated to see if a different number of repeats allows the
+     rest  of  the  pattern  to  match. Sometimes it is useful to
+     prevent this, either to change the nature of the  match,  or
+     to  cause  it fail earlier than it otherwise might, when the
+     author of the pattern knows there is no  point  in  carrying
+     on.
+
+     Consider, for example, the pattern \d+foo  when  applied  to
+     the subject line
+
+       123456bar
+
+     After matching all 6 digits and then failing to match "foo",
+     the normal action of the matcher is to try again with only 5
+     digits matching the \d+ item, and then with 4,  and  so  on,
+     before ultimately failing. Once-only subpatterns provide the
+     means for specifying that once a portion of the pattern  has
+     matched,  it  is  not to be re-evaluated in this way, so the
+     matcher would give up immediately on failing to match  "foo"
+     the  first  time.  The  notation  is another kind of special
+     parenthesis, starting with (?> as in this example:
+
+       (?>\d+)bar
+
+     This kind of parenthesis "locks up" the  part of the pattern
+     it  contains once it has matched, and a failure further into
+     the  pattern  is  prevented  from  backtracking   into   it.
+     Backtracking  past  it  to previous items, however, works as
+     normal.
+
+     An alternative description is that a subpattern of this type
+     matches  the  string  of  characters that an identical stan-
+     dalone pattern would match, if anchored at the current point
+     in the subject string.
+
+     Once-only subpatterns are not capturing subpatterns.  Simple
+     cases  such as the above example can be thought of as a max-
+     imizing repeat that must  swallow  everything  it  can.  So,
+     while both \d+ and \d+? are prepared to adjust the number of
+     digits they match in order to make the rest of  the  pattern
+     match, (?>\d+) can only match an entire sequence of digits.
+
+     This construction can of course contain arbitrarily  compli-
+     cated subpatterns, and it can be nested.
+
+     Once-only subpatterns can be used in conjunction with  look-
+     behind  assertions  to specify efficient matching at the end
+     of the subject string. Consider a simple pattern such as
+
+       abcd$
+
+     when applied to a long string which does not match.  Because
+     matching  proceeds  from  left  to right, PCRE will look for
+     each "a" in the subject and then see if what follows matches
+     the rest of the pattern. If the pattern is specified as
+
+       ^.*abcd$
+
+     the initial .* matches the entire string at first, but  when
+     this  fails  (because  there  is no following "a"), it back-
+     tracks to match all but the last character, then all but the
+     last  two  characters,  and so on. Once again the search for
+     "a" covers the entire string, from right to left, so we  are
+     no better off. However, if the pattern is written as
+
+       ^(?>.*)(?<=abcd)
+
+     there can be no backtracking for the .* item; it  can  match
+     only  the entire string. The subsequent lookbehind assertion
+     does a single test on the last four characters. If it fails,
+     the match fails immediately. For long strings, this approach
+     makes a significant difference to the processing time.
+
+     When a pattern contains an unlimited repeat inside a subpat-
+     tern  that  can  itself  be  repeated an unlimited number of
+     times, the use of a once-only subpattern is the only way  to
+     avoid  some  failing matches taking a very long time indeed.
+     The pattern
+
+       (\D+|<\d+>)*[!?]
+
+     matches an unlimited number of substrings that  either  con-
+     sist  of  non-digits,  or digits enclosed in <>, followed by
+     either ! or ?. When it matches, it runs quickly. However, if
+     it is applied to
+
+       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+     it takes a long  time  before  reporting  failure.  This  is
+     because the string can be divided between the two repeats in
+     a large number of ways, and all have to be tried. (The exam-
+     ple  used  [!?]  rather  than a single character at the end,
+     because both PCRE and Perl have an optimization that  allows
+     for  fast  failure  when  a  single  character is used. They
+     remember the last single character that is  required  for  a
+     match,  and  fail early if it is not present in the string.)
+     If the pattern is changed to
+
+       ((?>\D+)|<\d+>)*[!?]
+
+     sequences of non-digits cannot be broken, and  failure  hap-
+     pens quickly.
+
+
+
+CONDITIONAL SUBPATTERNS
+     It is possible to cause the matching process to obey a  sub-
+     pattern  conditionally  or to choose between two alternative
+     subpatterns, depending on the result  of  an  assertion,  or
+     whether  a previous capturing subpattern matched or not. The
+     two possible forms of conditional subpattern are
+
+       (?(condition)yes-pattern)
+       (?(condition)yes-pattern|no-pattern)
+
+     If the condition is satisfied, the yes-pattern is used; oth-
+     erwise  the  no-pattern  (if  present) is used. If there are
+     more than two alternatives in the subpattern, a compile-time
+     error occurs.
+
+     There are two kinds of condition. If the  text  between  the
+     parentheses  consists of a sequence of digits, the condition
+     is satisfied if the capturing subpattern of that number  has
+     previously  matched.  The  number must be greater than zero.
+     Consider  the  following  pattern,   which   contains   non-
+     significant white space to make it more readable (assume the
+     PCRE_EXTENDED option) and to divide it into three parts  for
+     ease of discussion:
+
+       ( \( )?    [^()]+    (?(1) \) )
+
+     The first part matches an optional opening parenthesis,  and
+     if  that character is present, sets it as the first captured
+     substring. The second part matches one  or  more  characters
+     that  are  not  parentheses. The third part is a conditional
+     subpattern that tests whether the first set  of  parentheses
+     matched  or  not.  If  they did, that is, if subject started
+     with an opening parenthesis, the condition is true,  and  so
+     the  yes-pattern  is  executed  and a closing parenthesis is
+     required. Otherwise, since no-pattern is  not  present,  the
+     subpattern  matches  nothing.  In  other words, this pattern
+     matches a sequence of non-parentheses,  optionally  enclosed
+     in parentheses.
+
+     If the condition is not a sequence of digits, it must be  an
+     assertion.  This  may be a positive or negative lookahead or
+     lookbehind assertion. Consider this pattern, again  contain-
+     ing  non-significant  white space, and with the two alterna-
+     tives on the second line:
+
+       (?(?=[^a-z]*[a-z])
+       \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
+
+     The condition is a positive lookahead assertion that matches
+     an optional sequence of non-letters followed by a letter. In
+     other words, it tests for  the  presence  of  at  least  one
+     letter  in the subject. If a letter is found, the subject is
+     matched against  the  first  alternative;  otherwise  it  is
+     matched  against the second. This pattern matches strings in
+     one of the two forms dd-aaa-dd or dd-dd-dd,  where  aaa  are
+     letters and dd are digits.
+
+
+
+COMMENTS
+     The sequence (?# marks the start of a comment which  contin-
+     ues  up  to the next closing parenthesis. Nested parentheses
+     are not permitted. The characters that  make  up  a  comment
+     play no part in the pattern matching at all.
+
+     If the PCRE_EXTENDED option is set, an unescaped # character
+     outside  a character class introduces a comment that contin-
+     ues up to the next newline character in the pattern.
+
+
+
+RECURSIVE PATTERNS
+     Consider the problem of matching a  string  in  parentheses,
+     allowing  for  unlimited nested parentheses. Without the use
+     of recursion, the best that can be done is to use a  pattern
+     that  matches  up  to some fixed depth of nesting. It is not
+     possible to handle an arbitrary nesting depth. Perl 5.6  has
+     provided   an  experimental  facility  that  allows  regular
+     expressions to recurse (amongst other things). It does  this
+     by  interpolating  Perl  code in the expression at run time,
+     and the code can refer to the expression itself. A Perl pat-
+     tern  to  solve  the parentheses problem can be created like
+     this:
+
+       $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;
+
+     The (?p{...}) item interpolates Perl code at run  time,  and
+     in  this  case refers recursively to the pattern in which it
+     appears. Obviously, PCRE cannot support the interpolation of
+     Perl  code.  Instead,  the special item (?R) is provided for
+     the specific case of recursion. This PCRE pattern solves the
+     parentheses  problem (assume the PCRE_EXTENDED option is set
+     so that white space is ignored):
+
+       \( ( (?>[^()]+) | (?R) )* \)
+
+     First it matches an opening parenthesis. Then it matches any
+     number  of substrings which can either be a sequence of non-
+     parentheses, or a recursive  match  of  the  pattern  itself
+     (i.e. a correctly parenthesized substring). Finally there is
+     a closing parenthesis.
+
+     This particular example pattern  contains  nested  unlimited
+     repeats, and so the use of a once-only subpattern for match-
+     ing strings of non-parentheses is  important  when  applying
+     the  pattern to strings that do not match. For example, when
+     it is applied to
+
+       (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+
+     it yields "no match" quickly. However, if a  once-only  sub-
+     pattern  is  not  used,  the match runs for a very long time
+     indeed because there are so many different ways the + and  *
+     repeats  can carve up the subject, and all have to be tested
+     before failure can be reported.
+
+     The values set for any capturing subpatterns are those  from
+     the outermost level of the recursion at which the subpattern
+     value is set. If the pattern above is matched against
+
+       (ab(cd)ef)
+
+     the value for the capturing parentheses is  "ef",  which  is
+     the  last  value  taken  on  at the top level. If additional
+     parentheses are added, giving
+
+       \( ( ( (?>[^()]+) | (?R) )* ) \)
+          ^                        ^
+          ^                        ^ the string they  capture  is
+     "ab(cd)ef",  the  contents  of the top level parentheses. If
+     there are more than 15 capturing parentheses in  a  pattern,
+     PCRE  has  to  obtain  extra  memory  to store data during a
+     recursion, which it does by using  pcre_malloc,  freeing  it
+     via  pcre_free  afterwards. If no memory can be obtained, it
+     saves data for the first 15 capturing parentheses  only,  as
+     there is no way to give an out-of-memory error from within a
+     recursion.
+
+
+
+PERFORMANCE
+     Certain items that may appear in patterns are more efficient
+     than  others.  It is more efficient to use a character class
+     like [aeiou] than a set of alternatives such as (a|e|i|o|u).
+     In  general,  the  simplest  construction  that provides the
+     required behaviour is usually the  most  efficient.  Jeffrey
+     Friedl's  book contains a lot of discussion about optimizing
+     regular expressions for efficient performance.
+
+     When a pattern begins with .* and the PCRE_DOTALL option  is
+     set,  the  pattern  is implicitly anchored by PCRE, since it
+     can match only at the start of a subject string. However, if
+     PCRE_DOTALL  is not set, PCRE cannot make this optimization,
+     because the . metacharacter does not then match  a  newline,
+     and if the subject string contains newlines, the pattern may
+     match from the character immediately following one  of  them
+     instead of from the very start. For example, the pattern
+
+       (.*) second
+
+     matches the subject "first\nand second" (where \n stands for
+     a newline character) with the first captured substring being
+     "and". In order to do this, PCRE  has  to  retry  the  match
+     starting after every newline in the subject.
+
+     If you are using such a pattern with subject strings that do
+     not  contain  newlines,  the best performance is obtained by
+     setting PCRE_DOTALL, or starting the  pattern  with  ^.*  to
+     indicate  explicit anchoring. That saves PCRE from having to
+     scan along the subject looking for a newline to restart at.
+
+     Beware of patterns that contain nested  indefinite  repeats.
+     These  can  take a long time to run when applied to a string
+     that does not match. Consider the pattern fragment
+
+       (a+)*
+
+     This can match "aaaa" in 33 different ways, and this  number
+     increases  very  rapidly  as  the string gets longer. (The *
+     repeat can match 0, 1, 2, 3, or 4 times,  and  for  each  of
+     those  cases other than 0, the + repeats can match different
+     numbers of times.) When the remainder of the pattern is such
+     that  the entire match is going to fail, PCRE has in princi-
+     ple to try every possible variation, and this  can  take  an
+     extremely long time.
+
+     An optimization catches some of the more simple  cases  such
+     as
+
+       (a+)*b
+
+     where a literal character follows. Before embarking  on  the
+     standard matching procedure, PCRE checks that there is a "b"
+     later in the subject string, and if there is not,  it  fails
+     the  match  immediately. However, when there is no following
+     literal this optimization cannot be used. You  can  see  the
+     difference by comparing the behaviour of
+
+       (a+)*\d
+
+     with the pattern above. The former gives  a  failure  almost
+     instantly  when  applied  to a whole line of "a" characters,
+     whereas the latter takes an appreciable  time  with  strings
+     longer than about 20 characters.
+
+
+
+UTF-8 SUPPORT
+     Starting at release 3.3, PCRE has some support for character
+     strings encoded in the UTF-8 format. This is incomplete, and
+     is regarded as experimental. In order to use  it,  you  must
+     configure PCRE to include UTF-8 support in the code, and, in
+     addition, you must call pcre_compile()  with  the  PCRE_UTF8
+     option flag. When you do this, both the pattern and any sub-
+     ject strings that are matched  against  it  are  treated  as
+     UTF-8  strings instead of just strings of bytes, but only in
+     the cases that are mentioned below.
+
+     If you compile PCRE with UTF-8 support, but do not use it at
+     run  time,  the  library will be a bit bigger, but the addi-
+     tional run time overhead is limited to testing the PCRE_UTF8
+     flag in several places, so should not be very large.
+
+     PCRE assumes that the strings  it  is  given  contain  valid
+     UTF-8  codes. It does not diagnose invalid UTF-8 strings. If
+     you pass invalid UTF-8 strings  to  PCRE,  the  results  are
+     undefined.
+
+     Running with PCRE_UTF8 set causes these changes in  the  way
+     PCRE works:
+
+     1. In a pattern, the escape sequence \x{...}, where the con-
+     tents  of  the  braces is a string of hexadecimal digits, is
+     interpreted as a UTF-8 character whose code  number  is  the
+     given   hexadecimal  number,  for  example:  \x{1234}.  This
+     inserts from one to six  literal  bytes  into  the  pattern,
+     using the UTF-8 encoding. If a non-hexadecimal digit appears
+     between the braces, the item is not recognized.
+
+     2. The original hexadecimal escape sequence, \xhh, generates
+     a two-byte UTF-8 character if its value is greater than 127.
+
+     3. Repeat quantifiers are NOT correctly handled if they fol-
+     low  a  multibyte character. For example, \x{100}* and \xc3+
+     do not work. If you want to repeat such characters, you must
+     enclose  them  in  non-capturing  parentheses,  for  example
+     (?:\x{100}), at present.
+
+     4. The dot metacharacter matches one UTF-8 character instead
+     of a single byte.
+
+     5. Unlike literal UTF-8 characters,  the  dot  metacharacter
+     followed  by  a  repeat quantifier does operate correctly on
+     UTF-8 characters instead of single bytes.
+
+     4. Although the \x{...} escape is permitted in  a  character
+     class,  characters  whose values are greater than 255 cannot
+     be included in a class.
+
+     5. A class is matched against a UTF-8 character  instead  of
+     just  a  single byte, but it can match only characters whose
+     values are less than 256.  Characters  with  greater  values
+     always fail to match a class.
+
+     6. Repeated classes work correctly on multiple characters.
+
+     7. Classes containing just a single character whose value is
+     greater than 127 (but less than 256), for example, [\x80] or
+     [^\x{93}], do not work because these are optimized into sin-
+     gle  byte  matches.  In the first case, of course, the class
+     brackets are just redundant.
+
+     8. Lookbehind assertions move backwards in the subject by  a
+     fixed  number  of  characters  instead  of a fixed number of
+     bytes. Simple cases have been tested to work correctly,  but
+     there may be hidden gotchas herein.
+
+     9. The character types  such  as  \d  and  \w  do  not  work
+     correctly  with  UTF-8  characters.  They continue to test a
+     single byte.
+
+     10. Anything not explicitly mentioned here continues to work
+     in bytes rather than in characters.
+
+     The following UTF-8 features of  Perl  5.6  are  not  imple-
+     mented:
+     1. The escape sequence \C to match a single byte.
+
+     2. The use of Unicode tables and properties and escapes  \p,
+     \P, and \X.
+
+
+
+AUTHOR
+     Philip Hazel <ph10@cam.ac.uk>
+     University Computing Service,
+     New Museums Site,
+     Cambridge CB2 3QG, England.
+     Phone: +44 1223 334714
+
+     Last updated: 28 August 2000,
+       the 250th anniversary of the death of J.S. Bach.
+     Copyright (c) 1997-2000 University of Cambridge.
diff --git a/pcre/doc/pcregrep.1 b/pcre/doc/pcregrep.1
new file mode 100644 (file)
index 0000000..ec733fa
--- /dev/null
@@ -0,0 +1,76 @@
+.TH PCREGREP 1\r
+.SH NAME\r
+pcregrep - a grep with Perl-compatible regular expressions.\r
+.SH SYNOPSIS\r
+.B pcregrep [-Vchilnsvx] pattern [file] ...\r
+\r
+\r
+.SH DESCRIPTION\r
+\fBpcregrep\fR searches files for character patterns, in the same way as other\r
+grep commands do, but it uses the PCRE regular expression library to support\r
+patterns that are compatible with the regular expressions of Perl 5. See\r
+\fBpcre(3)\fR for a full description of syntax and semantics.\r
+\r
+If no files are specified, \fBpcregrep\fR reads the standard input. By default,\r
+each line that matches the pattern is copied to the standard output, and if\r
+there is more than one file, the file name is printed before each line of\r
+output. However, there are options that can change how \fBpcregrep\fR behaves.\r
+\r
+Lines are limited to BUFSIZ characters. BUFSIZ is defined in \fB<stdio.h>\fR.\r
+The newline character is removed from the end of each line before it is matched\r
+against the pattern.\r
+\r
+\r
+.SH OPTIONS\r
+.TP 10\r
+\fB-V\fR\r
+Write the version number of the PCRE library being used to the standard error\r
+stream.\r
+.TP\r
+\fB-c\fR\r
+Do not print individual lines; instead just print a count of the number of\r
+lines that would otherwise have been printed. If several files are given, a\r
+count is printed for each of them.\r
+.TP\r
+\fB-h\fR\r
+Suppress printing of filenames when searching multiple files.\r
+.TP\r
+\fB-i\fR\r
+Ignore upper/lower case distinctions during comparisons.\r
+.TP\r
+\fB-l\fR\r
+Instead of printing lines from the files, just print the names of the files\r
+containing lines that would have been printed. Each file name is printed\r
+once, on a separate line.\r
+.TP\r
+\fB-n\fR\r
+Precede each line by its line number in the file.\r
+.TP\r
+\fB-s\fR\r
+Work silently, that is, display nothing except error messages.\r
+The exit status indicates whether any matches were found.\r
+.TP\r
+\fB-v\fR\r
+Invert the sense of the match, so that lines which do \fInot\fR match the\r
+pattern are now the ones that are found.\r
+.TP\r
+\fB-x\fR\r
+Force the pattern to be anchored (it must start matching at the beginning of\r
+the line) and in addition, require it to match the entire line. This is\r
+equivalent to having ^ and $ characters at the start and end of each\r
+alternative branch in the regular expression.\r
+\r
+\r
+.SH SEE ALSO\r
+\fBpcre(3)\fR, Perl 5 documentation\r
+\r
+\r
+.SH DIAGNOSTICS\r
+Exit status is 0 if any matches were found, 1 if no matches were found, and 2\r
+for syntax errors or inacessible files (even if matches were found).\r
+\r
+\r
+.SH AUTHOR\r
+Philip Hazel <ph10@cam.ac.uk>\r
+.br\r
+Copyright (c) 1997-2000 University of Cambridge.\r
diff --git a/pcre/doc/pcregrep.html b/pcre/doc/pcregrep.html
new file mode 100644 (file)
index 0000000..19f733c
--- /dev/null
@@ -0,0 +1,105 @@
+<HTML>\r
+<HEAD>\r
+<TITLE>pcregrep specification</TITLE>\r
+</HEAD>\r
+<body bgcolor="#FFFFFF" text="#00005A">\r
+<H1>pcregrep specification</H1>\r
+This HTML document has been generated automatically from the original man page.\r
+If there is any nonsense in it, please consult the man page in case the\r
+conversion went wrong.\r
+<UL>\r
+<LI><A NAME="TOC1" HREF="#SEC1">NAME</A>\r
+<LI><A NAME="TOC2" HREF="#SEC2">SYNOPSIS</A>\r
+<LI><A NAME="TOC3" HREF="#SEC3">DESCRIPTION</A>\r
+<LI><A NAME="TOC4" HREF="#SEC4">OPTIONS</A>\r
+<LI><A NAME="TOC5" HREF="#SEC5">SEE ALSO</A>\r
+<LI><A NAME="TOC6" HREF="#SEC6">DIAGNOSTICS</A>\r
+<LI><A NAME="TOC7" HREF="#SEC7">AUTHOR</A>\r
+</UL>\r
+<LI><A NAME="SEC1" HREF="#TOC1">NAME</A>\r
+<P>\r
+pcregrep - a grep with Perl-compatible regular expressions.\r
+</P>\r
+<LI><A NAME="SEC2" HREF="#TOC1">SYNOPSIS</A>\r
+<P>\r
+<B>pcregrep [-Vchilnsvx] pattern [file] ...</B>\r
+</P>\r
+<LI><A NAME="SEC3" HREF="#TOC1">DESCRIPTION</A>\r
+<P>\r
+<B>pcregrep</B> searches files for character patterns, in the same way as other\r
+grep commands do, but it uses the PCRE regular expression library to support\r
+patterns that are compatible with the regular expressions of Perl 5. See\r
+<B>pcre(3)</B> for a full description of syntax and semantics.\r
+</P>\r
+<P>\r
+If no files are specified, <B>pcregrep</B> reads the standard input. By default,\r
+each line that matches the pattern is copied to the standard output, and if\r
+there is more than one file, the file name is printed before each line of\r
+output. However, there are options that can change how <B>pcregrep</B> behaves.\r
+</P>\r
+<P>\r
+Lines are limited to BUFSIZ characters. BUFSIZ is defined in <B>&#60;stdio.h&#62;</B>.\r
+The newline character is removed from the end of each line before it is matched\r
+against the pattern.\r
+</P>\r
+<LI><A NAME="SEC4" HREF="#TOC1">OPTIONS</A>\r
+<P>\r
+<B>-V</B>\r
+Write the version number of the PCRE library being used to the standard error\r
+stream.\r
+</P>\r
+<P>\r
+<B>-c</B>\r
+Do not print individual lines; instead just print a count of the number of\r
+lines that would otherwise have been printed. If several files are given, a\r
+count is printed for each of them.\r
+</P>\r
+<P>\r
+<B>-h</B>\r
+Suppress printing of filenames when searching multiple files.\r
+</P>\r
+<P>\r
+<B>-i</B>\r
+Ignore upper/lower case distinctions during comparisons.\r
+</P>\r
+<P>\r
+<B>-l</B>\r
+Instead of printing lines from the files, just print the names of the files\r
+containing lines that would have been printed. Each file name is printed\r
+once, on a separate line.\r
+</P>\r
+<P>\r
+<B>-n</B>\r
+Precede each line by its line number in the file.\r
+</P>\r
+<P>\r
+<B>-s</B>\r
+Work silently, that is, display nothing except error messages.\r
+The exit status indicates whether any matches were found.\r
+</P>\r
+<P>\r
+<B>-v</B>\r
+Invert the sense of the match, so that lines which do <I>not</I> match the\r
+pattern are now the ones that are found.\r
+</P>\r
+<P>\r
+<B>-x</B>\r
+Force the pattern to be anchored (it must start matching at the beginning of\r
+the line) and in addition, require it to match the entire line. This is\r
+equivalent to having ^ and $ characters at the start and end of each\r
+alternative branch in the regular expression.\r
+</P>\r
+<LI><A NAME="SEC5" HREF="#TOC1">SEE ALSO</A>\r
+<P>\r
+<B>pcre(3)</B>, Perl 5 documentation\r
+</P>\r
+<LI><A NAME="SEC6" HREF="#TOC1">DIAGNOSTICS</A>\r
+<P>\r
+Exit status is 0 if any matches were found, 1 if no matches were found, and 2\r
+for syntax errors or inacessible files (even if matches were found).\r
+</P>\r
+<LI><A NAME="SEC7" HREF="#TOC1">AUTHOR</A>\r
+<P>\r
+Philip Hazel &#60;ph10@cam.ac.uk&#62;\r
+<BR>\r
+Copyright (c) 1997-2000 University of Cambridge.\r
diff --git a/pcre/doc/pcregrep.txt b/pcre/doc/pcregrep.txt
new file mode 100644 (file)
index 0000000..871350c
--- /dev/null
@@ -0,0 +1,87 @@
+NAME\r
+     pcregrep - a grep with Perl-compatible regular expressions.\r
+\r
+\r
+\r
+SYNOPSIS\r
+     pcregrep [-Vchilnsvx] pattern [file] ...\r
+\r
+\r
+\r
+DESCRIPTION\r
+     pcregrep searches files for character patterns, in the  same\r
+     way  as other grep commands do, but it uses the PCRE regular\r
+     expression library to support patterns that  are  compatible\r
+     with  the  regular  expressions of Perl 5. See pcre(3) for a\r
+     full description of syntax and semantics.\r
+\r
+     If no files  are  specified,  pcregrep  reads  the  standard\r
+     input.  By  default,  each  line that matches the pattern is\r
+     copied to the standard output, and if there is more than one\r
+     file,  the  file name is printed before each line of output.\r
+     However, there are options  that  can  change  how  pcregrep\r
+     behaves.\r
+\r
+     Lines are limited to BUFSIZ characters. BUFSIZ is defined in\r
+     <stdio.h>.  The newline character is removed from the end of\r
+     each line before it is matched against the pattern.\r
+\r
+\r
+\r
+OPTIONS\r
+     -V        Write the version number of the PCRE library being\r
+               used to the standard error stream.\r
+\r
+     -c        Do not print individual lines; instead just  print\r
+               a  count  of the number of lines that would other-\r
+               wise have  been  printed.  If  several  files  are\r
+               given, a count is printed for each of them.\r
+\r
+     -h        Suppress printing of filenames when searching mul-\r
+               tiple files.\r
+\r
+     -i        Ignore upper/lower case distinctions  during  com-\r
+               parisons.\r
+\r
+     -l        Instead of printing lines  from  the  files,  just\r
+               print the names of the files containing lines that\r
+               would have been printed. Each file name is printed\r
+               once, on a separate line.\r
+\r
+     -n        Precede each line by its line number in the file.\r
+\r
+     -s        Work silently, that  is,  display  nothing  except\r
+               error messages.  The exit status indicates whether\r
+               any matches were found.\r
+\r
+     -v        Invert the sense of the match, so that lines which\r
+               do not match the pattern are now the ones that are\r
+               found.\r
+\r
+     -x        Force the pattern to be anchored  (it  must  start\r
+               matching  at  the  beginning  of  the line) and in\r
+               addition, require it to  match  the  entire  line.\r
+               This is equivalent to having ^ and $ characters at\r
+               the start and end of each  alternative  branch  in\r
+               the regular expression.\r
+\r
+\r
+\r
+SEE ALSO\r
+     pcre(3), Perl 5 documentation\r
+\r
+\r
+\r
+\r
+\r
+DIAGNOSTICS\r
+     Exit status is 0 if any matches were found, 1 if no  matches\r
+     were  found,  and  2  for syntax errors or inacessible files\r
+     (even if matches were found).\r
+\r
+\r
+\r
+AUTHOR\r
+     Philip Hazel <ph10@cam.ac.uk>\r
+     Copyright (c) 1997-2000 University of Cambridge.\r
+\r
diff --git a/pcre/doc/pcreposix.3 b/pcre/doc/pcreposix.3
new file mode 100644 (file)
index 0000000..4853a97
--- /dev/null
@@ -0,0 +1,149 @@
+.TH PCRE 3\r
+.SH NAME\r
+pcreposix - POSIX API for Perl-compatible regular expressions.\r
+.SH SYNOPSIS\r
+.B #include <pcreposix.h>\r
+.PP\r
+.SM\r
+.br\r
+.B int regcomp(regex_t *\fIpreg\fR, const char *\fIpattern\fR,\r
+.ti +5n\r
+.B int \fIcflags\fR);\r
+.PP\r
+.br\r
+.B int regexec(regex_t *\fIpreg\fR, const char *\fIstring\fR,\r
+.ti +5n\r
+.B size_t \fInmatch\fR, regmatch_t \fIpmatch\fR[], int \fIeflags\fR);\r
+.PP\r
+.br\r
+.B size_t regerror(int \fIerrcode\fR, const regex_t *\fIpreg\fR,\r
+.ti +5n\r
+.B char *\fIerrbuf\fR, size_t \fIerrbuf_size\fR);\r
+.PP\r
+.br\r
+.B void regfree(regex_t *\fIpreg\fR);\r
+\r
+\r
+.SH DESCRIPTION\r
+This set of functions provides a POSIX-style API to the PCRE regular expression\r
+package. See the \fBpcre\fR documentation for a description of the native API,\r
+which contains additional functionality.\r
+\r
+The functions described here are just wrapper functions that ultimately call\r
+the native API. Their prototypes are defined in the \fBpcreposix.h\fR header\r
+file, and on Unix systems the library itself is called \fBpcreposix.a\fR, so\r
+can be accessed by adding \fB-lpcreposix\fR to the command for linking an\r
+application which uses them. Because the POSIX functions call the native ones,\r
+it is also necessary to add \fR-lpcre\fR.\r
+\r
+I have implemented only those option bits that can be reasonably mapped to PCRE\r
+native options. In addition, the options REG_EXTENDED and REG_NOSUB are defined\r
+with the value zero. They have no effect, but since programs that are written\r
+to the POSIX interface often use them, this makes it easier to slot in PCRE as\r
+a replacement library. Other POSIX options are not even defined.\r
+\r
+When PCRE is called via these functions, it is only the API that is POSIX-like\r
+in style. The syntax and semantics of the regular expressions themselves are\r
+still those of Perl, subject to the setting of various PCRE options, as\r
+described below.\r
+\r
+The header for these functions is supplied as \fBpcreposix.h\fR to avoid any\r
+potential clash with other POSIX libraries. It can, of course, be renamed or\r
+aliased as \fBregex.h\fR, which is the "correct" name. It provides two\r
+structure types, \fIregex_t\fR for compiled internal forms, and\r
+\fIregmatch_t\fR for returning captured substrings. It also defines some\r
+constants whose names start with "REG_"; these are used for setting options and\r
+identifying error codes.\r
+\r
+\r
+.SH COMPILING A PATTERN\r
+\r
+The function \fBregcomp()\fR is called to compile a pattern into an\r
+internal form. The pattern is a C string terminated by a binary zero, and\r
+is passed in the argument \fIpattern\fR. The \fIpreg\fR argument is a pointer\r
+to a regex_t structure which is used as a base for storing information about\r
+the compiled expression.\r
+\r
+The argument \fIcflags\fR is either zero, or contains one or more of the bits\r
+defined by the following macros:\r
+\r
+  REG_ICASE\r
+\r
+The PCRE_CASELESS option is set when the expression is passed for compilation\r
+to the native function.\r
+\r
+  REG_NEWLINE\r
+\r
+The PCRE_MULTILINE option is set when the expression is passed for compilation\r
+to the native function.\r
+\r
+In the absence of these flags, no options are passed to the native function.\r
+This means the the regex is compiled with PCRE default semantics. In\r
+particular, the way it handles newline characters in the subject string is the\r
+Perl way, not the POSIX way. Note that setting PCRE_MULTILINE has only\r
+\fIsome\fR of the effects specified for REG_NEWLINE. It does not affect the way\r
+newlines are matched by . (they aren't) or a negative class such as [^a] (they\r
+are).\r
+\r
+The yield of \fBregcomp()\fR is zero on success, and non-zero otherwise. The\r
+\fIpreg\fR structure is filled in on success, and one member of the structure\r
+is publicized: \fIre_nsub\fR contains the number of capturing subpatterns in\r
+the regular expression. Various error codes are defined in the header file.\r
+\r
+\r
+.SH MATCHING A PATTERN\r
+The function \fBregexec()\fR is called to match a pre-compiled pattern\r
+\fIpreg\fR against a given \fIstring\fR, which is terminated by a zero byte,\r
+subject to the options in \fIeflags\fR. These can be:\r
+\r
+  REG_NOTBOL\r
+\r
+The PCRE_NOTBOL option is set when calling the underlying PCRE matching\r
+function.\r
+\r
+  REG_NOTEOL\r
+\r
+The PCRE_NOTEOL option is set when calling the underlying PCRE matching\r
+function.\r
+\r
+The portion of the string that was matched, and also any captured substrings,\r
+are returned via the \fIpmatch\fR argument, which points to an array of\r
+\fInmatch\fR structures of type \fIregmatch_t\fR, containing the members\r
+\fIrm_so\fR and \fIrm_eo\fR. These contain the offset to the first character of\r
+each substring and the offset to the first character after the end of each\r
+substring, respectively. The 0th element of the vector relates to the entire\r
+portion of \fIstring\fR that was matched; subsequent elements relate to the\r
+capturing subpatterns of the regular expression. Unused entries in the array\r
+have both structure members set to -1.\r
+\r
+A successful match yields a zero return; various error codes are defined in the\r
+header file, of which REG_NOMATCH is the "expected" failure code.\r
+\r
+\r
+.SH ERROR MESSAGES\r
+The \fBregerror()\fR function maps a non-zero errorcode from either\r
+\fBregcomp\fR or \fBregexec\fR to a printable message. If \fIpreg\fR is not\r
+NULL, the error should have arisen from the use of that structure. A message\r
+terminated by a binary zero is placed in \fIerrbuf\fR. The length of the\r
+message, including the zero, is limited to \fIerrbuf_size\fR. The yield of the\r
+function is the size of buffer needed to hold the whole message.\r
+\r
+\r
+.SH STORAGE\r
+Compiling a regular expression causes memory to be allocated and associated\r
+with the \fIpreg\fR structure. The function \fBregfree()\fR frees all such\r
+memory, after which \fIpreg\fR may no longer be used as a compiled expression.\r
+\r
+\r
+.SH AUTHOR\r
+Philip Hazel <ph10@cam.ac.uk>\r
+.br\r
+University Computing Service,\r
+.br\r
+New Museums Site,\r
+.br\r
+Cambridge CB2 3QG, England.\r
+.br\r
+Phone: +44 1223 334714\r
+\r
+Copyright (c) 1997-2000 University of Cambridge.\r
diff --git a/pcre/doc/pcreposix.html b/pcre/doc/pcreposix.html
new file mode 100644 (file)
index 0000000..79ff544
--- /dev/null
@@ -0,0 +1,191 @@
+<HTML>\r
+<HEAD>\r
+<TITLE>pcreposix specification</TITLE>\r
+</HEAD>\r
+<body bgcolor="#FFFFFF" text="#00005A">\r
+<H1>pcreposix specification</H1>\r
+This HTML document has been generated automatically from the original man page.\r
+If there is any nonsense in it, please consult the man page in case the\r
+conversion went wrong.\r
+<UL>\r
+<LI><A NAME="TOC1" HREF="#SEC1">NAME</A>\r
+<LI><A NAME="TOC2" HREF="#SEC2">SYNOPSIS</A>\r
+<LI><A NAME="TOC3" HREF="#SEC3">DESCRIPTION</A>\r
+<LI><A NAME="TOC4" HREF="#SEC4">COMPILING A PATTERN</A>\r
+<LI><A NAME="TOC5" HREF="#SEC5">MATCHING A PATTERN</A>\r
+<LI><A NAME="TOC6" HREF="#SEC6">ERROR MESSAGES</A>\r
+<LI><A NAME="TOC7" HREF="#SEC7">STORAGE</A>\r
+<LI><A NAME="TOC8" HREF="#SEC8">AUTHOR</A>\r
+</UL>\r
+<LI><A NAME="SEC1" HREF="#TOC1">NAME</A>\r
+<P>\r
+pcreposix - POSIX API for Perl-compatible regular expressions.\r
+</P>\r
+<LI><A NAME="SEC2" HREF="#TOC1">SYNOPSIS</A>\r
+<P>\r
+<B>#include &#60;pcreposix.h&#62;</B>\r
+</P>\r
+<P>\r
+<B>int regcomp(regex_t *<I>preg</I>, const char *<I>pattern</I>,</B>\r
+<B>int <I>cflags</I>);</B>\r
+</P>\r
+<P>\r
+<B>int regexec(regex_t *<I>preg</I>, const char *<I>string</I>,</B>\r
+<B>size_t <I>nmatch</I>, regmatch_t <I>pmatch</I>[], int <I>eflags</I>);</B>\r
+</P>\r
+<P>\r
+<B>size_t regerror(int <I>errcode</I>, const regex_t *<I>preg</I>,</B>\r
+<B>char *<I>errbuf</I>, size_t <I>errbuf_size</I>);</B>\r
+</P>\r
+<P>\r
+<B>void regfree(regex_t *<I>preg</I>);</B>\r
+</P>\r
+<LI><A NAME="SEC3" HREF="#TOC1">DESCRIPTION</A>\r
+<P>\r
+This set of functions provides a POSIX-style API to the PCRE regular expression\r
+package. See the <B>pcre</B> documentation for a description of the native API,\r
+which contains additional functionality.\r
+</P>\r
+<P>\r
+The functions described here are just wrapper functions that ultimately call\r
+the native API. Their prototypes are defined in the <B>pcreposix.h</B> header\r
+file, and on Unix systems the library itself is called <B>pcreposix.a</B>, so\r
+can be accessed by adding <B>-lpcreposix</B> to the command for linking an\r
+application which uses them. Because the POSIX functions call the native ones,\r
+it is also necessary to add \fR-lpcre\fR.\r
+</P>\r
+<P>\r
+I have implemented only those option bits that can be reasonably mapped to PCRE\r
+native options. In addition, the options REG_EXTENDED and REG_NOSUB are defined\r
+with the value zero. They have no effect, but since programs that are written\r
+to the POSIX interface often use them, this makes it easier to slot in PCRE as\r
+a replacement library. Other POSIX options are not even defined.\r
+</P>\r
+<P>\r
+When PCRE is called via these functions, it is only the API that is POSIX-like\r
+in style. The syntax and semantics of the regular expressions themselves are\r
+still those of Perl, subject to the setting of various PCRE options, as\r
+described below.\r
+</P>\r
+<P>\r
+The header for these functions is supplied as <B>pcreposix.h</B> to avoid any\r
+potential clash with other POSIX libraries. It can, of course, be renamed or\r
+aliased as <B>regex.h</B>, which is the "correct" name. It provides two\r
+structure types, <I>regex_t</I> for compiled internal forms, and\r
+<I>regmatch_t</I> for returning captured substrings. It also defines some\r
+constants whose names start with "REG_"; these are used for setting options and\r
+identifying error codes.\r
+</P>\r
+<LI><A NAME="SEC4" HREF="#TOC1">COMPILING A PATTERN</A>\r
+<P>\r
+The function <B>regcomp()</B> is called to compile a pattern into an\r
+internal form. The pattern is a C string terminated by a binary zero, and\r
+is passed in the argument <I>pattern</I>. The <I>preg</I> argument is a pointer\r
+to a regex_t structure which is used as a base for storing information about\r
+the compiled expression.\r
+</P>\r
+<P>\r
+The argument <I>cflags</I> is either zero, or contains one or more of the bits\r
+defined by the following macros:\r
+</P>\r
+<P>\r
+<PRE>\r
+  REG_ICASE\r
+</PRE>\r
+</P>\r
+<P>\r
+The PCRE_CASELESS option is set when the expression is passed for compilation\r
+to the native function.\r
+</P>\r
+<P>\r
+<PRE>\r
+  REG_NEWLINE\r
+</PRE>\r
+</P>\r
+<P>\r
+The PCRE_MULTILINE option is set when the expression is passed for compilation\r
+to the native function.\r
+</P>\r
+<P>\r
+In the absence of these flags, no options are passed to the native function.\r
+This means the the regex is compiled with PCRE default semantics. In\r
+particular, the way it handles newline characters in the subject string is the\r
+Perl way, not the POSIX way. Note that setting PCRE_MULTILINE has only\r
+<I>some</I> of the effects specified for REG_NEWLINE. It does not affect the way\r
+newlines are matched by . (they aren't) or a negative class such as [^a] (they\r
+are).\r
+</P>\r
+<P>\r
+The yield of <B>regcomp()</B> is zero on success, and non-zero otherwise. The\r
+<I>preg</I> structure is filled in on success, and one member of the structure\r
+is publicized: <I>re_nsub</I> contains the number of capturing subpatterns in\r
+the regular expression. Various error codes are defined in the header file.\r
+</P>\r
+<LI><A NAME="SEC5" HREF="#TOC1">MATCHING A PATTERN</A>\r
+<P>\r
+The function <B>regexec()</B> is called to match a pre-compiled pattern\r
+<I>preg</I> against a given <I>string</I>, which is terminated by a zero byte,\r
+subject to the options in <I>eflags</I>. These can be:\r
+</P>\r
+<P>\r
+<PRE>\r
+  REG_NOTBOL\r
+</PRE>\r
+</P>\r
+<P>\r
+The PCRE_NOTBOL option is set when calling the underlying PCRE matching\r
+function.\r
+</P>\r
+<P>\r
+<PRE>\r
+  REG_NOTEOL\r
+</PRE>\r
+</P>\r
+<P>\r
+The PCRE_NOTEOL option is set when calling the underlying PCRE matching\r
+function.\r
+</P>\r
+<P>\r
+The portion of the string that was matched, and also any captured substrings,\r
+are returned via the <I>pmatch</I> argument, which points to an array of\r
+<I>nmatch</I> structures of type <I>regmatch_t</I>, containing the members\r
+<I>rm_so</I> and <I>rm_eo</I>. These contain the offset to the first character of\r
+each substring and the offset to the first character after the end of each\r
+substring, respectively. The 0th element of the vector relates to the entire\r
+portion of <I>string</I> that was matched; subsequent elements relate to the\r
+capturing subpatterns of the regular expression. Unused entries in the array\r
+have both structure members set to -1.\r
+</P>\r
+<P>\r
+A successful match yields a zero return; various error codes are defined in the\r
+header file, of which REG_NOMATCH is the "expected" failure code.\r
+</P>\r
+<LI><A NAME="SEC6" HREF="#TOC1">ERROR MESSAGES</A>\r
+<P>\r
+The <B>regerror()</B> function maps a non-zero errorcode from either\r
+<B>regcomp</B> or <B>regexec</B> to a printable message. If <I>preg</I> is not\r
+NULL, the error should have arisen from the use of that structure. A message\r
+terminated by a binary zero is placed in <I>errbuf</I>. The length of the\r
+message, including the zero, is limited to <I>errbuf_size</I>. The yield of the\r
+function is the size of buffer needed to hold the whole message.\r
+</P>\r
+<LI><A NAME="SEC7" HREF="#TOC1">STORAGE</A>\r
+<P>\r
+Compiling a regular expression causes memory to be allocated and associated\r
+with the <I>preg</I> structure. The function <B>regfree()</B> frees all such\r
+memory, after which <I>preg</I> may no longer be used as a compiled expression.\r
+</P>\r
+<LI><A NAME="SEC8" HREF="#TOC1">AUTHOR</A>\r
+<P>\r
+Philip Hazel &#60;ph10@cam.ac.uk&#62;\r
+<BR>\r
+University Computing Service,\r
+<BR>\r
+New Museums Site,\r
+<BR>\r
+Cambridge CB2 3QG, England.\r
+<BR>\r
+Phone: +44 1223 334714\r
+</P>\r
+<P>\r
+Copyright (c) 1997-2000 University of Cambridge.\r
diff --git a/pcre/doc/pcreposix.txt b/pcre/doc/pcreposix.txt
new file mode 100644 (file)
index 0000000..2d76f7c
--- /dev/null
@@ -0,0 +1,159 @@
+NAME
+     pcreposix - POSIX API for  Perl-compatible  regular  expres-
+     sions.
+
+
+
+SYNOPSIS
+     #include <pcreposix.h>
+
+     int regcomp(regex_t *preg, const char *pattern,
+          int cflags);
+
+     int regexec(regex_t *preg, const char *string,
+          size_t nmatch, regmatch_t pmatch[], int eflags);
+
+     size_t regerror(int errcode, const regex_t *preg,
+          char *errbuf, size_t errbuf_size);
+
+     void regfree(regex_t *preg);
+
+
+
+DESCRIPTION
+     This set of functions provides a POSIX-style API to the PCRE
+     regular expression package. See the pcre documentation for a
+     description of the native  API,  which  contains  additional
+     functionality.
+
+     The functions described here are just wrapper functions that
+     ultimately call the native API. Their prototypes are defined
+     in the pcreposix.h header file,  and  on  Unix  systems  the
+     library  itself is called pcreposix.a, so can be accessed by
+     adding -lpcreposix to the command for linking an application
+     which uses them. Because the POSIX functions call the native
+     ones, it is also necessary to add -lpcre.
+
+     I have implemented only those option bits that can  be  rea-
+     sonably  mapped  to  PCRE  native  options. In addition, the
+     options REG_EXTENDED and  REG_NOSUB  are  defined  with  the
+     value zero. They have no effect, but since programs that are
+     written to the POSIX interface often use them, this makes it
+     easier to slot in PCRE as a replacement library. Other POSIX
+     options are not even defined.
+
+     When PCRE is called via these functions, it is only the  API
+     that is POSIX-like in style. The syntax and semantics of the
+     regular expressions themselves are still those of Perl, sub-
+     ject  to  the  setting of various PCRE options, as described
+     below.
+
+     The header for these functions is supplied as pcreposix.h to
+     avoid  any  potential  clash  with other POSIX libraries. It
+     can, of course, be renamed or aliased as regex.h,  which  is
+     the "correct" name. It provides two structure types, regex_t
+     for compiled internal forms, and  regmatch_t  for  returning
+     captured  substrings.  It  also defines some constants whose
+     names start with "REG_"; these are used for setting  options
+     and identifying error codes.
+
+
+
+COMPILING A PATTERN
+     The function regcomp() is called to compile a  pattern  into
+     an  internal form. The pattern is a C string terminated by a
+     binary zero, and is passed in the argument pattern. The preg
+     argument  is  a pointer to a regex_t structure which is used
+     as a base for storing information about the compiled expres-
+     sion.
+
+     The argument cflags is either zero, or contains one or  more
+     of the bits defined by the following macros:
+
+       REG_ICASE
+
+     The PCRE_CASELESS option  is  set  when  the  expression  is
+     passed for compilation to the native function.
+
+       REG_NEWLINE
+
+     The PCRE_MULTILINE option is  set  when  the  expression  is
+     passed for compilation to the native function.
+
+     In the absence of these flags, no options are passed to  the
+     native  function.  This means the the regex is compiled with
+     PCRE default semantics. In particular, the  way  it  handles
+     newline  characters  in  the subject string is the Perl way,
+     not the POSIX way. Note that setting PCRE_MULTILINE has only
+     some  of  the effects specified for REG_NEWLINE. It does not
+     affect the way newlines are matched by . (they aren't) or  a
+     negative class such as [^a] (they are).
+
+     The yield of regcomp() is zero on success, and non-zero oth-
+     erwise.  The preg structure is filled in on success, and one
+     member of the structure is publicized: re_nsub contains  the
+     number  of  capturing subpatterns in the regular expression.
+     Various error codes are defined in the header file.
+
+
+
+MATCHING A PATTERN
+     The function regexec() is called  to  match  a  pre-compiled
+     pattern  preg against a given string, which is terminated by
+     a zero byte, subject to the options in eflags. These can be:
+
+       REG_NOTBOL
+
+     The PCRE_NOTBOL option is set when  calling  the  underlying
+     PCRE matching function.
+
+       REG_NOTEOL
+
+     The PCRE_NOTEOL option is set when  calling  the  underlying
+     PCRE matching function.
+
+     The portion of the string that was  matched,  and  also  any
+     captured  substrings,  are returned via the pmatch argument,
+     which points to  an  array  of  nmatch  structures  of  type
+     regmatch_t,  containing  the  members rm_so and rm_eo. These
+     contain the offset to the first character of each  substring
+     and  the offset to the first character after the end of each
+     substring, respectively.  The  0th  element  of  the  vector
+     relates  to  the  entire portion of string that was matched;
+     subsequent elements relate to the capturing  subpatterns  of
+     the  regular  expression.  Unused  entries in the array have
+     both structure members set to -1.
+
+     A successful match yields a zero return; various error codes
+     are  defined in the header file, of which REG_NOMATCH is the
+     "expected" failure code.
+
+
+
+ERROR MESSAGES
+     The regerror()  function  maps  a  non-zero  errorcode  from
+     either regcomp or regexec to a printable message. If preg is
+     not NULL, the error should have arisen from the use of  that
+     structure.  A  message terminated by a binary zero is placed
+     in errbuf. The length of the message, including the zero, is
+     limited  to  errbuf_size.  The  yield of the function is the
+     size of buffer needed to hold the whole message.
+
+
+
+STORAGE
+     Compiling a regular expression causes memory to be allocated
+     and  associated  with  the preg structure. The function reg-
+     free() frees all such memory, after which preg may no longer
+     be used as a compiled expression.
+
+
+
+AUTHOR
+     Philip Hazel <ph10@cam.ac.uk>
+     University Computing Service,
+     New Museums Site,
+     Cambridge CB2 3QG, England.
+     Phone: +44 1223 334714
+
+     Copyright (c) 1997-2000 University of Cambridge.
diff --git a/pcre/doc/pcretest.txt b/pcre/doc/pcretest.txt
new file mode 100644 (file)
index 0000000..722e6b8
--- /dev/null
@@ -0,0 +1,246 @@
+The pcretest program\r
+--------------------\r
+\r
+This program is intended for testing PCRE, but it can also be used for\r
+experimenting with regular expressions.\r
+\r
+If it is given two filename arguments, it reads from the first and writes to\r
+the second. If it is given only one filename argument, it reads from that file\r
+and writes to stdout. Otherwise, it reads from stdin and writes to stdout, and\r
+prompts for each line of input, using "re>" to prompt for regular expressions,\r
+and "data>" to prompt for data lines.\r
+\r
+The program handles any number of sets of input on a single input file. Each\r
+set starts with a regular expression, and continues with any number of data\r
+lines to be matched against the pattern. An empty line signals the end of the\r
+data lines, at which point a new regular expression is read. The regular\r
+expressions are given enclosed in any non-alphameric delimiters other than\r
+backslash, for example\r
+\r
+  /(a|bc)x+yz/\r
+\r
+White space before the initial delimiter is ignored. A regular expression may\r
+be continued over several input lines, in which case the newline characters are\r
+included within it. See the test input files in the testdata directory for many\r
+examples. It is possible to include the delimiter within the pattern by\r
+escaping it, for example\r
+\r
+  /abc\/def/\r
+\r
+If you do so, the escape and the delimiter form part of the pattern, but since\r
+delimiters are always non-alphameric, this does not affect its interpretation.\r
+If the terminating delimiter is immediately followed by a backslash, for\r
+example,\r
+\r
+  /abc/\\r
+\r
+then a backslash is added to the end of the pattern. This is done to provide a\r
+way of testing the error condition that arises if a pattern finishes with a\r
+backslash, because\r
+\r
+  /abc\/\r
+\r
+is interpreted as the first line of a pattern that starts with "abc/", causing\r
+pcretest to read the next line as a continuation of the regular expression.\r
+\r
+\r
+PATTERN MODIFIERS\r
+-----------------\r
+\r
+The pattern may be followed by i, m, s, or x to set the PCRE_CASELESS,\r
+PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively. For\r
+example:\r
+\r
+  /caseless/i\r
+\r
+These modifier letters have the same effect as they do in Perl. There are\r
+others which set PCRE options that do not correspond to anything in Perl: /A,\r
+/E, and /X set PCRE_ANCHORED, PCRE_DOLLAR_ENDONLY, and PCRE_EXTRA respectively.\r
+\r
+Searching for all possible matches within each subject string can be requested\r
+by the /g or /G modifier. After finding a match, PCRE is called again to search\r
+the remainder of the subject string. The difference between /g and /G is that\r
+the former uses the startoffset argument to pcre_exec() to start searching at\r
+a new point within the entire string (which is in effect what Perl does),\r
+whereas the latter passes over a shortened substring. This makes a difference\r
+to the matching process if the pattern begins with a lookbehind assertion\r
+(including \b or \B).\r
+\r
+If any call to pcre_exec() in a /g or /G sequence matches an empty string, the\r
+next call is done with the PCRE_NOTEMPTY and PCRE_ANCHORED flags set in order\r
+to search for another, non-empty, match at the same point. If this second match\r
+fails, the start offset is advanced by one, and the normal match is retried.\r
+This imitates the way Perl handles such cases when using the /g modifier or the\r
+split() function.\r
+\r
+There are a number of other modifiers for controlling the way pcretest\r
+operates.\r
+\r
+The /+ modifier requests that as well as outputting the substring that matched\r
+the entire pattern, pcretest should in addition output the remainder of the\r
+subject string. This is useful for tests where the subject contains multiple\r
+copies of the same substring.\r
+\r
+The /L modifier must be followed directly by the name of a locale, for example,\r
+\r
+  /pattern/Lfr\r
+\r
+For this reason, it must be the last modifier letter. The given locale is set,\r
+pcre_maketables() is called to build a set of character tables for the locale,\r
+and this is then passed to pcre_compile() when compiling the regular\r
+expression. Without an /L modifier, NULL is passed as the tables pointer; that\r
+is, /L applies only to the expression on which it appears.\r
+\r
+The /I modifier requests that pcretest output information about the compiled\r
+expression (whether it is anchored, has a fixed first character, and so on). It\r
+does this by calling pcre_fullinfo() after compiling an expression, and\r
+outputting the information it gets back. If the pattern is studied, the results\r
+of that are also output.\r
+\r
+The /D modifier is a PCRE debugging feature, which also assumes /I. It causes\r
+the internal form of compiled regular expressions to be output after\r
+compilation.\r
+\r
+The /S modifier causes pcre_study() to be called after the expression has been\r
+compiled, and the results used when the expression is matched.\r
+\r
+The /M modifier causes the size of memory block used to hold the compiled\r
+pattern to be output.\r
+\r
+The /P modifier causes pcretest to call PCRE via the POSIX wrapper API rather\r
+than its native API. When this is done, all other modifiers except /i, /m, and\r
+/+ are ignored. REG_ICASE is set if /i is present, and REG_NEWLINE is set if /m\r
+is present. The wrapper functions force PCRE_DOLLAR_ENDONLY always, and\r
+PCRE_DOTALL unless REG_NEWLINE is set.\r
+\r
+The /8 modifier causes pcretest to call PCRE with the PCRE_UTF8 option set.\r
+This turns on the (currently incomplete) support for UTF-8 character handling\r
+in PCRE, provided that it was compiled with this support enabled. This modifier\r
+also causes any non-printing characters in output strings to be printed using\r
+the \x{hh...} notation if they are valid UTF-8 sequences.\r
+\r
+\r
+DATA LINES\r
+----------\r
+\r
+Before each data line is passed to pcre_exec(), leading and trailing whitespace\r
+is removed, and it is then scanned for \ escapes. The following are recognized:\r
+\r
+  \a         alarm (= BEL)\r
+  \b         backspace\r
+  \e         escape\r
+  \f         formfeed\r
+  \n         newline\r
+  \r         carriage return\r
+  \t         tab\r
+  \v         vertical tab\r
+  \nnn       octal character (up to 3 octal digits)\r
+  \xhh       hexadecimal character (up to 2 hex digits)\r
+  \x{hh...}  hexadecimal UTF-8 character\r
+\r
+  \A         pass the PCRE_ANCHORED option to pcre_exec()\r
+  \B         pass the PCRE_NOTBOL option to pcre_exec()\r
+  \Cdd       call pcre_copy_substring() for substring dd after a successful\r
+               match (any decimal number less than 32)\r
+  \Gdd       call pcre_get_substring() for substring dd after a successful\r
+               match (any decimal number less than 32)\r
+  \L         call pcre_get_substringlist() after a successful match\r
+  \N         pass the PCRE_NOTEMPTY option to pcre_exec()\r
+  \Odd       set the size of the output vector passed to pcre_exec() to dd\r
+               (any number of decimal digits)\r
+  \Z         pass the PCRE_NOTEOL option to pcre_exec()\r
+\r
+A backslash followed by anything else just escapes the anything else. If the\r
+very last character is a backslash, it is ignored. This gives a way of passing\r
+an empty line as data, since a real empty line terminates the data input.\r
+\r
+If /P was present on the regex, causing the POSIX wrapper API to be used, only\r
+\B, and \Z have any effect, causing REG_NOTBOL and REG_NOTEOL to be passed to\r
+regexec() respectively.\r
+\r
+The use of \x{hh...} to represent UTF-8 characters is not dependent on the use\r
+of the /8 modifier on the pattern. It is recognized always. There may be any\r
+number of hexadecimal digits inside the braces. The result is from one to six\r
+bytes, encoded according to the UTF-8 rules.\r
+\r
+\r
+OUTPUT FROM PCRETEST\r
+--------------------\r
+\r
+When a match succeeds, pcretest outputs the list of captured substrings that\r
+pcre_exec() returns, starting with number 0 for the string that matched the\r
+whole pattern. Here is an example of an interactive pcretest run.\r
+\r
+  $ pcretest\r
+  PCRE version 2.06 08-Jun-1999\r
+\r
+    re> /^abc(\d+)/\r
+  data> abc123\r
+   0: abc123\r
+   1: 123\r
+  data> xyz\r
+  No match\r
+\r
+If the strings contain any non-printing characters, they are output as \0x\r
+escapes, or as \x{...} escapes if the /8 modifier was present on the pattern.\r
+If the pattern has the /+ modifier, then the output for substring 0 is followed\r
+by the the rest of the subject string, identified by "0+" like this:\r
+\r
+    re> /cat/+\r
+  data> cataract\r
+   0: cat\r
+   0+ aract\r
+\r
+If the pattern has the /g or /G modifier, the results of successive matching\r
+attempts are output in sequence, like this:\r
+\r
+    re> /\Bi(\w\w)/g\r
+  data> Mississippi\r
+   0: iss\r
+   1: ss\r
+   0: iss\r
+   1: ss\r
+   0: ipp\r
+   1: pp\r
+\r
+"No match" is output only if the first match attempt fails.\r
+\r
+If any of \C, \G, or \L are present in a data line that is successfully\r
+matched, the substrings extracted by the convenience functions are output with\r
+C, G, or L after the string number instead of a colon. This is in addition to\r
+the normal full list. The string length (that is, the return from the\r
+extraction function) is given in parentheses after each string for \C and \G.\r
+\r
+Note that while patterns can be continued over several lines (a plain ">"\r
+prompt is used for continuations), data lines may not. However newlines can be\r
+included in data by means of the \n escape.\r
+\r
+\r
+COMMAND LINE OPTIONS\r
+--------------------\r
+\r
+If the -p option is given to pcretest, it is equivalent to adding /P to each\r
+regular expression: the POSIX wrapper API is used to call PCRE. None of the\r
+following flags has any effect in this case.\r
+\r
+If the option -d is given to pcretest, it is equivalent to adding /D to each\r
+regular expression: the internal form is output after compilation.\r
+\r
+If the option -i is given to pcretest, it is equivalent to adding /I to each\r
+regular expression: information about the compiled pattern is given after\r
+compilation.\r
+\r
+If the option -m is given to pcretest, it outputs the size of each compiled\r
+pattern after it has been compiled. It is equivalent to adding /M to each\r
+regular expression. For compatibility with earlier versions of pcretest, -s is\r
+a synonym for -m.\r
+\r
+If the -t option is given, each compile, study, and match is run 20000 times\r
+while being timed, and the resulting time per compile or match is output in\r
+milliseconds. Do not set -t with -m, because you will then get the size output\r
+20000 times and the timing will be distorted. If you want to change the number\r
+of repetitions used for timing, edit the definition of LOOPREPEAT at the top of\r
+pcretest.c\r
+\r
+Philip Hazel <ph10@cam.ac.uk>\r
+August 2000\r
diff --git a/pcre/doc/perltest.txt b/pcre/doc/perltest.txt
new file mode 100644 (file)
index 0000000..33155c1
--- /dev/null
@@ -0,0 +1,29 @@
+The perltest program\r
+--------------------\r
+\r
+The perltest program tests Perl's regular expressions; it has the same\r
+specification as pcretest, and so can be given identical input, except that\r
+input patterns can be followed only by Perl's lower case modifiers and /+ (as\r
+used by pcretest), which is recognized and handled by the program.\r
+\r
+The data lines are processed as Perl double-quoted strings, so if they contain\r
+" \ $ or @ characters, these have to be escaped. For this reason, all such\r
+characters in testinput1 and testinput3 are escaped so that they can be used\r
+for perltest as well as for pcretest, and the special upper case modifiers such\r
+as /A that pcretest recognizes are not used in these files. The output should\r
+be identical, apart from the initial identifying banner.\r
+\r
+For testing UTF-8 features, an alternative form of perltest, called perltest8,\r
+is supplied. This requires Perl 5.6 or higher. It recognizes the special\r
+modifier /8 that pcretest uses to invoke UTF-8 functionality. The testinput5\r
+file can be fed to perltest8.\r
+\r
+The testinput2 and testinput4 files are not suitable for feeding to perltest,\r
+since they do make use of the special upper case modifiers and escapes that\r
+pcretest uses to test some features of PCRE. The first of these files also\r
+contains malformed regular expressions, in order to check that PCRE diagnoses\r
+them correctly. Similarly, testinput6 tests UTF-8 features that do not relate\r
+to Perl.\r
+\r
+Philip Hazel <ph10@cam.ac.uk>\r
+August 2000\r
diff --git a/pcre/doc/readme b/pcre/doc/readme
new file mode 100644 (file)
index 0000000..d124ee0
--- /dev/null
@@ -0,0 +1,270 @@
+README file for PCRE (Perl-compatible regular expression library)
+-----------------------------------------------------------------
+
+The latest release of PCRE is always available from
+
+  ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz
+
+Please read the NEWS file if you are upgrading from a previous release.
+
+PCRE has its own native API, but a set of "wrapper" functions that are based on
+the POSIX API are also supplied in the library libpcreposix. Note that this
+just provides a POSIX calling interface to PCRE: the regular expressions
+themselves still follow Perl syntax and semantics. The header file
+for the POSIX-style functions is called pcreposix.h. The official POSIX name is
+regex.h, but I didn't want to risk possible problems with existing files of
+that name by distributing it that way. To use it with an existing program that
+uses the POSIX API, it will have to be renamed or pointed at by a link.
+
+
+Building PCRE on a Unix system
+------------------------------
+
+To build PCRE on a Unix system, run the "configure" command in the PCRE
+distribution directory. This is a standard GNU "autoconf" configuration script,
+for which generic instructions are supplied in INSTALL. On many systems just
+running "./configure" is sufficient, but the usual methods of changing standard
+defaults are available. For example,
+
+CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local
+
+specifies that the C compiler should be run with the flags '-O2 -Wall' instead
+of the default, and that "make install" should install PCRE under /opt/local
+instead of the default /usr/local.
+
+If you want to make use of the experimential, incomplete support for UTF-8
+character strings in PCRE, you must add --enable-utf8 to the "configure"
+command. Without it, the code for handling UTF-8 is not included in the
+library. (Even when included, it still has to be enabled by an option at run
+time.)
+
+The "configure" script builds four files:
+
+. Makefile is built by copying Makefile.in and making substitutions.
+. config.h is built by copying config.in and making substitutions.
+. pcre-config is built by copying pcre-config.in and making substitutions.
+. RunTest is a script for running tests
+
+Once "configure" has run, you can run "make". It builds two libraries called
+libpcre and libpcreposix, a test program called pcretest, and the pcregrep
+command. You can use "make install" to copy these, and the public header file
+pcre.h, to appropriate live directories on your system, in the normal way.
+
+Running "make install" also installs the command pcre-config, which can be used
+to recall information about the PCRE configuration and installation. For
+example,
+
+  pcre-config --version
+
+prints the version number, and
+
+ pcre-config --libs
+
+outputs information about where the library is installed. This command can be
+included in makefiles for programs that use PCRE, saving the programmer from
+having to remember too many details.
+
+
+Shared libraries on Unix systems
+--------------------------------
+
+The default distribution builds PCRE as two shared libraries. This support is
+new and experimental and may not work on all systems. It relies on the
+"libtool" scripts - these are distributed with PCRE. It should build a
+"libtool" script and use this to compile and link shared libraries, which are
+placed in a subdirectory called .libs. The programs pcretest and pcregrep are
+built to use these uninstalled libraries by means of wrapper scripts. When you
+use "make install" to install shared libraries, pcregrep and pcretest are
+automatically re-built to use the newly installed libraries. However, only
+pcregrep is installed, as pcretest is really just a test program.
+
+To build PCRE using static libraries you must use --disable-shared when
+configuring it. For example
+
+./configure --prefix=/usr/gnu --disable-shared
+
+Then run "make" in the usual way.
+
+
+Building on non-Unix systems
+----------------------------
+
+For a non-Unix system, read the comments in the file NON-UNIX-USE. PCRE has
+been compiled on Windows systems and on Macintoshes, but I don't know the
+details because I don't use those systems. It should be straightforward to
+build PCRE on any system that has a Standard C compiler, because it uses only
+Standard C functions.
+
+
+Testing PCRE
+------------
+
+To test PCRE on a Unix system, run the RunTest script in the pcre directory.
+(This can also be run by "make runtest", "make check", or "make test".) For
+other systems, see the instruction in NON-UNIX-USE.
+
+The script runs the pcretest test program (which is documented in
+doc/pcretest.txt) on each of the testinput files (in the testdata directory) in
+turn, and compares the output with the contents of the corresponding testoutput
+file. A file called testtry is used to hold the output from pcretest. To run
+pcretest on just one of the test files, give its number as an argument to
+RunTest, for example:
+
+  RunTest 3
+
+The first and third test files can also be fed directly into the perltest
+script to check that Perl gives the same results. The third file requires the
+additional features of release 5.005, which is why it is kept separate from the
+main test input, which needs only Perl 5.004. In the long run, when 5.005 (or
+higher) is widespread, these two test files may get amalgamated.
+
+The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(),
+pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error
+detection, and run-time flags that are specific to PCRE, as well as the POSIX
+wrapper API. It also uses the debugging flag to check some of the internals of
+pcre_compile().
+
+If you build PCRE with a locale setting that is not the standard C locale, the
+character tables may be different (see next paragraph). In some cases, this may
+cause failures in the second set of tests. For example, in a locale where the
+isprint() function yields TRUE for characters in the range 128-255, the use of
+[:isascii:] inside a character class defines a different set of characters, and
+this shows up in this test as a difference in the compiled code, which is being
+listed for checking. Where the comparison test output contains [\x00-\x7f] the
+test will contain [\x00-\xff], and similarly in some other cases. This is not a
+bug in PCRE.
+
+The fourth set of tests checks pcre_maketables(), the facility for building a
+set of character tables for a specific locale and using them instead of the
+default tables. The tests make use of the "fr" (French) locale. Before running
+the test, the script checks for the presence of this locale by running the
+"locale" command. If that command fails, or if it doesn't include "fr" in the
+list of available locales, the fourth test cannot be run, and a comment is
+output to say why. If running this test produces instances of the error
+
+  ** Failed to set locale "fr"
+
+in the comparison output, it means that locale is not available on your system,
+despite being listed by "locale". This does not mean that PCRE is broken.
+
+The fifth test checks the experimental, incomplete UTF-8 support. It is not run
+automatically unless PCRE is built with UTF-8 support. This file can be fed
+directly to the perltest8 script, which requires Perl 5.6 or higher. The sixth
+file tests internal UTF-8 features of PCRE that are not relevant to Perl.
+
+
+Character tables
+----------------
+
+PCRE uses four tables for manipulating and identifying characters. The final
+argument of the pcre_compile() function is a pointer to a block of memory
+containing the concatenated tables. A call to pcre_maketables() can be used to
+generate a set of tables in the current locale. If the final argument for
+pcre_compile() is passed as NULL, a set of default tables that is built into
+the binary is used.
+
+The source file called chartables.c contains the default set of tables. This is
+not supplied in the distribution, but is built by the program dftables
+(compiled from dftables.c), which uses the ANSI C character handling functions
+such as isalnum(), isalpha(), isupper(), islower(), etc. to build the table
+sources. This means that the default C locale which is set for your system will
+control the contents of these default tables. You can change the default tables
+by editing chartables.c and then re-building PCRE. If you do this, you should
+probably also edit Makefile to ensure that the file doesn't ever get
+re-generated.
+
+The first two 256-byte tables provide lower casing and case flipping functions,
+respectively. The next table consists of three 32-byte bit maps which identify
+digits, "word" characters, and white space, respectively. These are used when
+building 32-byte bit maps that represent character classes.
+
+The final 256-byte table has bits indicating various character types, as
+follows:
+
+    1   white space character
+    2   letter
+    4   decimal digit
+    8   hexadecimal digit
+   16   alphanumeric or '_'
+  128   regular expression metacharacter or binary zero
+
+You should not alter the set of characters that contain the 128 bit, as that
+will cause PCRE to malfunction.
+
+
+Manifest
+--------
+
+The distribution should contain the following files:
+
+(A) The actual source files of the PCRE library functions and their
+    headers:
+
+  dftables.c            auxiliary program for building chartables.c
+  get.c                 )
+  maketables.c          )
+  study.c               ) source of
+  pcre.c                )   the functions
+  pcreposix.c           )
+  pcre.in               "source" for the header for the external API; pcre.h
+                          is built from this by "configure"
+  pcreposix.h           header for the external POSIX wrapper API
+  internal.h            header for internal use
+  config.in             template for config.h, which is built by configure
+
+(B) Auxiliary files:
+
+  AUTHORS               information about the author of PCRE
+  ChangeLog             log of changes to the code
+  INSTALL               generic installation instructions
+  LICENCE               conditions for the use of PCRE
+  COPYING               the same, using GNU's standard name
+  Makefile.in           template for Unix Makefile, which is built by configure
+  NEWS                  important changes in this release
+  NON-UNIX-USE          notes on building PCRE on non-Unix systems
+  README                this file
+  RunTest.in            template for a Unix shell script for running tests
+  config.guess          ) files used by libtool,
+  config.sub            )   used only when building a shared library
+  configure             a configuring shell script (built by autoconf)
+  configure.in          the autoconf input used to build configure
+  doc/Tech.Notes        notes on the encoding
+  doc/pcre.3            man page source for the PCRE functions
+  doc/pcre.html         HTML version
+  doc/pcre.txt          plain text version
+  doc/pcreposix.3       man page source for the POSIX wrapper API
+  doc/pcreposix.html    HTML version
+  doc/pcreposix.txt     plain text version
+  doc/pcretest.txt      documentation of test program
+  doc/perltest.txt      documentation of Perl test program
+  doc/pcregrep.1        man page source for the pcregrep utility
+  doc/pcregrep.html     HTML version
+  doc/pcregrep.txt      plain text version
+  install-sh            a shell script for installing files
+  ltconfig              ) files used to build "libtool",
+  ltmain.sh             )   used only when building a shared library
+  pcretest.c            test program
+  perltest              Perl test program
+  perltest8             Perl test program for UTF-8 tests
+  pcregrep.c            source of a grep utility that uses PCRE
+  pcre-config.in        source of script which retains PCRE information
+  testdata/testinput1   test data, compatible with Perl 5.004 and 5.005
+  testdata/testinput2   test data for error messages and non-Perl things
+  testdata/testinput3   test data, compatible with Perl 5.005
+  testdata/testinput4   test data for locale-specific tests
+  testdata/testinput5   test data for UTF-8 tests compatible with Perl 5.6
+  testdata/testinput6   test data for other UTF-8 tests
+  testdata/testoutput1  test results corresponding to testinput1
+  testdata/testoutput2  test results corresponding to testinput2
+  testdata/testoutput3  test results corresponding to testinput3
+  testdata/testoutput4  test results corresponding to testinput4
+  testdata/testoutput5  test results corresponding to testinput5
+  testdata/testoutput6  test results corresponding to testinput6
+
+(C) Auxiliary files for Win32 DLL
+
+  dll.mk
+  pcre.def
+
+Philip Hazel <ph10@cam.ac.uk>
+August 2000
diff --git a/pcre/get.c b/pcre/get.c
new file mode 100644 (file)
index 0000000..42e9bd4
--- /dev/null
@@ -0,0 +1,227 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/*
+This is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language. See
+the file Tech.Notes for some information on the internals.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+           Copyright (c) 1997-2000 University of Cambridge
+
+-----------------------------------------------------------------------------
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), then the terms of that licence shall
+   supersede any condition above with which it is incompatible.
+-----------------------------------------------------------------------------
+*/
+
+/* This module contains some convenience functions for extracting substrings
+from the subject string after a regex match has succeeded. The original idea
+for these functions came from Scott Wimer <scottw@cgibuilder.com>. */
+
+
+/* Include the internals header, which itself includes Standard C headers plus
+the external pcre header. */
+
+#include "internal.h"
+
+
+
+/*************************************************
+*      Copy captured string to given buffer      *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer.
+Note that we use memcpy() rather than strncpy() in case there are binary zeros
+in the string.
+
+Arguments:
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  stringnumber   the number of the required substring
+  buffer         where to put the substring
+  size           the size of the buffer
+
+Returns:         if successful:
+                   the length of the copied string, not including the zero
+                   that is put on the end; can be zero
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) buffer too small
+                   PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+int
+pcre_copy_substring(const char *subject, int *ovector, int stringcount,
+  int stringnumber, char *buffer, int size)
+{
+int yield;
+if (stringnumber < 0 || stringnumber >= stringcount)
+  return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
+memcpy(buffer, subject + ovector[stringnumber], yield);
+buffer[yield] = 0;
+return yield;
+}
+
+
+
+/*************************************************
+*      Copy all captured strings to new store    *
+*************************************************/
+
+/* This function gets one chunk of store and builds a list of pointers and all
+of the captured substrings in it. A NULL pointer is put on the end of the list.
+
+Arguments:
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  listptr        set to point to the list of pointers
+
+Returns:         if successful: 0
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) failed to get store
+*/
+
+int
+pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
+  const char ***listptr)
+{
+int i;
+int size = sizeof(char *);
+int double_count = stringcount * 2;
+char **stringlist;
+char *p;
+
+for (i = 0; i < double_count; i += 2)
+  size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
+
+stringlist = (char **)(pcre_malloc)(size);
+if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
+
+*listptr = (const char **)stringlist;
+p = (char *)(stringlist + stringcount + 1);
+
+for (i = 0; i < double_count; i += 2)
+  {
+  int len = ovector[i+1] - ovector[i];
+  memcpy(p, subject + ovector[i], len);
+  *stringlist++ = p;
+  p += len;
+  *p++ = 0;
+  }
+
+*stringlist = NULL;
+return 0;
+}
+
+
+
+/*************************************************
+*   Free store obtained by get_substring_list    *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (pcre_free)() directly.
+
+Argument:   the result of a previous pcre_get_substring_list()
+Returns:    nothing
+*/
+
+void
+pcre_free_substring_list(const char **pointer)
+{
+(pcre_free)((void *)pointer);
+}
+
+
+
+/*************************************************
+*      Copy captured string to new store         *
+*************************************************/
+
+/* This function copies a single captured substring into a piece of new
+store
+
+Arguments:
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  stringnumber   the number of the required substring
+  stringptr      where to put a pointer to the substring
+
+Returns:         if successful:
+                   the length of the string, not including the zero that
+                   is put on the end; can be zero
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) failed to get store
+                   PCRE_ERROR_NOSUBSTRING (-7) substring not present
+*/
+
+int
+pcre_get_substring(const char *subject, int *ovector, int stringcount,
+  int stringnumber, const char **stringptr)
+{
+int yield;
+char *substring;
+if (stringnumber < 0 || stringnumber >= stringcount)
+  return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+substring = (char *)(pcre_malloc)(yield + 1);
+if (substring == NULL) return PCRE_ERROR_NOMEMORY;
+memcpy(substring, subject + ovector[stringnumber], yield);
+substring[yield] = 0;
+*stringptr = substring;
+return yield;
+}
+
+
+
+/*************************************************
+*       Free store obtained by get_substring     *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (pcre_free)() directly.
+
+Argument:   the result of a previous pcre_get_substring()
+Returns:    nothing
+*/
+
+void
+pcre_free_substring(const char *pointer)
+{
+(pcre_free)((void *)pointer);
+}
+
+/* End of get.c */
diff --git a/pcre/install b/pcre/install
new file mode 100644 (file)
index 0000000..0880281
--- /dev/null
@@ -0,0 +1,185 @@
+Basic Installation
+==================
+
+   These are generic installation instructions that apply to systems that
+can run the `configure' shell script - Unix systems and any that imitate
+it. They are not specific to PCRE. There are PCRE-specific instructions
+for non-Unix systems in the file NON-UNIX-USE.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/pcre/install-sh b/pcre/install-sh
new file mode 100644 (file)
index 0000000..e9de238
--- /dev/null
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/pcre/internal.h b/pcre/internal.h
new file mode 100644 (file)
index 0000000..25bb7f8
--- /dev/null
@@ -0,0 +1,381 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+
+/* This is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language. See
+the file Tech.Notes for some information on the internals.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+           Copyright (c) 1997-2000 University of Cambridge
+
+-----------------------------------------------------------------------------
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), then the terms of that licence shall
+   supersede any condition above with which it is incompatible.
+-----------------------------------------------------------------------------
+*/
+
+/* This header contains definitions that are shared between the different
+modules, but which are not relevant to the outside. */
+
+/* Get the definitions provided by running "configure" */
+
+#include "config.h"
+
+/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
+define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
+is set. Otherwise, include an emulating function for those systems that have
+neither (there some non-Unix environments where this is the case). This assumes
+that all calls to memmove are moving strings upwards in store, which is the
+case in PCRE. */
+
+#if ! HAVE_MEMMOVE
+#undef  memmove        /* some systems may have a macro */
+#if HAVE_BCOPY
+#define memmove(a, b, c) bcopy(b, a, c)
+#else
+void *
+pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n)
+{
+int i;
+dest += n;
+src += n;
+for (i = 0; i < n; ++i) *(--dest) =  *(--src);
+}
+#define memmove(a, b, c) pcre_memmove(a, b, c)
+#endif
+#endif
+
+/* Standard C headers plus the external interface definition */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pcre.h"
+
+/* In case there is no definition of offsetof() provided - though any proper
+Standard C system should have one. */
+
+#ifndef offsetof
+#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
+#endif
+
+/* These are the public options that can change during matching. */
+
+#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
+
+/* Private options flags start at the most significant end of the four bytes,
+but skip the top bit so we can use ints for convenience without getting tangled
+with negative values. The public options defined in pcre.h start at the least
+significant end. Make sure they don't overlap, though now that we have expanded
+to four bytes there is plenty of space. */
+
+#define PCRE_FIRSTSET      0x40000000  /* first_char is set */
+#define PCRE_REQCHSET      0x20000000  /* req_char is set */
+#define PCRE_STARTLINE     0x10000000  /* start after \n for multiline */
+#define PCRE_INGROUP       0x08000000  /* compiling inside a group */
+#define PCRE_ICHANGED      0x04000000  /* i option changes within regex */
+
+/* Options for the "extra" block produced by pcre_study(). */
+
+#define PCRE_STUDY_MAPPED   0x01     /* a map of starting chars exists */
+
+/* Masks for identifying the public options which are permitted at compile
+time, run time or study time, respectively. */
+
+#define PUBLIC_OPTIONS \
+  (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
+   PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8)
+
+#define PUBLIC_EXEC_OPTIONS \
+  (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY)
+
+#define PUBLIC_STUDY_OPTIONS 0   /* None defined */
+
+/* Magic number to provide a small check against being handed junk. */
+
+#define MAGIC_NUMBER  0x50435245UL   /* 'PCRE' */
+
+/* Miscellaneous definitions */
+
+typedef int BOOL;
+
+#define FALSE   0
+#define TRUE    1
+
+/* These are escaped items that aren't just an encoding of a particular data
+value such as \n. They must have non-zero values, as check_escape() returns
+their negation. Also, they must appear in the same order as in the opcode
+definitions below, up to ESC_z. The final one must be ESC_REF as subsequent
+values are used for \1, \2, \3, etc. There is a test in the code for an escape
+greater than ESC_b and less than ESC_X to detect the types that may be
+repeated. If any new escapes are put in-between that don't consume a character,
+that code will have to change. */
+
+enum { ESC_A = 1, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w,
+       ESC_Z, ESC_z, ESC_REF };
+
+/* Opcode table: OP_BRA must be last, as all values >= it are used for brackets
+that extract substrings. Starting from 1 (i.e. after OP_END), the values up to
+OP_EOD must correspond in order to the list of escapes immediately above. */
+
+enum {
+  OP_END,            /* End of pattern */
+
+  /* Values corresponding to backslashed metacharacters */
+
+  OP_SOD,            /* Start of data: \A */
+  OP_NOT_WORD_BOUNDARY,  /* \B */
+  OP_WORD_BOUNDARY,      /* \b */
+  OP_NOT_DIGIT,          /* \D */
+  OP_DIGIT,              /* \d */
+  OP_NOT_WHITESPACE,     /* \S */
+  OP_WHITESPACE,         /* \s */
+  OP_NOT_WORDCHAR,       /* \W */
+  OP_WORDCHAR,           /* \w */
+  OP_EODN,           /* End of data or \n at end of data: \Z. */
+  OP_EOD,            /* End of data: \z */
+
+  OP_OPT,            /* Set runtime options */
+  OP_CIRC,           /* Start of line - varies with multiline switch */
+  OP_DOLL,           /* End of line - varies with multiline switch */
+  OP_ANY,            /* Match any character */
+  OP_CHARS,          /* Match string of characters */
+  OP_NOT,            /* Match anything but the following char */
+
+  OP_STAR,           /* The maximizing and minimizing versions of */
+  OP_MINSTAR,        /* all these opcodes must come in pairs, with */
+  OP_PLUS,           /* the minimizing one second. */
+  OP_MINPLUS,        /* This first set applies to single characters */
+  OP_QUERY,
+  OP_MINQUERY,
+  OP_UPTO,           /* From 0 to n matches */
+  OP_MINUPTO,
+  OP_EXACT,          /* Exactly n matches */
+
+  OP_NOTSTAR,        /* The maximizing and minimizing versions of */
+  OP_NOTMINSTAR,     /* all these opcodes must come in pairs, with */
+  OP_NOTPLUS,        /* the minimizing one second. */
+  OP_NOTMINPLUS,     /* This first set applies to "not" single characters */
+  OP_NOTQUERY,
+  OP_NOTMINQUERY,
+  OP_NOTUPTO,        /* From 0 to n matches */
+  OP_NOTMINUPTO,
+  OP_NOTEXACT,       /* Exactly n matches */
+
+  OP_TYPESTAR,       /* The maximizing and minimizing versions of */
+  OP_TYPEMINSTAR,    /* all these opcodes must come in pairs, with */
+  OP_TYPEPLUS,       /* the minimizing one second. These codes must */
+  OP_TYPEMINPLUS,    /* be in exactly the same order as those above. */
+  OP_TYPEQUERY,      /* This set applies to character types such as \d */
+  OP_TYPEMINQUERY,
+  OP_TYPEUPTO,       /* From 0 to n matches */
+  OP_TYPEMINUPTO,
+  OP_TYPEEXACT,      /* Exactly n matches */
+
+  OP_CRSTAR,         /* The maximizing and minimizing versions of */
+  OP_CRMINSTAR,      /* all these opcodes must come in pairs, with */
+  OP_CRPLUS,         /* the minimizing one second. These codes must */
+  OP_CRMINPLUS,      /* be in exactly the same order as those above. */
+  OP_CRQUERY,        /* These are for character classes and back refs */
+  OP_CRMINQUERY,
+  OP_CRRANGE,        /* These are different to the three seta above. */
+  OP_CRMINRANGE,
+
+  OP_CLASS,          /* Match a character class */
+  OP_REF,            /* Match a back reference */
+  OP_RECURSE,        /* Match this pattern recursively */
+
+  OP_ALT,            /* Start of alternation */
+  OP_KET,            /* End of group that doesn't have an unbounded repeat */
+  OP_KETRMAX,        /* These two must remain together and in this */
+  OP_KETRMIN,        /* order. They are for groups the repeat for ever. */
+
+  /* The assertions must come before ONCE and COND */
+
+  OP_ASSERT,         /* Positive lookahead */
+  OP_ASSERT_NOT,     /* Negative lookahead */
+  OP_ASSERTBACK,     /* Positive lookbehind */
+  OP_ASSERTBACK_NOT, /* Negative lookbehind */
+  OP_REVERSE,        /* Move pointer back - used in lookbehind assertions */
+
+  /* ONCE and COND must come after the assertions, with ONCE first, as there's
+  a test for >= ONCE for a subpattern that isn't an assertion. */
+
+  OP_ONCE,           /* Once matched, don't back up into the subpattern */
+  OP_COND,           /* Conditional group */
+  OP_CREF,           /* Used to hold an extraction string number */
+
+  OP_BRAZERO,        /* These two must remain together and in this */
+  OP_BRAMINZERO,     /* order. */
+
+  OP_BRA             /* This and greater values are used for brackets that
+                        extract substrings. */
+};
+
+/* The highest extraction number. This is limited by the number of opcodes
+left after OP_BRA, i.e. 255 - OP_BRA. We actually set it somewhat lower. */
+
+#define EXTRACT_MAX  99
+
+/* The texts of compile-time error messages are defined as macros here so that
+they can be accessed by the POSIX wrapper and converted into error codes.  Yes,
+I could have used error codes in the first place, but didn't feel like changing
+just to accommodate the POSIX wrapper. */
+
+#define ERR1  "\\ at end of pattern"
+#define ERR2  "\\c at end of pattern"
+#define ERR3  "unrecognized character follows \\"
+#define ERR4  "numbers out of order in {} quantifier"
+#define ERR5  "number too big in {} quantifier"
+#define ERR6  "missing terminating ] for character class"
+#define ERR7  "invalid escape sequence in character class"
+#define ERR8  "range out of order in character class"
+#define ERR9  "nothing to repeat"
+#define ERR10 "operand of unlimited repeat could match the empty string"
+#define ERR11 "internal error: unexpected repeat"
+#define ERR12 "unrecognized character after (?"
+#define ERR13 "too many capturing parenthesized sub-patterns"
+#define ERR14 "missing )"
+#define ERR15 "back reference to non-existent subpattern"
+#define ERR16 "erroffset passed as NULL"
+#define ERR17 "unknown option bit(s) set"
+#define ERR18 "missing ) after comment"
+#define ERR19 "too many sets of parentheses"
+#define ERR20 "regular expression too large"
+#define ERR21 "failed to get memory"
+#define ERR22 "unmatched parentheses"
+#define ERR23 "internal error: code overflow"
+#define ERR24 "unrecognized character after (?<"
+#define ERR25 "lookbehind assertion is not fixed length"
+#define ERR26 "malformed number after (?("
+#define ERR27 "conditional group contains more than two branches"
+#define ERR28 "assertion expected after (?("
+#define ERR29 "(?p must be followed by )"
+#define ERR30 "unknown POSIX class name"
+#define ERR31 "POSIX collating elements are not supported"
+#define ERR32 "this version of PCRE is not compiled with PCRE_UTF8 support"
+#define ERR33 "characters with values > 255 are not yet supported in classes"
+#define ERR34 "character value in \\x{...} sequence is too large"
+#define ERR35 "invalid condition (?(0)"
+
+/* All character handling must be done as unsigned characters. Otherwise there
+are problems with top-bit-set characters and functions such as isspace().
+However, we leave the interface to the outside world as char *, because that
+should make things easier for callers. We define a short type for unsigned char
+to save lots of typing. I tried "uchar", but it causes problems on Digital
+Unix, where it is defined in sys/types, so use "uschar" instead. */
+
+typedef unsigned char uschar;
+
+/* The real format of the start of the pcre block; the actual code vector
+runs on as long as necessary after the end. */
+
+typedef struct real_pcre {
+  unsigned long int magic_number;
+  size_t size;
+  const unsigned char *tables;
+  unsigned long int options;
+  uschar top_bracket;
+  uschar top_backref;
+  uschar first_char;
+  uschar req_char;
+  uschar code[1];
+} real_pcre;
+
+/* The real format of the extra block returned by pcre_study(). */
+
+typedef struct real_pcre_extra {
+  uschar options;
+  uschar start_bits[32];
+} real_pcre_extra;
+
+
+/* Structure for passing "static" information around between the functions
+doing the compiling, so that they are thread-safe. */
+
+typedef struct compile_data {
+  const uschar *lcc;            /* Points to lower casing table */
+  const uschar *fcc;            /* Points to case-flipping table */
+  const uschar *cbits;          /* Points to character type table */
+  const uschar *ctypes;         /* Points to table of type maps */
+} compile_data;
+
+/* Structure for passing "static" information around between the functions
+doing the matching, so that they are thread-safe. */
+
+typedef struct match_data {
+  int    errorcode;             /* As it says */
+  int   *offset_vector;         /* Offset vector */
+  int    offset_end;            /* One past the end */
+  int    offset_max;            /* The maximum usable for return data */
+  const uschar *lcc;            /* Points to lower casing table */
+  const uschar *ctypes;         /* Points to table of type maps */
+  BOOL   offset_overflow;       /* Set if too many extractions */
+  BOOL   notbol;                /* NOTBOL flag */
+  BOOL   noteol;                /* NOTEOL flag */
+  BOOL   utf8;                  /* UTF8 flag */
+  BOOL   endonly;               /* Dollar not before final \n */
+  BOOL   notempty;              /* Empty string match not wanted */
+  const uschar *start_pattern;  /* For use when recursing */
+  const uschar *start_subject;  /* Start of the subject string */
+  const uschar *end_subject;    /* End of the subject string */
+  const uschar *start_match;    /* Start of this match attempt */
+  const uschar *end_match_ptr;  /* Subject position at end match */
+  int    end_offset_top;        /* Highwater mark at end of match */
+} match_data;
+
+/* Bit definitions for entries in the pcre_ctypes table. */
+
+#define ctype_space   0x01
+#define ctype_letter  0x02
+#define ctype_digit   0x04
+#define ctype_xdigit  0x08
+#define ctype_word    0x10   /* alphameric or '_' */
+#define ctype_meta    0x80   /* regexp meta char or zero (end pattern) */
+
+/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
+of bits for a class map. Some classes are built by combining these tables. */
+
+#define cbit_space     0      /* [:space:] or \s */
+#define cbit_xdigit   32      /* [:xdigit:] */
+#define cbit_digit    64      /* [:digit:] or \d */
+#define cbit_upper    96      /* [:upper:] */
+#define cbit_lower   128      /* [:lower:] */
+#define cbit_word    160      /* [:word:] or \w */
+#define cbit_graph   192      /* [:graph:] */
+#define cbit_print   224      /* [:print:] */
+#define cbit_punct   256      /* [:punct:] */
+#define cbit_cntrl   288      /* [:cntrl:] */
+#define cbit_length  320      /* Length of the cbits table */
+
+/* Offsets of the various tables from the base tables pointer, and
+total length. */
+
+#define lcc_offset      0
+#define fcc_offset    256
+#define cbits_offset  512
+#define ctypes_offset (cbits_offset + cbit_length)
+#define tables_length (ctypes_offset + 256)
+
+/* End of internal.h */
diff --git a/pcre/licence b/pcre/licence
new file mode 100644 (file)
index 0000000..34d20db
--- /dev/null
@@ -0,0 +1,46 @@
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2000 University of Cambridge
+
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission. In practice, this means that if you use
+   PCRE in software which you distribute to others, commercially or
+   otherwise, you must put a sentence like this
+
+     Regular expression support is provided by the PCRE library package,
+     which is open source software, written by Philip Hazel, and copyright
+     by the University of Cambridge, England.
+
+   somewhere reasonably visible in your documentation and in any relevant
+   files or online help data or similar. A reference to the ftp site for
+   the source, that is, to
+
+     ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+
+   should also be given in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), then the terms of that licence shall
+   supersede any condition above with which it is incompatible.
+
+End
diff --git a/pcre/ltconfig b/pcre/ltconfig
new file mode 100644 (file)
index 0000000..a01334f
--- /dev/null
@@ -0,0 +1,3078 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) PATH_SEPARATOR=';' ;;
+    *)     PATH_SEPARATOR=':' ;;
+  esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != Xset; then
+  # find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+   test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running ltconfig again with it.
+      ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf "%s\n"'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.4
+TIMESTAMP=" (1.385.2.196 1999/12/07 21:47:57)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+    --debug                enable verbose shell tracing
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --disable-fast-install do not optimize for fast installation
+    --enable-dlopen        enable dlopen support
+    --enable-win32-dll     enable building dlls on win32 hosts
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+-o, --output=FILE          specify the output file [default=$default_ofile]
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+    --disable-lock         disable file locking
+    --cache-file=FILE      configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --disable-fast-install) enable_fast_install=no ;;
+
+  --enable-dlopen) enable_dlopen=yes ;;
+
+  --enable-win32-dll) enable_win32_dll=yes ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --output | -o) prev=ofile ;;
+  --output=*) ofile="$optarg" ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  --disable-lock) need_locks=no ;;
+
+  --cache-file=*) cache_file="$optarg" ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test ! -f "$ltmain"; then
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi
+if test "X${LANG+set}"   = Xset; then LANG=C;   export LANG;   fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+  echo "loading cache $cache_file within ltconfig"
+  . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to LTMAIN.
+  srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$SHELL $ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$SHELL $ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:581: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+  # Append any warnings to the config.log.
+  cat conftest.err 1>&5
+
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  cat conftest.err 1>&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_exeext="no"
+  $rm conftest*
+  echo 'main () { return 0; }' > conftest.c
+  echo "$progname:629: checking for executable suffix" >& 5
+  if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    for ac_file in conftest.*; do
+      case $ac_file in
+      *.c | *.err | *.$objext ) ;;
+      *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+      esac
+    done
+  else
+    cat conftest.err 1>&5
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+  exeext=""
+else
+  exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+
+  case "$host_os" in
+  beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+    # PIC is the default for these OSes.
+    ;;
+  aix*)
+    # Below there is a dirty hack to force normal static linking with -ldl
+    # The problem is because libdl dynamically linked with both libc and
+    # libC (AIX C++ library), which obviously doesn't included in libraries
+    # list by gcc. This cause undefined symbols with -static flags.
+    # This hack allows C programs to be linked with "-static -ldl", but
+    # we not sure about C++ programs.
+    link_static_flag="$link_static_flag ${wl}-lC"
+    ;;
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec; then
+       pic_flag=-Kconform_pic
+    fi
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4* | osf5*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      pic_flag='-Kconform_pic'
+      link_static_flag='-Bstatic'
+    fi
+    ;;
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+    
+    case "$host_os" in
+    hpux9* | hpux10* | hpux11*)
+      # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+      # create non-PIC objects.  So, if there were any warnings, we assume that
+      # PIC is not supported.
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       can_build_shared=no
+       pic_flag=
+      else
+       echo "$ac_t"yes 1>&6
+       pic_flag=" $pic_flag"
+      fi
+      ;;
+    *)
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+      ;;
+    esac
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+    if test -s out/conftest.err; then
+      echo "$ac_t"no 1>&6
+      compiler_c_o=no
+    else
+      echo "$ac_t"yes 1>&6
+      compiler_c_o=yes
+    fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  compiler_c_o=no
+  echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_o_lo=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_o_lo=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_o_lo=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$ac_t$hard_links" 1>&6
+  $rm conftest*
+  if test "$hard_links" = no; then
+    echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+  echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_rtti_exceptions=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_rtti_exceptions=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_rtti_exceptions=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+  
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftest.dat
+  if ln -s X conftest.dat 2>/dev/null; then
+    $rm conftest.dat
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:991: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:1015: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:1018: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$with_gcc" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case "$host_os" in
+  aix3* | aix4*)
+    # On AIX, the GNU linker is very broken
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def  $objdir/$soname-ltdll.$objext $libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols'
+
+    archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+      _lt_hint=1;
+      for symbol in `cat $export_symbols`; do
+       echo "  \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def;
+       _lt_hint=`expr 1 + \$_lt_hint`;
+      done~
+      test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+      old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' 
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+      # can we support soname and/or expsyms with a.out? -oliva
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;      
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+        whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+        whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+    hardcode_libdir_separator=':'
+    if test "$with_gcc" = yes; then
+      collect2name=`${CC} -print-prog-name=collect2`
+      if test -f "$collect2name" && \
+        strings "$collect2name" | grep resolve_lib_name >/dev/null
+      then
+       # We have reworked collect2
+       hardcode_direct=yes
+      else
+       # We have old collect2
+       hardcode_direct=unsupported
+       # It fails to find uninstalled libraries when the uninstalled
+       # path is not listed in the libpath.  Setting hardcode_minus_L
+       # to unsupported forces relinking
+       hardcode_minus_L=yes
+       hardcode_libdir_flag_spec='-L$libdir'
+       hardcode_libdir_separator=
+      fi
+      shared_flag='-shared'
+    else
+      shared_flag='${wl}-bM:SRE'
+      hardcode_direct=yes
+    fi
+    allow_undefined_flag=' ${wl}-berok'
+    archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+    archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+    case "$host_os" in aix4.[01]|aix4.[01].*)
+      # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+      always_export_symbols=yes ;;
+    esac
+   ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+    fix_srcfile_path='`cygpath -w $srcfile`'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case "$host_os" in
+    hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+                        # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts'      # ELF
+    fi
+    hardcode_libdir_flag_spec='${wl}-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)  # As osf3* with the addition of the -msym flag
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ;;
+
+  solaris*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case "$host_os" in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    hardcode_direct=no #Motorola manual says yes, but my tests say they lie 
+    ;;  
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  unixware7*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -B"
+         break
+       elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -p"
+         break
+       else
+         NM=${NM="$ac_dir/nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  global_symbol_pipe="sed -n -e 's/^.*[        ]\($symcode\)[  ][      ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  $rm conftest*
+  cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  echo "$progname:1635: checking if global_symbol_pipe works" >&5
+  if { (eval echo $progname:1636: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { echo "$progname:1639: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+       if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+         cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         sed 's/^. \(.*\) \(.*\)$/  {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+         cat <<\EOF >> conftest.c
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$objext conftstm.$objext
+         save_LIBS="$LIBS"
+         save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$objext"
+         CFLAGS="$CFLAGS$no_builtin_flag"
+         if { (eval echo $progname:1691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+           pipe_works=yes
+         else
+           echo "$progname: failed program was:" >&5
+           cat conftest.c >&5
+         fi
+         LIBS="$save_LIBS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    global_symbol_pipe=
+  fi
+done
+if test "$pipe_works" = yes; then
+  echo "${ac_t}ok" 1>&6
+else
+  echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4*)
+  version_type=linux
+  # AIX has no versioning support, so currently we can not hardcode correct
+  # soname into executable. Probably we can add versioning support to
+  # collect2, so additional links can be useful in future.
+  # We preserve .a as extension for shared libraries though AIX4.2
+  # and later linker supports .so
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+  shlibpath_var=LIBPATH
+  deplibs_check_method=pass_all
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen="load_add_on"
+  lt_cv_dlopen_libs=
+  lt_cv_dlopen_self=yes
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  if test "$with_gcc" = yes; then
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+  else
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+  fi
+  dynamic_linker='Win32 ld.exe'
+  deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  file_magic_cmd='${OBJDUMP} -f'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  lt_cv_dlopen="LoadLibrary"
+  lt_cv_dlopen_libs=
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+  
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case "$version_type" in
+    freebsd-elf*)
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      deplibs_check_method=unknown
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_os" in
+  freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+  case "$host_os" in
+  irix5*)
+    libsuff= shlibsuff=
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case "$LD" in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  deplibs_check_method='pass_all'
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd*)
+  version_type=sunos
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+openbsd*)
+  version_type=sunos
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+    need_version=no
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  # this will be overridden with pass_all, but let us keep it just in case
+  deplibs_check_method='file_magic COFF format alpha shared library'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  deplibs_check_method='pass_all'
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/lib/libc.so
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_vendor" in
+    ncr)
+      deplibs_check_method='pass_all'
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+  if test x$can_build_shared = xyes; then
+    test x$enable_win32_dll = xno && can_build_shared=no
+    echo "checking if package supports dlls... $can_build_shared" 1>&6
+  fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+  case "$deplibs_check_method" in
+  "file_magic "*)
+    file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+    if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+       egrep "$file_magic_regex" > /dev/null; then
+      :
+    else
+      cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+    fi ;;
+  esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+  lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2212: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2220 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2252: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2257 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2282: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2299: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2307 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2339: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2344 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2387: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2395 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  fi
+
+  case "$lt_cv_dlopen" in
+  dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2452: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2457 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile >/dev/null 2>conftest.out"
+{ (eval echo $progname:2462: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+    if test "x$ac_cv_header_dlfcn_h" = xyes; then
+      CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    fi
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+  echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2490: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self=cross
+  else
+    cat > conftest.c <<EOF
+#line 2498 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+              if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+  if test "$lt_cv_dlopen_self" = yes; then
+    LDFLAGS="$LDFLAGS $link_static_flag"
+  echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2563: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self_static=cross
+  else
+    cat > conftest.c <<EOF
+#line 2571 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+    if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self_static=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+    ;;
+  esac
+
+  case "$lt_cv_dlopen_self" in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case "$lt_cv_dlopen_self_static" in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+  # Now quote all the things that may contain metacharacters.
+  for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+    AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+    file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case "$var" in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case "$ltecho" in
+  *'\$0 --fallback-echo"')
+    ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+  trap "$rm \"$ofile\"; exit 1" 1 2 15
+  echo "creating $ofile"
+  $rm "$ofile"
+  cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+  cfgfile="$ofile"
+  ;;
+
+*)
+  # Double-quote the variables that need it (for aesthetics).
+  for var in old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+    eval "$var=\\\"\$var\\\""
+  done
+
+  # Just create a config file.
+  cfgfile="$ofile.cfg"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  echo "creating $cfgfile"
+  $rm "$cfgfile"
+  cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+  ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+  echo '### END LIBTOOL CONFIG' >> "$ofile"
+  echo >> "$ofile"
+  case "$host_os" in
+  aix3*)
+    cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # Append the ltmain.sh script.
+  sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+
+  chmod +x "$ofile"
+  ;;
+
+*)
+  # Compile the libtool program.
+  echo "FIXME: would compile $ltmain"
+  ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
index 50515ad..ab65054 100644 (file)
@@ -2619,7 +2619,7 @@ static const void *lt_preloaded_setup() {
          # linked before any other PIC object.  But we must not use
          # pic_flag when linking with -static.  The problem exists in
          # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)\r
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
            case "$compile_command " in
            *" -static "*) ;;
            *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
diff --git a/pcre/maketables.c b/pcre/maketables.c
new file mode 100644 (file)
index 0000000..c0f06c0
--- /dev/null
@@ -0,0 +1,132 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/*
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+           Copyright (c) 1997-2000 University of Cambridge
+
+-----------------------------------------------------------------------------
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), then the terms of that licence shall
+   supersede any condition above with which it is incompatible.
+-----------------------------------------------------------------------------
+
+See the file Tech.Notes for some information on the internals.
+*/
+
+
+/* This file is compiled on its own as part of the PCRE library. However,
+it is also included in the compilation of dftables.c, in which case the macro
+DFTABLES is defined. */
+
+#ifndef DFTABLES
+#include "internal.h"
+#endif
+
+
+
+/*************************************************
+*           Create PCRE character tables         *
+*************************************************/
+
+/* This function builds a set of character tables for use by PCRE and returns
+a pointer to them. They are build using the ctype functions, and consequently
+their contents will depend upon the current locale setting. When compiled as
+part of the library, the store is obtained via pcre_malloc(), but when compiled
+inside dftables, use malloc().
+
+Arguments:   none
+Returns:     pointer to the contiguous block of data
+*/
+
+unsigned const char *
+pcre_maketables(void)
+{
+unsigned char *yield, *p;
+int i;
+
+#ifndef DFTABLES
+yield = (unsigned char*)(pcre_malloc)(tables_length);
+#else
+yield = (unsigned char*)malloc(tables_length);
+#endif
+
+if (yield == NULL) return NULL;
+p = yield;
+
+/* First comes the lower casing table */
+
+for (i = 0; i < 256; i++) *p++ = tolower(i);
+
+/* Next the case-flipping table */
+
+for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
+
+/* Then the character class tables. Don't try to be clever and save effort
+on exclusive ones - in some locales things may be different. */
+
+memset(p, 0, cbit_length);
+for (i = 0; i < 256; i++)
+  {
+  if (isdigit(i))
+    {
+    p[cbit_digit  + i/8] |= 1 << (i&7);
+    p[cbit_word   + i/8] |= 1 << (i&7);
+    }
+  if (isupper(i))
+    {
+    p[cbit_upper  + i/8] |= 1 << (i&7);
+    p[cbit_word   + i/8] |= 1 << (i&7);
+    }
+  if (islower(i))
+    {
+    p[cbit_lower  + i/8] |= 1 << (i&7);
+    p[cbit_word   + i/8] |= 1 << (i&7);
+    }
+  if (i == '_')   p[cbit_word   + i/8] |= 1 << (i&7);
+  if (isspace(i)) p[cbit_space  + i/8] |= 1 << (i&7);
+  if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
+  if (isgraph(i)) p[cbit_graph  + i/8] |= 1 << (i&7);
+  if (isprint(i)) p[cbit_print  + i/8] |= 1 << (i&7);
+  if (ispunct(i)) p[cbit_punct  + i/8] |= 1 << (i&7);
+  if (iscntrl(i)) p[cbit_cntrl  + i/8] |= 1 << (i&7);
+  }
+p += cbit_length;
+
+/* Finally, the character type table */
+
+for (i = 0; i < 256; i++)
+  {
+  int x = 0;
+  if (isspace(i)) x += ctype_space;
+  if (isalpha(i)) x += ctype_letter;
+  if (isdigit(i)) x += ctype_digit;
+  if (isxdigit(i)) x += ctype_xdigit;
+  if (isalnum(i) || i == '_') x += ctype_word;
+  if (strchr("*+?{^.$|()[", i) != 0) x += ctype_meta;
+  *p++ = x;
+  }
+
+return yield;
+}
+
+/* End of maketables.c */
diff --git a/pcre/pcre-config b/pcre/pcre-config
new file mode 100644 (file)
index 0000000..ac9ccfe
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+prefix=/usr/local
+exec_prefix=${prefix}
+exec_prefix_set=no
+
+usage="\
+Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]"
+
+if test $# -eq 0; then
+      echo "${usage}" 1>&2
+      exit 1
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo $prefix
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+    --version)
+      echo 3.4
+      ;;
+    --cflags | --cflags-posix)
+      if test ${prefix}/include != /usr/include ; then
+        includes=-I${prefix}/include
+      fi
+      echo $includes
+      ;;
+    --libs-posix)
+      echo -L${exec_prefix}/lib -lpcreposix -lpcre
+      ;;
+    --libs)
+      echo -L${exec_prefix}/lib -lpcre
+      ;;
+    *)
+      echo "${usage}" 1>&2
+      exit 1
+      ;;
+  esac
+  shift
+done
diff --git a/pcre/pcre-config.in b/pcre/pcre-config.in
new file mode 100644 (file)
index 0000000..8daded9
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+exec_prefix_set=no
+
+usage="\
+Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]"
+
+if test $# -eq 0; then
+      echo "${usage}" 1>&2
+      exit 1
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo $prefix
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+    --version)
+      echo @PCRE_VERSION@
+      ;;
+    --cflags | --cflags-posix)
+      if test @includedir@ != /usr/include ; then
+        includes=-I@includedir@
+      fi
+      echo $includes
+      ;;
+    --libs-posix)
+      echo -L@libdir@ -lpcreposix -lpcre
+      ;;
+    --libs)
+      echo -L@libdir@ -lpcre
+      ;;
+    *)
+      echo "${usage}" 1>&2
+      exit 1
+      ;;
+  esac
+  shift
+done
diff --git a/pcre/pcre.def b/pcre/pcre.def
new file mode 100644 (file)
index 0000000..0e8cf3f
--- /dev/null
@@ -0,0 +1,19 @@
+EXPORTS
+
+pcre_malloc DATA
+pcre_free DATA
+
+pcre_compile
+pcre_copy_substring
+pcre_exec
+pcre_get_substring
+pcre_get_substring_list
+pcre_info
+pcre_maketables
+pcre_study
+pcre_version
+
+regcomp
+regexec
+regerror
+regfree
index e5a875a..d27ba85 100644 (file)
@@ -17,7 +17,7 @@ make changes to pcre.in. */
 /* Win32 uses DLL by default */
 
 #ifdef _WIN32
-# ifdef STATIC
+# ifdef STATIC_PCRE
 #  define PCRE_DL_IMPORT
 # else
 #  define PCRE_DL_IMPORT __declspec(dllimport)
index 1dffb02..d698f40 100644 (file)
@@ -17,7 +17,7 @@ make changes to pcre.in. */
 /* Win32 uses DLL by default */
 
 #ifdef _WIN32
-# ifdef STATIC
+# ifdef STATIC_PCRE
 #  define PCRE_DL_IMPORT
 # else
 #  define PCRE_DL_IMPORT __declspec(dllimport)
diff --git a/pcre/pcregrep.c b/pcre/pcregrep.c
new file mode 100644 (file)
index 0000000..e8c934e
--- /dev/null
@@ -0,0 +1,228 @@
+/*************************************************
+*               pcregrep program                 *
+*************************************************/
+
+/* This is a grep program that uses the PCRE regular expression library to do
+its pattern matching. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "config.h"
+#include "pcre.h"
+
+#define FALSE 0
+#define TRUE 1
+
+typedef int BOOL;
+
+
+
+/*************************************************
+*               Global variables                 *
+*************************************************/
+
+static pcre *pattern;
+static pcre_extra *hints;
+
+static BOOL count_only = FALSE;
+static BOOL filenames_only = FALSE;
+static BOOL invert = FALSE;
+static BOOL number = FALSE;
+static BOOL silent = FALSE;
+static BOOL whole_lines = FALSE;
+
+
+
+#if ! HAVE_STRERROR
+/*************************************************
+*     Provide strerror() for non-ANSI libraries  *
+*************************************************/
+
+/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror()
+in their libraries, but can provide the same facility by this simple
+alternative function. */
+
+extern int   sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(int n)
+{
+if (n < 0 || n >= sys_nerr) return "unknown error number";
+return sys_errlist[n];
+}
+#endif /* HAVE_STRERROR */
+
+
+
+/*************************************************
+*              Grep an individual file           *
+*************************************************/
+
+static int
+pcregrep(FILE *in, char *name)
+{
+int rc = 1;
+int linenumber = 0;
+int count = 0;
+int offsets[99];
+char buffer[BUFSIZ];
+
+while (fgets(buffer, sizeof(buffer), in) != NULL)
+  {
+  BOOL match;
+  int length = (int)strlen(buffer);
+  if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0;
+  linenumber++;
+
+  match = pcre_exec(pattern, hints, buffer, length, 0, 0, offsets, 99) >= 0;
+  if (match && whole_lines && offsets[1] != length) match = FALSE;
+
+  if (match != invert)
+    {
+    if (count_only) count++;
+
+    else if (filenames_only)
+      {
+      fprintf(stdout, "%s\n", (name == NULL)? "<stdin>" : name);
+      return 0;
+      }
+
+    else if (silent) return 0;
+
+    else
+      {
+      if (name != NULL) fprintf(stdout, "%s:", name);
+      if (number) fprintf(stdout, "%d:", linenumber);
+      fprintf(stdout, "%s\n", buffer);
+      }
+
+    rc = 0;
+    }
+  }
+
+if (count_only)
+  {
+  if (name != NULL) fprintf(stdout, "%s:", name);
+  fprintf(stdout, "%d\n", count);
+  }
+
+return rc;
+}
+
+
+
+
+/*************************************************
+*                Usage function                  *
+*************************************************/
+
+static int
+usage(int rc)
+{
+fprintf(stderr, "Usage: pcregrep [-Vchilnsvx] pattern [file] ...\n");
+return rc;
+}
+
+
+
+
+/*************************************************
+*                Main program                    *
+*************************************************/
+
+int
+main(int argc, char **argv)
+{
+int i;
+int rc = 1;
+int options = 0;
+int errptr;
+const char *error;
+BOOL filenames = TRUE;
+
+/* Process the options */
+
+for (i = 1; i < argc; i++)
+  {
+  char *s;
+  if (argv[i][0] != '-') break;
+  s = argv[i] + 1;
+  while (*s != 0)
+    {
+    switch (*s++)
+      {
+      case 'c': count_only = TRUE; break;
+      case 'h': filenames = FALSE; break;
+      case 'i': options |= PCRE_CASELESS; break;
+      case 'l': filenames_only = TRUE;
+      case 'n': number = TRUE; break;
+      case 's': silent = TRUE; break;
+      case 'v': invert = TRUE; break;
+      case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break;
+
+      case 'V':
+      fprintf(stderr, "PCRE version %s\n", pcre_version());
+      break;
+
+      default:
+      fprintf(stderr, "pcregrep: unknown option %c\n", s[-1]);
+      return usage(2);
+      }
+    }
+  }
+
+/* There must be at least a regexp argument */
+
+if (i >= argc) return usage(0);
+
+/* Compile the regular expression. */
+
+pattern = pcre_compile(argv[i++], options, &error, &errptr, NULL);
+if (pattern == NULL)
+  {
+  fprintf(stderr, "pcregrep: error in regex at offset %d: %s\n", errptr, error);
+  return 2;
+  }
+
+/* Study the regular expression, as we will be running it may times */
+
+hints = pcre_study(pattern, 0, &error);
+if (error != NULL)
+  {
+  fprintf(stderr, "pcregrep: error while studing regex: %s\n", error);
+  return 2;
+  }
+
+/* If there are no further arguments, do the business on stdin and exit */
+
+if (i >= argc) return pcregrep(stdin, NULL);
+
+/* Otherwise, work through the remaining arguments as files. If there is only
+one, don't give its name on the output. */
+
+if (i == argc - 1) filenames = FALSE;
+if (filenames_only) filenames = TRUE;
+
+for (; i < argc; i++)
+  {
+  FILE *in = fopen(argv[i], "r");
+  if (in == NULL)
+    {
+    fprintf(stderr, "%s: failed to open: %s\n", argv[i], strerror(errno));
+    rc = 2;
+    }
+  else
+    {
+    int frc = pcregrep(in, filenames? argv[i] : NULL);
+    if (frc == 0 && rc == 1) rc = 0;
+    fclose(in);
+    }
+  }
+
+return rc;
+}
+
+/* End */
index 6aeb882..519d2dd 100644 (file)
@@ -251,7 +251,7 @@ if (rc == 0) rc = nmatch;    /* All captured slots were filled in */
 if (rc >= 0)
   {
   size_t i;
-  for (i = 0; i < rc; i++)
+  for (i = 0; i < (size_t)rc; i++)
     {
     pmatch[i].rm_so = ovector[i*2];
     pmatch[i].rm_eo = ovector[i*2+1];
diff --git a/pcre/pcreposix.h b/pcre/pcreposix.h
new file mode 100644 (file)
index 0000000..7660acb
--- /dev/null
@@ -0,0 +1,88 @@
+/*************************************************
+*       Perl-Compatible Regular Expressions      *
+*************************************************/
+
+/* Copyright (c) 1997-2000 University of Cambridge */
+
+#ifndef _PCREPOSIX_H
+#define _PCREPOSIX_H
+
+/* This is the header for the POSIX wrapper interface to the PCRE Perl-
+Compatible Regular Expression library. It defines the things POSIX says should
+be there. I hope. */
+
+/* Have to include stdlib.h in order to ensure that size_t is defined. */
+
+#include <stdlib.h>
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options defined by POSIX. */
+
+#define REG_ICASE     0x01
+#define REG_NEWLINE   0x02
+#define REG_NOTBOL    0x04
+#define REG_NOTEOL    0x08
+
+/* These are not used by PCRE, but by defining them we make it easier
+to slot PCRE into existing programs that make POSIX calls. */
+
+#define REG_EXTENDED  0
+#define REG_NOSUB     0
+
+/* Error values. Not all these are relevant or used by the wrapper. */
+
+enum {
+  REG_ASSERT = 1,  /* internal error ? */
+  REG_BADBR,       /* invalid repeat counts in {} */
+  REG_BADPAT,      /* pattern error */
+  REG_BADRPT,      /* ? * + invalid */
+  REG_EBRACE,      /* unbalanced {} */
+  REG_EBRACK,      /* unbalanced [] */
+  REG_ECOLLATE,    /* collation error - not relevant */
+  REG_ECTYPE,      /* bad class */
+  REG_EESCAPE,     /* bad escape sequence */
+  REG_EMPTY,       /* empty expression */
+  REG_EPAREN,      /* unbalanced () */
+  REG_ERANGE,      /* bad range inside [] */
+  REG_ESIZE,       /* expression too big */
+  REG_ESPACE,      /* failed to get memory */
+  REG_ESUBREG,     /* bad back reference */
+  REG_INVARG,      /* bad argument */
+  REG_NOMATCH      /* match failed */
+};
+
+
+/* The structure representing a compiled regular expression. */
+
+typedef struct {
+  void *re_pcre;
+  size_t re_nsub;
+  size_t re_erroffset;
+} regex_t;
+
+/* The structure in which a captured offset is returned. */
+
+typedef int regoff_t;
+
+typedef struct {
+  regoff_t rm_so;
+  regoff_t rm_eo;
+} regmatch_t;
+
+/* The functions */
+
+extern int regcomp(regex_t *, const char *, int);
+extern int regexec(regex_t *, const char *, size_t, regmatch_t *, int);
+extern size_t regerror(int, const regex_t *, char *, size_t);
+extern void regfree(regex_t *);
+
+#ifdef __cplusplus
+}   /* extern "C" */
+#endif
+
+#endif /* End of pcreposix.h */
diff --git a/pcre/pcretest.c b/pcre/pcretest.c
new file mode 100644 (file)
index 0000000..ee5df5f
--- /dev/null
@@ -0,0 +1,1225 @@
+/*************************************************
+*             PCRE testing program               *
+*************************************************/
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <locale.h>
+
+/* Use the internal info for displaying the results of pcre_study(). */
+
+#include "internal.h"
+
+/* It is possible to compile this test program without including support for
+testing the POSIX interface, though this is not available via the standard
+Makefile. */
+
+#if !defined NOPOSIX
+#include "pcreposix.h"
+#endif
+
+#ifndef CLOCKS_PER_SEC
+#ifdef CLK_TCK
+#define CLOCKS_PER_SEC CLK_TCK
+#else
+#define CLOCKS_PER_SEC 100
+#endif
+#endif
+
+#define LOOPREPEAT 20000
+
+
+static FILE *outfile;
+static int log_store = 0;
+static size_t gotten_store;
+
+
+
+static int utf8_table1[] = {
+  0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff};
+
+static int utf8_table2[] = {
+  0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+
+static int utf8_table3[] = {
+  0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+
+
+/*************************************************
+*       Convert character value to UTF-8         *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x7fffffff
+and encodes it as a UTF-8 character in 0 to 6 bytes.
+
+Arguments:
+  cvalue     the character value
+  buffer     pointer to buffer for result - at least 6 bytes long
+
+Returns:     number of characters placed in the buffer
+             -1 if input character is negative
+             0 if input character is positive but too big (only when
+             int is longer than 32 bits)
+*/
+
+static int
+ord2utf8(int cvalue, unsigned char *buffer)
+{
+register int i, j;
+for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++)
+  if (cvalue <= utf8_table1[i]) break;
+if (i >= sizeof(utf8_table1)/sizeof(int)) return 0;
+if (cvalue < 0) return -1;
+*buffer++ = utf8_table2[i] | (cvalue & utf8_table3[i]);
+cvalue >>= 6 - i;
+for (j = 0; j < i; j++)
+  {
+  *buffer++ = 0x80 | (cvalue & 0x3f);
+  cvalue >>= 6;
+  }
+return i + 1;
+}
+
+
+/*************************************************
+*            Convert UTF-8 string to value       *
+*************************************************/
+
+/* This function takes one or more bytes that represents a UTF-8 character,
+and returns the value of the character.
+
+Argument:
+  buffer   a pointer to the byte vector
+  vptr     a pointer to an int to receive the value
+
+Returns:   >  0 => the number of bytes consumed
+           -6 to 0 => malformed UTF-8 character at offset = (-return)
+*/
+
+int
+utf82ord(unsigned char *buffer, int *vptr)
+{
+int c = *buffer++;
+int d = c;
+int i, j, s;
+
+for (i = -1; i < 6; i++)               /* i is number of additional bytes */
+  {
+  if ((d & 0x80) == 0) break;
+  d <<= 1;
+  }
+
+if (i == -1) { *vptr = c; return 1; }  /* ascii character */
+if (i == 0 || i == 6) return 0;        /* invalid UTF-8 */
+
+/* i now has a value in the range 1-5 */
+
+d = c & utf8_table3[i];
+s = 6 - i;
+
+for (j = 0; j < i; j++)
+  {
+  c = *buffer++;
+  if ((c & 0xc0) != 0x80) return -(j+1);
+  d |= (c & 0x3f) << s;
+  s += 6;
+  }
+
+/* Check that encoding was the correct unique one */
+
+for (j = 0; j < sizeof(utf8_table1)/sizeof(int); j++)
+  if (d <= utf8_table1[j]) break;
+if (j != i) return -(i+1);
+
+/* Valid value */
+
+*vptr = d;
+return i+1;
+}
+
+
+
+
+
+
+/* Debugging function to print the internal form of the regex. This is the same
+code as contained in pcre.c under the DEBUG macro. */
+
+static const char *OP_names[] = {
+  "End", "\\A", "\\B", "\\b", "\\D", "\\d",
+  "\\S", "\\s", "\\W", "\\w", "\\Z", "\\z",
+  "Opt", "^", "$", "Any", "chars", "not",
+  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
+  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
+  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",
+  "*", "*?", "+", "+?", "?", "??", "{", "{",
+  "class", "Ref", "Recurse",
+  "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not",
+  "AssertB", "AssertB not", "Reverse", "Once", "Cond", "Cref",
+  "Brazero", "Braminzero", "Bra"
+};
+
+
+static void print_internals(pcre *re)
+{
+unsigned char *code = ((real_pcre *)re)->code;
+
+fprintf(outfile, "------------------------------------------------------------------\n");
+
+for(;;)
+  {
+  int c;
+  int charlength;
+
+  fprintf(outfile, "%3d ", (int)(code - ((real_pcre *)re)->code));
+
+  if (*code >= OP_BRA)
+    {
+    fprintf(outfile, "%3d Bra %d", (code[1] << 8) + code[2], *code - OP_BRA);
+    code += 2;
+    }
+
+  else switch(*code)
+    {
+    case OP_END:
+    fprintf(outfile, "    %s\n", OP_names[*code]);
+    fprintf(outfile, "------------------------------------------------------------------\n");
+    return;
+
+    case OP_OPT:
+    fprintf(outfile, " %.2x %s", code[1], OP_names[*code]);
+    code++;
+    break;
+
+    case OP_COND:
+    fprintf(outfile, "%3d Cond", (code[1] << 8) + code[2]);
+    code += 2;
+    break;
+
+    case OP_CREF:
+    fprintf(outfile, " %.2d %s", code[1], OP_names[*code]);
+    code++;
+    break;
+
+    case OP_CHARS:
+    charlength = *(++code);
+    fprintf(outfile, "%3d ", charlength);
+    while (charlength-- > 0)
+      if (isprint(c = *(++code))) fprintf(outfile, "%c", c);
+        else fprintf(outfile, "\\x%02x", c);
+    break;
+
+    case OP_KETRMAX:
+    case OP_KETRMIN:
+    case OP_ALT:
+    case OP_KET:
+    case OP_ASSERT:
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK:
+    case OP_ASSERTBACK_NOT:
+    case OP_ONCE:
+    fprintf(outfile, "%3d %s", (code[1] << 8) + code[2], OP_names[*code]);
+    code += 2;
+    break;
+
+    case OP_REVERSE:
+    fprintf(outfile, "%3d %s", (code[1] << 8) + code[2], OP_names[*code]);
+    code += 2;
+    break;
+
+    case OP_STAR:
+    case OP_MINSTAR:
+    case OP_PLUS:
+    case OP_MINPLUS:
+    case OP_QUERY:
+    case OP_MINQUERY:
+    case OP_TYPESTAR:
+    case OP_TYPEMINSTAR:
+    case OP_TYPEPLUS:
+    case OP_TYPEMINPLUS:
+    case OP_TYPEQUERY:
+    case OP_TYPEMINQUERY:
+    if (*code >= OP_TYPESTAR)
+      fprintf(outfile, "    %s", OP_names[code[1]]);
+    else if (isprint(c = code[1])) fprintf(outfile, "    %c", c);
+      else fprintf(outfile, "    \\x%02x", c);
+    fprintf(outfile, "%s", OP_names[*code++]);
+    break;
+
+    case OP_EXACT:
+    case OP_UPTO:
+    case OP_MINUPTO:
+    if (isprint(c = code[3])) fprintf(outfile, "    %c{", c);
+      else fprintf(outfile, "    \\x%02x{", c);
+    if (*code != OP_EXACT) fprintf(outfile, ",");
+    fprintf(outfile, "%d}", (code[1] << 8) + code[2]);
+    if (*code == OP_MINUPTO) fprintf(outfile, "?");
+    code += 3;
+    break;
+
+    case OP_TYPEEXACT:
+    case OP_TYPEUPTO:
+    case OP_TYPEMINUPTO:
+    fprintf(outfile, "    %s{", OP_names[code[3]]);
+    if (*code != OP_TYPEEXACT) fprintf(outfile, "0,");
+    fprintf(outfile, "%d}", (code[1] << 8) + code[2]);
+    if (*code == OP_TYPEMINUPTO) fprintf(outfile, "?");
+    code += 3;
+    break;
+
+    case OP_NOT:
+    if (isprint(c = *(++code))) fprintf(outfile, "    [^%c]", c);
+      else fprintf(outfile, "    [^\\x%02x]", c);
+    break;
+
+    case OP_NOTSTAR:
+    case OP_NOTMINSTAR:
+    case OP_NOTPLUS:
+    case OP_NOTMINPLUS:
+    case OP_NOTQUERY:
+    case OP_NOTMINQUERY:
+    if (isprint(c = code[1])) fprintf(outfile, "    [^%c]", c);
+      else fprintf(outfile, "    [^\\x%02x]", c);
+    fprintf(outfile, "%s", OP_names[*code++]);
+    break;
+
+    case OP_NOTEXACT:
+    case OP_NOTUPTO:
+    case OP_NOTMINUPTO:
+    if (isprint(c = code[3])) fprintf(outfile, "    [^%c]{", c);
+      else fprintf(outfile, "    [^\\x%02x]{", c);
+    if (*code != OP_NOTEXACT) fprintf(outfile, ",");
+    fprintf(outfile, "%d}", (code[1] << 8) + code[2]);
+    if (*code == OP_NOTMINUPTO) fprintf(outfile, "?");
+    code += 3;
+    break;
+
+    case OP_REF:
+    fprintf(outfile, "    \\%d", *(++code));
+    code++;
+    goto CLASS_REF_REPEAT;
+
+    case OP_CLASS:
+      {
+      int i, min, max;
+      code++;
+      fprintf(outfile, "    [");
+
+      for (i = 0; i < 256; i++)
+        {
+        if ((code[i/8] & (1 << (i&7))) != 0)
+          {
+          int j;
+          for (j = i+1; j < 256; j++)
+            if ((code[j/8] & (1 << (j&7))) == 0) break;
+          if (i == '-' || i == ']') fprintf(outfile, "\\");
+          if (isprint(i)) fprintf(outfile, "%c", i); else fprintf(outfile, "\\x%02x", i);
+          if (--j > i)
+            {
+            fprintf(outfile, "-");
+            if (j == '-' || j == ']') fprintf(outfile, "\\");
+            if (isprint(j)) fprintf(outfile, "%c", j); else fprintf(outfile, "\\x%02x", j);
+            }
+          i = j;
+          }
+        }
+      fprintf(outfile, "]");
+      code += 32;
+
+      CLASS_REF_REPEAT:
+
+      switch(*code)
+        {
+        case OP_CRSTAR:
+        case OP_CRMINSTAR:
+        case OP_CRPLUS:
+        case OP_CRMINPLUS:
+        case OP_CRQUERY:
+        case OP_CRMINQUERY:
+        fprintf(outfile, "%s", OP_names[*code]);
+        break;
+
+        case OP_CRRANGE:
+        case OP_CRMINRANGE:
+        min = (code[1] << 8) + code[2];
+        max = (code[3] << 8) + code[4];
+        if (max == 0) fprintf(outfile, "{%d,}", min);
+        else fprintf(outfile, "{%d,%d}", min, max);
+        if (*code == OP_CRMINRANGE) fprintf(outfile, "?");
+        code += 4;
+        break;
+
+        default:
+        code--;
+        }
+      }
+    break;
+
+    /* Anything else is just a one-node item */
+
+    default:
+    fprintf(outfile, "    %s", OP_names[*code]);
+    break;
+    }
+
+  code++;
+  fprintf(outfile, "\n");
+  }
+}
+
+
+
+/* Character string printing function. A "normal" and a UTF-8 version. */
+
+static void pchars(unsigned char *p, int length, int utf8)
+{
+int c;
+while (length-- > 0)
+  {
+  if (utf8)
+    {
+    int rc = utf82ord(p, &c);
+    if (rc > 0)
+      {
+      length -= rc - 1;
+      p += rc;
+      if (c < 256 && isprint(c)) fprintf(outfile, "%c", c);
+        else fprintf(outfile, "\\x{%02x}", c);
+      continue;
+      }
+    }
+
+   /* Not UTF-8, or malformed UTF-8  */
+
+  if (isprint(c = *(p++))) fprintf(outfile, "%c", c);
+    else fprintf(outfile, "\\x%02x", c);
+  }
+}
+
+
+
+/* Alternative malloc function, to test functionality and show the size of the
+compiled re. */
+
+static void *new_malloc(size_t size)
+{
+gotten_store = size;
+if (log_store)
+  fprintf(outfile, "Memory allocation (code space): %d\n",
+    (int)((int)size - offsetof(real_pcre, code[0])));
+return malloc(size);
+}
+
+
+
+
+/* Get one piece of information from the pcre_fullinfo() function */
+
+static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)
+{
+int rc;
+if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)
+  fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);
+}
+
+
+
+
+/* Read lines from named file or stdin and write to named file or stdout; lines
+consist of a regular expression, in delimiters and optionally followed by
+options, followed by a set of test data, terminated by an empty line. */
+
+int main(int argc, char **argv)
+{
+FILE *infile = stdin;
+int options = 0;
+int study_options = 0;
+int op = 1;
+int timeit = 0;
+int showinfo = 0;
+int showstore = 0;
+int posix = 0;
+int debug = 0;
+int done = 0;
+unsigned char buffer[30000];
+unsigned char dbuffer[1024];
+
+/* Static so that new_malloc can use it. */
+
+outfile = stdout;
+
+/* Scan options */
+
+while (argc > 1 && argv[op][0] == '-')
+  {
+  if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0)
+    showstore = 1;
+  else if (strcmp(argv[op], "-t") == 0) timeit = 1;
+  else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
+  else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
+  else if (strcmp(argv[op], "-p") == 0) posix = 1;
+  else
+    {
+    printf("*** Unknown option %s\n", argv[op]);
+    printf("Usage: pcretest [-d] [-i] [-p] [-s] [-t] [<input> [<output>]]\n");
+    printf("  -d   debug: show compiled code; implies -i\n"
+           "  -i   show information about compiled pattern\n"
+           "  -p   use POSIX interface\n"
+           "  -s   output store information\n"
+           "  -t   time compilation and execution\n");
+    return 1;
+    }
+  op++;
+  argc--;
+  }
+
+/* Sort out the input and output files */
+
+if (argc > 1)
+  {
+  infile = fopen(argv[op], "r");
+  if (infile == NULL)
+    {
+    printf("** Failed to open %s\n", argv[op]);
+    return 1;
+    }
+  }
+
+if (argc > 2)
+  {
+  outfile = fopen(argv[op+1], "w");
+  if (outfile == NULL)
+    {
+    printf("** Failed to open %s\n", argv[op+1]);
+    return 1;
+    }
+  }
+
+/* Set alternative malloc function */
+
+pcre_malloc = new_malloc;
+
+/* Heading line, then prompt for first regex if stdin */
+
+fprintf(outfile, "PCRE version %s\n\n", pcre_version());
+
+/* Main loop */
+
+while (!done)
+  {
+  pcre *re = NULL;
+  pcre_extra *extra = NULL;
+
+#if !defined NOPOSIX  /* There are still compilers that require no indent */
+  regex_t preg;
+  int do_posix = 0;
+#endif
+
+  const char *error;
+  unsigned char *p, *pp, *ppp;
+  unsigned const char *tables = NULL;
+  int do_study = 0;
+  int do_debug = debug;
+  int do_G = 0;
+  int do_g = 0;
+  int do_showinfo = showinfo;
+  int do_showrest = 0;
+  int utf8 = 0;
+  int erroroffset, len, delimiter;
+
+  if (infile == stdin) printf("  re> ");
+  if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) break;
+  if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
+
+  p = buffer;
+  while (isspace(*p)) p++;
+  if (*p == 0) continue;
+
+  /* Get the delimiter and seek the end of the pattern; if is isn't
+  complete, read more. */
+
+  delimiter = *p++;
+
+  if (isalnum(delimiter) || delimiter == '\\')
+    {
+    fprintf(outfile, "** Delimiter must not be alphameric or \\\n");
+    goto SKIP_DATA;
+    }
+
+  pp = p;
+
+  for(;;)
+    {
+    while (*pp != 0)
+      {
+      if (*pp == '\\' && pp[1] != 0) pp++;
+        else if (*pp == delimiter) break;
+      pp++;
+      }
+    if (*pp != 0) break;
+
+    len = sizeof(buffer) - (pp - buffer);
+    if (len < 256)
+      {
+      fprintf(outfile, "** Expression too long - missing delimiter?\n");
+      goto SKIP_DATA;
+      }
+
+    if (infile == stdin) printf("    > ");
+    if (fgets((char *)pp, len, infile) == NULL)
+      {
+      fprintf(outfile, "** Unexpected EOF\n");
+      done = 1;
+      goto CONTINUE;
+      }
+    if (infile != stdin) fprintf(outfile, "%s", (char *)pp);
+    }
+
+  /* If the first character after the delimiter is backslash, make
+  the pattern end with backslash. This is purely to provide a way
+  of testing for the error message when a pattern ends with backslash. */
+
+  if (pp[1] == '\\') *pp++ = '\\';
+
+  /* Terminate the pattern at the delimiter */
+
+  *pp++ = 0;
+
+  /* Look for options after final delimiter */
+
+  options = 0;
+  study_options = 0;
+  log_store = showstore;  /* default from command line */
+
+  while (*pp != 0)
+    {
+    switch (*pp++)
+      {
+      case 'g': do_g = 1; break;
+      case 'i': options |= PCRE_CASELESS; break;
+      case 'm': options |= PCRE_MULTILINE; break;
+      case 's': options |= PCRE_DOTALL; break;
+      case 'x': options |= PCRE_EXTENDED; break;
+
+      case '+': do_showrest = 1; break;
+      case 'A': options |= PCRE_ANCHORED; break;
+      case 'D': do_debug = do_showinfo = 1; break;
+      case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
+      case 'G': do_G = 1; break;
+      case 'I': do_showinfo = 1; break;
+      case 'M': log_store = 1; break;
+
+#if !defined NOPOSIX
+      case 'P': do_posix = 1; break;
+#endif
+
+      case 'S': do_study = 1; break;
+      case 'U': options |= PCRE_UNGREEDY; break;
+      case 'X': options |= PCRE_EXTRA; break;
+      case '8': options |= PCRE_UTF8; utf8 = 1; break;
+
+      case 'L':
+      ppp = pp;
+      while (*ppp != '\n' && *ppp != ' ') ppp++;
+      *ppp = 0;
+      if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
+        {
+        fprintf(outfile, "** Failed to set locale \"%s\"\n", pp);
+        goto SKIP_DATA;
+        }
+      tables = pcre_maketables();
+      pp = ppp;
+      break;
+
+      case '\n': case ' ': break;
+      default:
+      fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);
+      goto SKIP_DATA;
+      }
+    }
+
+  /* Handle compiling via the POSIX interface, which doesn't support the
+  timing, showing, or debugging options, nor the ability to pass over
+  local character tables. */
+
+#if !defined NOPOSIX
+  if (posix || do_posix)
+    {
+    int rc;
+    int cflags = 0;
+    if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;
+    if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;
+    rc = regcomp(&preg, (char *)p, cflags);
+
+    /* Compilation failed; go back for another re, skipping to blank line
+    if non-interactive. */
+
+    if (rc != 0)
+      {
+      (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer));
+      fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);
+      goto SKIP_DATA;
+      }
+    }
+
+  /* Handle compiling via the native interface */
+
+  else
+#endif  /* !defined NOPOSIX */
+
+    {
+    if (timeit)
+      {
+      register int i;
+      clock_t time_taken;
+      clock_t start_time = clock();
+      for (i = 0; i < LOOPREPEAT; i++)
+        {
+        re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
+        if (re != NULL) free(re);
+        }
+      time_taken = clock() - start_time;
+      fprintf(outfile, "Compile time %.3f milliseconds\n",
+        ((double)time_taken * 1000.0) /
+        ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
+      }
+
+    re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
+
+    /* Compilation failed; go back for another re, skipping to blank line
+    if non-interactive. */
+
+    if (re == NULL)
+      {
+      fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset);
+      SKIP_DATA:
+      if (infile != stdin)
+        {
+        for (;;)
+          {
+          if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
+            {
+            done = 1;
+            goto CONTINUE;
+            }
+          len = (int)strlen((char *)buffer);
+          while (len > 0 && isspace(buffer[len-1])) len--;
+          if (len == 0) break;
+          }
+        fprintf(outfile, "\n");
+        }
+      goto CONTINUE;
+      }
+
+    /* Compilation succeeded; print data if required. There are now two
+    info-returning functions. The old one has a limited interface and
+    returns only limited data. Check that it agrees with the newer one. */
+
+    if (do_showinfo)
+      {
+      int old_first_char, old_options, old_count;
+      int count, backrefmax, first_char, need_char;
+      size_t size;
+
+      if (do_debug) print_internals(re);
+
+      new_info(re, NULL, PCRE_INFO_OPTIONS, &options);
+      new_info(re, NULL, PCRE_INFO_SIZE, &size);
+      new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
+      new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);
+      new_info(re, NULL, PCRE_INFO_FIRSTCHAR, &first_char);
+      new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char);
+
+      old_count = pcre_info(re, &old_options, &old_first_char);
+      if (count < 0) fprintf(outfile,
+        "Error %d from pcre_info()\n", count);
+      else
+        {
+        if (old_count != count) fprintf(outfile,
+          "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,
+            old_count);
+
+        if (old_first_char != first_char) fprintf(outfile,
+          "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",
+            first_char, old_first_char);
+
+        if (old_options != options) fprintf(outfile,
+          "Options disagreement: pcre_fullinfo=%d pcre_info=%d\n", options,
+            old_options);
+        }
+
+      if (size != gotten_store) fprintf(outfile,
+        "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n",
+        size, gotten_store);
+
+      fprintf(outfile, "Capturing subpattern count = %d\n", count);
+      if (backrefmax > 0)
+        fprintf(outfile, "Max back reference = %d\n", backrefmax);
+      if (options == 0) fprintf(outfile, "No options\n");
+        else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s\n",
+          ((options & PCRE_ANCHORED) != 0)? " anchored" : "",
+          ((options & PCRE_CASELESS) != 0)? " caseless" : "",
+          ((options & PCRE_EXTENDED) != 0)? " extended" : "",
+          ((options & PCRE_MULTILINE) != 0)? " multiline" : "",
+          ((options & PCRE_DOTALL) != 0)? " dotall" : "",
+          ((options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
+          ((options & PCRE_EXTRA) != 0)? " extra" : "",
+          ((options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
+          ((options & PCRE_UTF8) != 0)? " utf8" : "");
+
+      if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0)
+        fprintf(outfile, "Case state changes\n");
+
+      if (first_char == -1)
+        {
+        fprintf(outfile, "First char at start or follows \\n\n");
+        }
+      else if (first_char < 0)
+        {
+        fprintf(outfile, "No first char\n");
+        }
+      else
+        {
+        if (isprint(first_char))
+          fprintf(outfile, "First char = \'%c\'\n", first_char);
+        else
+          fprintf(outfile, "First char = %d\n", first_char);
+        }
+
+      if (need_char < 0)
+        {
+        fprintf(outfile, "No need char\n");
+        }
+      else
+        {
+        if (isprint(need_char))
+          fprintf(outfile, "Need char = \'%c\'\n", need_char);
+        else
+          fprintf(outfile, "Need char = %d\n", need_char);
+        }
+      }
+
+    /* If /S was present, study the regexp to generate additional info to
+    help with the matching. */
+
+    if (do_study)
+      {
+      if (timeit)
+        {
+        register int i;
+        clock_t time_taken;
+        clock_t start_time = clock();
+        for (i = 0; i < LOOPREPEAT; i++)
+          extra = pcre_study(re, study_options, &error);
+        time_taken = clock() - start_time;
+        if (extra != NULL) free(extra);
+        fprintf(outfile, "  Study time %.3f milliseconds\n",
+          ((double)time_taken * 1000.0)/
+          ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
+        }
+
+      extra = pcre_study(re, study_options, &error);
+      if (error != NULL)
+        fprintf(outfile, "Failed to study: %s\n", error);
+      else if (extra == NULL)
+        fprintf(outfile, "Study returned NULL\n");
+
+      else if (do_showinfo)
+        {
+        uschar *start_bits = NULL;
+        new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
+        if (start_bits == NULL)
+          fprintf(outfile, "No starting character set\n");
+        else
+          {
+          int i;
+          int c = 24;
+          fprintf(outfile, "Starting character set: ");
+          for (i = 0; i < 256; i++)
+            {
+            if ((start_bits[i/8] & (1<<(i%8))) != 0)
+              {
+              if (c > 75)
+                {
+                fprintf(outfile, "\n  ");
+                c = 2;
+                }
+              if (isprint(i) && i != ' ')
+                {
+                fprintf(outfile, "%c ", i);
+                c += 2;
+                }
+              else
+                {
+                fprintf(outfile, "\\x%02x ", i);
+                c += 5;
+                }
+              }
+            }
+          fprintf(outfile, "\n");
+          }
+        }
+      }
+    }
+
+  /* Read data lines and test them */
+
+  for (;;)
+    {
+    unsigned char *q;
+    unsigned char *bptr = dbuffer;
+    int count, c;
+    int copystrings = 0;
+    int getstrings = 0;
+    int getlist = 0;
+    int gmatched = 0;
+    int start_offset = 0;
+    int g_notempty = 0;
+    int offsets[45];
+    int size_offsets = sizeof(offsets)/sizeof(int);
+
+    options = 0;
+
+    if (infile == stdin) printf("data> ");
+    if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
+      {
+      done = 1;
+      goto CONTINUE;
+      }
+    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
+
+    len = (int)strlen((char *)buffer);
+    while (len > 0 && isspace(buffer[len-1])) len--;
+    buffer[len] = 0;
+    if (len == 0) break;
+
+    p = buffer;
+    while (isspace(*p)) p++;
+
+    q = dbuffer;
+    while ((c = *p++) != 0)
+      {
+      int i = 0;
+      int n = 0;
+      if (c == '\\') switch ((c = *p++))
+        {
+        case 'a': c =    7; break;
+        case 'b': c = '\b'; break;
+        case 'e': c =   27; break;
+        case 'f': c = '\f'; break;
+        case 'n': c = '\n'; break;
+        case 'r': c = '\r'; break;
+        case 't': c = '\t'; break;
+        case 'v': c = '\v'; break;
+
+        case '0': case '1': case '2': case '3':
+        case '4': case '5': case '6': case '7':
+        c -= '0';
+        while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
+          c = c * 8 + *p++ - '0';
+        break;
+
+        case 'x':
+
+        /* Handle \x{..} specially - new Perl thing for utf8 */
+
+        if (*p == '{')
+          {
+          unsigned char *pt = p;
+          c = 0;
+          while (isxdigit(*(++pt)))
+            c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W');
+          if (*pt == '}')
+            {
+            unsigned char buffer[8];
+            int ii, utn;
+            utn = ord2utf8(c, buffer);
+            for (ii = 0; ii < utn - 1; ii++) *q++ = buffer[ii];
+            c = buffer[ii];   /* Last byte */
+            p = pt + 1;
+            break;
+            }
+          /* Not correct form; fall through */
+          }
+
+        /* Ordinary \x */
+
+        c = 0;
+        while (i++ < 2 && isxdigit(*p))
+          {
+          c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');
+          p++;
+          }
+        break;
+
+        case 0:   /* Allows for an empty line */
+        p--;
+        continue;
+
+        case 'A':  /* Option setting */
+        options |= PCRE_ANCHORED;
+        continue;
+
+        case 'B':
+        options |= PCRE_NOTBOL;
+        continue;
+
+        case 'C':
+        while(isdigit(*p)) n = n * 10 + *p++ - '0';
+        copystrings |= 1 << n;
+        continue;
+
+        case 'G':
+        while(isdigit(*p)) n = n * 10 + *p++ - '0';
+        getstrings |= 1 << n;
+        continue;
+
+        case 'L':
+        getlist = 1;
+        continue;
+
+        case 'N':
+        options |= PCRE_NOTEMPTY;
+        continue;
+
+        case 'O':
+        while(isdigit(*p)) n = n * 10 + *p++ - '0';
+        if (n <= (int)(sizeof(offsets)/sizeof(int))) size_offsets = n;
+        continue;
+
+        case 'Z':
+        options |= PCRE_NOTEOL;
+        continue;
+        }
+      *q++ = c;
+      }
+    *q = 0;
+    len = q - dbuffer;
+
+    /* Handle matching via the POSIX interface, which does not
+    support timing. */
+
+#if !defined NOPOSIX
+    if (posix || do_posix)
+      {
+      int rc;
+      int eflags = 0;
+      regmatch_t pmatch[sizeof(offsets)/sizeof(int)];
+      if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
+      if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;
+
+      rc = regexec(&preg, (const char *)bptr, size_offsets, pmatch, eflags);
+
+      if (rc != 0)
+        {
+        (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer));
+        fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);
+        }
+      else
+        {
+        size_t i;
+        for (i = 0; i < size_offsets; i++)
+          {
+          if (pmatch[i].rm_so >= 0)
+            {
+            fprintf(outfile, "%2d: ", (int)i);
+            pchars(dbuffer + pmatch[i].rm_so,
+              pmatch[i].rm_eo - pmatch[i].rm_so, utf8);
+            fprintf(outfile, "\n");
+            if (i == 0 && do_showrest)
+              {
+              fprintf(outfile, " 0+ ");
+              pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, utf8);
+              fprintf(outfile, "\n");
+              }
+            }
+          }
+        }
+      }
+
+    /* Handle matching via the native interface - repeats for /g and /G */
+
+    else
+#endif  /* !defined NOPOSIX */
+
+    for (;; gmatched++)    /* Loop for /g or /G */
+      {
+      if (timeit)
+        {
+        register int i;
+        clock_t time_taken;
+        clock_t start_time = clock();
+        for (i = 0; i < LOOPREPEAT; i++)
+          count = pcre_exec(re, extra, (char *)bptr, len,
+            start_offset, options | g_notempty, offsets, size_offsets);
+        time_taken = clock() - start_time;
+        fprintf(outfile, "Execute time %.3f milliseconds\n",
+          ((double)time_taken * 1000.0)/
+          ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
+        }
+
+      count = pcre_exec(re, extra, (char *)bptr, len,
+        start_offset, options | g_notempty, offsets, size_offsets);
+
+      if (count == 0)
+        {
+        fprintf(outfile, "Matched, but too many substrings\n");
+        count = size_offsets/3;
+        }
+
+      /* Matched */
+
+      if (count >= 0)
+        {
+        int i;
+        for (i = 0; i < count * 2; i += 2)
+          {
+          if (offsets[i] < 0)
+            fprintf(outfile, "%2d: <unset>\n", i/2);
+          else
+            {
+            fprintf(outfile, "%2d: ", i/2);
+            pchars(bptr + offsets[i], offsets[i+1] - offsets[i], utf8);
+            fprintf(outfile, "\n");
+            if (i == 0)
+              {
+              if (do_showrest)
+                {
+                fprintf(outfile, " 0+ ");
+                pchars(bptr + offsets[i+1], len - offsets[i+1], utf8);
+                fprintf(outfile, "\n");
+                }
+              }
+            }
+          }
+
+        for (i = 0; i < 32; i++)
+          {
+          if ((copystrings & (1 << i)) != 0)
+            {
+            char copybuffer[16];
+            int rc = pcre_copy_substring((char *)bptr, offsets, count,
+              i, copybuffer, sizeof(copybuffer));
+            if (rc < 0)
+              fprintf(outfile, "copy substring %d failed %d\n", i, rc);
+            else
+              fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc);
+            }
+          }
+
+        for (i = 0; i < 32; i++)
+          {
+          if ((getstrings & (1 << i)) != 0)
+            {
+            const char *substring;
+            int rc = pcre_get_substring((char *)bptr, offsets, count,
+              i, &substring);
+            if (rc < 0)
+              fprintf(outfile, "get substring %d failed %d\n", i, rc);
+            else
+              {
+              fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);
+              /* free((void *)substring); */
+              pcre_free_substring(substring);
+              }
+            }
+          }
+
+        if (getlist)
+          {
+          const char **stringlist;
+          int rc = pcre_get_substring_list((char *)bptr, offsets, count,
+            &stringlist);
+          if (rc < 0)
+            fprintf(outfile, "get substring list failed %d\n", rc);
+          else
+            {
+            for (i = 0; i < count; i++)
+              fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
+            if (stringlist[i] != NULL)
+              fprintf(outfile, "string list not terminated by NULL\n");
+            /* free((void *)stringlist); */
+            pcre_free_substring_list(stringlist);
+            }
+          }
+        }
+
+      /* Failed to match. If this is a /g or /G loop and we previously set
+      g_notempty after a null match, this is not necessarily the end.
+      We want to advance the start offset, and continue. Fudge the offset
+      values to achieve this. We won't be at the end of the string - that
+      was checked before setting g_notempty. */
+
+      else
+        {
+        if (g_notempty != 0)
+          {
+          offsets[0] = start_offset;
+          offsets[1] = start_offset + 1;
+          }
+        else
+          {
+          if (gmatched == 0)   /* Error if no previous matches */
+            {
+            if (count == -1) fprintf(outfile, "No match\n");
+              else fprintf(outfile, "Error %d\n", count);
+            }
+          break;  /* Out of the /g loop */
+          }
+        }
+
+      /* If not /g or /G we are done */
+
+      if (!do_g && !do_G) break;
+
+      /* If we have matched an empty string, first check to see if we are at
+      the end of the subject. If so, the /g loop is over. Otherwise, mimic
+      what Perl's /g options does. This turns out to be rather cunning. First
+      we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the
+      same point. If this fails (picked up above) we advance to the next
+      character. */
+
+      g_notempty = 0;
+      if (offsets[0] == offsets[1])
+        {
+        if (offsets[0] == len) break;
+        g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;
+        }
+
+      /* For /g, update the start offset, leaving the rest alone */
+
+      if (do_g) start_offset = offsets[1];
+
+      /* For /G, update the pointer and length */
+
+      else
+        {
+        bptr += offsets[1];
+        len -= offsets[1];
+        }
+      }  /* End of loop for /g and /G */
+    }    /* End of loop for data lines */
+
+  CONTINUE:
+
+#if !defined NOPOSIX
+  if (posix || do_posix) regfree(&preg);
+#endif
+
+  if (re != NULL) free(re);
+  if (extra != NULL) free(extra);
+  if (tables != NULL)
+    {
+    free((void *)tables);
+    setlocale(LC_CTYPE, "C");
+    }
+  }
+
+fprintf(outfile, "\n");
+return 0;
+}
+
+/* End */
diff --git a/pcre/study.c b/pcre/study.c
new file mode 100644 (file)
index 0000000..676db94
--- /dev/null
@@ -0,0 +1,397 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/*
+This is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language. See
+the file Tech.Notes for some information on the internals.
+
+Written by: Philip Hazel <ph10@cam.ac.uk>
+
+           Copyright (c) 1997-2000 University of Cambridge
+
+-----------------------------------------------------------------------------
+Permission is granted to anyone to use this software for any purpose on any
+computer system, and to redistribute it freely, subject to the following
+restrictions:
+
+1. This software is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+4. If PCRE is embedded in any software that is released under the GNU
+   General Purpose Licence (GPL), then the terms of that licence shall
+   supersede any condition above with which it is incompatible.
+-----------------------------------------------------------------------------
+*/
+
+
+/* Include the internals header, which itself includes Standard C headers plus
+the external pcre header. */
+
+#include "internal.h"
+
+
+
+/*************************************************
+*      Set a bit and maybe its alternate case    *
+*************************************************/
+
+/* Given a character, set its bit in the table, and also the bit for the other
+version of a letter if we are caseless.
+
+Arguments:
+  start_bits    points to the bit map
+  c             is the character
+  caseless      the caseless flag
+  cd            the block with char table pointers
+
+Returns:        nothing
+*/
+
+static void
+set_bit(uschar *start_bits, int c, BOOL caseless, compile_data *cd)
+{
+start_bits[c/8] |= (1 << (c&7));
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
+  start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
+}
+
+
+
+/*************************************************
+*          Create bitmap of starting chars       *
+*************************************************/
+
+/* This function scans a compiled unanchored expression and attempts to build a
+bitmap of the set of initial characters. If it can't, it returns FALSE. As time
+goes by, we may be able to get more clever at doing this.
+
+Arguments:
+  code         points to an expression
+  start_bits   points to a 32-byte table, initialized to 0
+  caseless     the current state of the caseless flag
+  cd           the block with char table pointers
+
+Returns:       TRUE if table built, FALSE otherwise
+*/
+
+static BOOL
+set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
+  compile_data *cd)
+{
+register int c;
+
+/* This next statement and the later reference to dummy are here in order to
+trick the optimizer of the IBM C compiler for OS/2 into generating correct
+code. Apparently IBM isn't going to fix the problem, and we would rather not
+disable optimization (in this module it actually makes a big difference, and
+the pcre module can use all the optimization it can get). */
+
+volatile int dummy;
+
+do
+  {
+  const uschar *tcode = code + 3;
+  BOOL try_next = TRUE;
+
+  while (try_next)
+    {
+    try_next = FALSE;
+
+    /* If a branch starts with a bracket or a positive lookahead assertion,
+    recurse to set bits from within them. That's all for this branch. */
+
+    if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT)
+      {
+      if (!set_start_bits(tcode, start_bits, caseless, cd))
+        return FALSE;
+      }
+
+    else switch(*tcode)
+      {
+      default:
+      return FALSE;
+
+      /* Skip over lookbehind and negative lookahead assertions */
+
+      case OP_ASSERT_NOT:
+      case OP_ASSERTBACK:
+      case OP_ASSERTBACK_NOT:
+      try_next = TRUE;
+      do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT);
+      tcode += 3;
+      break;
+
+      /* Skip over an option setting, changing the caseless flag */
+
+      case OP_OPT:
+      caseless = (tcode[1] & PCRE_CASELESS) != 0;
+      tcode += 2;
+      try_next = TRUE;
+      break;
+
+      /* BRAZERO does the bracket, but carries on. */
+
+      case OP_BRAZERO:
+      case OP_BRAMINZERO:
+      if (!set_start_bits(++tcode, start_bits, caseless, cd))
+        return FALSE;
+      dummy = 1;
+      do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT);
+      tcode += 3;
+      try_next = TRUE;
+      break;
+
+      /* Single-char * or ? sets the bit and tries the next item */
+
+      case OP_STAR:
+      case OP_MINSTAR:
+      case OP_QUERY:
+      case OP_MINQUERY:
+      set_bit(start_bits, tcode[1], caseless, cd);
+      tcode += 2;
+      try_next = TRUE;
+      break;
+
+      /* Single-char upto sets the bit and tries the next */
+
+      case OP_UPTO:
+      case OP_MINUPTO:
+      set_bit(start_bits, tcode[3], caseless, cd);
+      tcode += 4;
+      try_next = TRUE;
+      break;
+
+      /* At least one single char sets the bit and stops */
+
+      case OP_EXACT:       /* Fall through */
+      tcode++;
+
+      case OP_CHARS:       /* Fall through */
+      tcode++;
+
+      case OP_PLUS:
+      case OP_MINPLUS:
+      set_bit(start_bits, tcode[1], caseless, cd);
+      break;
+
+      /* Single character type sets the bits and stops */
+
+      case OP_NOT_DIGIT:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= ~cd->cbits[c+cbit_digit];
+      break;
+
+      case OP_DIGIT:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= cd->cbits[c+cbit_digit];
+      break;
+
+      case OP_NOT_WHITESPACE:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= ~cd->cbits[c+cbit_space];
+      break;
+
+      case OP_WHITESPACE:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= cd->cbits[c+cbit_space];
+      break;
+
+      case OP_NOT_WORDCHAR:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= ~cd->cbits[c+cbit_word];
+      break;
+
+      case OP_WORDCHAR:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= cd->cbits[c+cbit_word];
+      break;
+
+      /* One or more character type fudges the pointer and restarts, knowing
+      it will hit a single character type and stop there. */
+
+      case OP_TYPEPLUS:
+      case OP_TYPEMINPLUS:
+      tcode++;
+      try_next = TRUE;
+      break;
+
+      case OP_TYPEEXACT:
+      tcode += 3;
+      try_next = TRUE;
+      break;
+
+      /* Zero or more repeats of character types set the bits and then
+      try again. */
+
+      case OP_TYPEUPTO:
+      case OP_TYPEMINUPTO:
+      tcode += 2;               /* Fall through */
+
+      case OP_TYPESTAR:
+      case OP_TYPEMINSTAR:
+      case OP_TYPEQUERY:
+      case OP_TYPEMINQUERY:
+      switch(tcode[1])
+        {
+        case OP_NOT_DIGIT:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= ~cd->cbits[c+cbit_digit];
+        break;
+
+        case OP_DIGIT:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= cd->cbits[c+cbit_digit];
+        break;
+
+        case OP_NOT_WHITESPACE:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= ~cd->cbits[c+cbit_space];
+        break;
+
+        case OP_WHITESPACE:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= cd->cbits[c+cbit_space];
+        break;
+
+        case OP_NOT_WORDCHAR:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= ~cd->cbits[c+cbit_word];
+        break;
+
+        case OP_WORDCHAR:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= cd->cbits[c+cbit_word];
+        break;
+        }
+
+      tcode += 2;
+      try_next = TRUE;
+      break;
+
+      /* Character class: set the bits and either carry on or not,
+      according to the repeat count. */
+
+      case OP_CLASS:
+        {
+        tcode++;
+        for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
+        tcode += 32;
+        switch (*tcode)
+          {
+          case OP_CRSTAR:
+          case OP_CRMINSTAR:
+          case OP_CRQUERY:
+          case OP_CRMINQUERY:
+          tcode++;
+          try_next = TRUE;
+          break;
+
+          case OP_CRRANGE:
+          case OP_CRMINRANGE:
+          if (((tcode[1] << 8) + tcode[2]) == 0)
+            {
+            tcode += 5;
+            try_next = TRUE;
+            }
+          break;
+          }
+        }
+      break; /* End of class handling */
+
+      }      /* End of switch */
+    }        /* End of try_next loop */
+
+  code += (code[1] << 8) + code[2];   /* Advance to next branch */
+  }
+while (*code == OP_ALT);
+return TRUE;
+}
+
+
+
+/*************************************************
+*          Study a compiled expression           *
+*************************************************/
+
+/* This function is handed a compiled expression that it must study to produce
+information that will speed up the matching. It returns a pcre_extra block
+which then gets handed back to pcre_exec().
+
+Arguments:
+  re        points to the compiled expression
+  options   contains option bits
+  errorptr  points to where to place error messages;
+            set NULL unless error
+
+Returns:    pointer to a pcre_extra block,
+            NULL on error or if no optimization possible
+*/
+
+pcre_extra *
+pcre_study(const pcre *external_re, int options, const char **errorptr)
+{
+uschar start_bits[32];
+real_pcre_extra *extra;
+const real_pcre *re = (const real_pcre *)external_re;
+compile_data compile_block;
+
+*errorptr = NULL;
+
+if (re == NULL || re->magic_number != MAGIC_NUMBER)
+  {
+  *errorptr = "argument is not a compiled regular expression";
+  return NULL;
+  }
+
+if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
+  {
+  *errorptr = "unknown or incorrect option bit(s) set";
+  return NULL;
+  }
+
+/* For an anchored pattern, or an unchored pattern that has a first char, or a
+multiline pattern that matches only at "line starts", no further processing at
+present. */
+
+if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
+  return NULL;
+
+/* Set the character tables in the block which is passed around */
+
+compile_block.lcc = re->tables + lcc_offset;
+compile_block.fcc = re->tables + fcc_offset;
+compile_block.cbits = re->tables + cbits_offset;
+compile_block.ctypes = re->tables + ctypes_offset;
+
+/* See if we can find a fixed set of initial characters for the pattern. */
+
+memset(start_bits, 0, 32 * sizeof(uschar));
+if (!set_start_bits(re->code, start_bits, (re->options & PCRE_CASELESS) != 0,
+  &compile_block)) return NULL;
+
+/* Get an "extra" block and put the information therein. */
+
+extra = (real_pcre_extra *)(pcre_malloc)(sizeof(real_pcre_extra));
+
+if (extra == NULL)
+  {
+  *errorptr = "failed to get memory";
+  return NULL;
+  }
+
+extra->options = PCRE_STUDY_MAPPED;
+memcpy(extra->start_bits, start_bits, sizeof(start_bits));
+
+return (pcre_extra *)extra;
+}
+
+/* End of study.c */
diff --git a/pcre/vc_dftables.dsp b/pcre/vc_dftables.dsp
new file mode 100755 (executable)
index 0000000..3a579a6
--- /dev/null
@@ -0,0 +1,296 @@
+# Microsoft Developer Studio Project File - Name="vc_dftables" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 5.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=vc_dftables - Win32 Debug with Win32 threads\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "vc_dftables.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "vc_dftables.mak"\\r
+ CFG="vc_dftables - Win32 Debug with Win32 threads"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "vc_dftables - Win32 Release" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE "vc_dftables - Win32 Debug" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE "vc_dftables - Win32 Debug with Win32 threads" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE "vc_dftables - Win32 Release with Win32 threads" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "vc_dftables - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "vc_dftables"\r
+# PROP Intermediate_Dir "vc_dftables"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# Begin Special Build Tool\r
+OutDir=.\vc_dftables\r
+SOURCE=$(InputPath)\r
+PostBuild_Desc=Running program to generate chartables.c\r
+PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c\r
+# End Special Build Tool\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "vc_dftables_dbg"\r
+# PROP Intermediate_Dir "vc_dftables_dbg"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# Begin Special Build Tool\r
+OutDir=.\vc_dftables_dbg\r
+SOURCE=$(InputPath)\r
+PostBuild_Desc=Running program to generate chartables.c\r
+PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c\r
+# End Special Build Tool\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "vc_dftab"\r
+# PROP BASE Intermediate_Dir "vc_dftab"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "vc_dftables_dbg"\r
+# PROP Intermediate_Dir "vc_dftables_dbg"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# Begin Special Build Tool\r
+OutDir=.\vc_dftables_dbg\r
+SOURCE=$(InputPath)\r
+PostBuild_Desc=Running program to generate chartables.c\r
+PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c\r
+# End Special Build Tool\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "vc_dfta0"\r
+# PROP BASE Intermediate_Dir "vc_dfta0"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "vc_dftables"\r
+# PROP Intermediate_Dir "vc_dftables"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# Begin Special Build Tool\r
+OutDir=.\vc_dftables\r
+SOURCE=$(InputPath)\r
+PostBuild_Desc=Running program to generate chartables.c\r
+PostBuild_Cmds=$(OutDir)\vc_dftables.exe >$(OutDir)\..\chartables.c\r
+# End Special Build Tool\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "vc_dftables - Win32 Release"\r
+# Name "vc_dftables - Win32 Debug"\r
+# Name "vc_dftables - Win32 Debug with Win32 threads"\r
+# Name "vc_dftables - Win32 Release with Win32 threads"\r
+# Begin Group "File Copy"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=..\vc_config_pthreads.h\r
+\r
+!IF  "$(CFG)" == "vc_dftables - Win32 Release"\r
+\r
+# PROP Ignore_Default_Tool 1\r
+# Begin Custom Build - Copying vc_config_pthreads.h\r
+WkspDir=.\r
+InputPath=..\vc_config_pthreads.h\r
+\r
+"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       copy "$(InputPath)" "$(WkspDir)\..\config.h"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug"\r
+\r
+# PROP Ignore_Default_Tool 1\r
+# Begin Custom Build - Copying vc_config_pthreads.h\r
+WkspDir=.\r
+InputPath=..\vc_config_pthreads.h\r
+\r
+"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       copy "$(InputPath)" "$(WkspDir)\..\config.h"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads"\r
+\r
+# PROP Exclude_From_Build 1\r
+# PROP Ignore_Default_Tool 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads"\r
+\r
+# PROP Exclude_From_Build 1\r
+# PROP Ignore_Default_Tool 1\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\vc_config_winthreads.h\r
+\r
+!IF  "$(CFG)" == "vc_dftables - Win32 Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+# PROP Ignore_Default_Tool 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+# PROP Ignore_Default_Tool 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads"\r
+\r
+# PROP Ignore_Default_Tool 1\r
+# Begin Custom Build - Copying vc_config_winthreads.h\r
+WkspDir=.\r
+InputPath=..\vc_config_winthreads.h\r
+\r
+"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       copy "$(InputPath)" "$(WkspDir)\..\config.h"\r
+\r
+# End Custom Build\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads"\r
+\r
+# PROP Ignore_Default_Tool 1\r
+# Begin Custom Build - Copying vc_config_winthreads.h\r
+WkspDir=.\r
+InputPath=..\vc_config_winthreads.h\r
+\r
+"$(WkspDir)\..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"\r
+       copy "$(InputPath)" "$(WkspDir)\..\config.h"\r
+\r
+# End Custom Build\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=..\config.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\config.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\dftables.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\internal.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\maketables.c\r
+\r
+!IF  "$(CFG)" == "vc_dftables - Win32 Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Debug with Win32 threads"\r
+\r
+# PROP BASE Exclude_From_Build 1\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_dftables - Win32 Release with Win32 threads"\r
+\r
+# PROP BASE Exclude_From_Build 1\r
+# PROP Exclude_From_Build 1\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre.h\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/pcrs.c b/pcrs.c
index cd0c94a..45a471b 100644 (file)
--- a/pcrs.c
+++ b/pcrs.c
-const char pcrs_rcs[] = "$Id: pcrs.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
+const char pcrs_rcs[] = "$Id: pcrs.c,v 1.18 2002/03/08 14:17:14 oes Exp $";
 
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/pcrs.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/pcrs.c,v $
  *
- * Purpose     :  This is the pre-pre-alpha realease of libpcrs. It is only
- *                published at this (ugly) stage of development, because it is
- *                needed for a new feature in JunkBuster.
+ * Purpose     :  pcrs is a supplement to the pcre library by Philip Hazel
+ *                <ph10@cam.ac.uk> and adds Perl-style substitution. That
+ *                is, it mimics Perl's 's' operator. See pcrs(3) for details.
  *
- *                Apart from the code being quite a mess, no inconsistencies,
- *                memory leaks or functional bugs **should** be present.
  *
- *                While you ROTFL at the code, you could just as well mail me
- *                (andreas@oesterhelt.org) with advice for improvement.
+ * Copyright   :  Written and Copyright (C) 2000, 2001 by Andreas S. Oesterhelt
+ *                <andreas@oesterhelt.org>
  *
- *                pcrs is a supplement to the brilliant pcre library by Philip
- *                Hazel (ph10@cam.ac.uk) and adds Perl-style substitution. That
- *                is, it mimics Perl's 's' operator.
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU Lesser
+ *                General Public License (LGPL), version 2.1, which  should
+ *                be included in this distribution (see LICENSE.txt), with
+ *                the exception that the permission to replace that license
+ *                with the GNU General Public License (GPL) given in section
+ *                3 is restricted to version 2 of the GPL.
  *
- *                Currently, there's no documentation besides comments and the
- *                source itself ;-)
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the license for more details.
  *
- * Copyright   :  Written and copyright by andreas@oesterhelt.org
+ *                The GNU Lesser General Public License should be included
+ *                with this file.  If not, you can view it at
+ *                http://www.gnu.org/licenses/lgpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
  * Revisions   :
  *    $Log: pcrs.c,v $
+ *    Revision 1.18  2002/03/08 14:17:14  oes
+ *    Fixing -Wconversion warnings
+ *
+ *    Revision 1.17  2002/03/08 13:45:48  oes
+ *    Hiding internal functions
+ *
+ *    Revision 1.16  2001/11/30 21:32:14  jongfoster
+ *    Fixing signed/unsigned comparison (Andreas please check this!)
+ *    One tab->space
+ *
+ *    Revision 1.15  2001/09/20 16:11:06  steudten
+ *
+ *    Add casting for some string functions.
+ *
+ *    Revision 1.14  2001/09/09 21:41:57  oes
+ *    Fixing yet another silly bug
+ *
+ *    Revision 1.13  2001/09/06 14:05:59  oes
+ *    Fixed silly bug
+ *
+ *    Revision 1.12  2001/08/18 11:35:00  oes
+ *    - Introduced pcrs_strerror()
+ *    - made some NULL arguments non-fatal
+ *    - added support for \n \r \e \b \t \f \a \0 in substitute
+ *    - made quoting adhere to standard rules
+ *    - added warning for bad backrefs
+ *    - added pcrs_execute_list()
+ *    - fixed comments
+ *    - bugfix & cosmetics
+ *
+ *    Revision 1.11  2001/08/15 15:32:03  oes
+ *     - Added support for Perl's special variables $+, $' and $`
+ *     - Improved the substitute parser
+ *     - Replaced the hard limit for the maximum number of matches
+ *       by dynamic reallocation
+ *
+ *    Revision 1.10  2001/08/05 13:13:11  jongfoster
+ *    Making parameters "const" where possible.
+ *
+ *    Revision 1.9  2001/07/18 17:27:00  oes
+ *    Changed interface; Cosmetics
+ *
+ *    Revision 1.8  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.7  2001/06/29 13:33:04  oes
+ *    - Cleaned up, renamed and reordered functions,
+ *      improved comments
+ *    - Removed my_strsep
+ *    - Replaced globalflag with a general flags int
+ *      that holds PCRS_GLOBAL, PCRS_SUCCESS, and PCRS_TRIVIAL
+ *    - Introduced trivial option that will prevent pcrs
+ *      from honouring backreferences in the substitute,
+ *      which is useful for large substitutes that are
+ *      red in from somewhere and saves the pain of escaping
+ *      the backrefs
+ *    - Introduced convenience function pcrs_free_joblist()
+ *    - Split pcrs_make_job() into pcrs_compile(), which still
+ *      takes a complete s/// comand as argument and parses it,
+ *      and a new function pcrs_make_job, which takes the
+ *      three separate components. This should make for a
+ *      much friendlier frontend.
+ *    - Removed create_pcrs_job() which was useless
+ *    - Fixed a bug in pcrs_execute
+ *    - Success flag is now handled by pcrs instead of user
+ *
+ *    Revision 1.6  2001/06/03 19:12:45  oes
+ *    added FIXME
+ *
+ *    Revision 1.5  2001/05/29 09:50:24  jongfoster
+ *    (Fixed one int -> size_t)
+ *
+ *    Revision 1.4  2001/05/25 14:12:40  oes
+ *    Fixed bug: Empty substitutes now detected
+ *
+ *    Revision 1.3  2001/05/25 11:03:55  oes
+ *    Added sanity check for NULL jobs to pcrs_exec_substitution
+ *
+ *    Revision 1.2  2001/05/22 18:46:04  oes
+ *
+ *      Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:02  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
 #include <pcre.h>
 #include <string.h>
+#include <ctype.h>
+
 #include "pcrs.h"
+
 const char pcrs_h_rcs[] = PCRS_H_VERSION;
 
+/*
+ * Internal prototypes
+ */
+
+static int              pcrs_parse_perl_options(const char *optstring, int *flags);
+static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag,
+                        int capturecount, int *errptr);
 
 /*********************************************************************
  *
- * Function    :  my_strsep
- *
- * Description :  Convenience function. It acts like strsep, except that
- *                it respects quoting of the delimiter character with the
- *                quote character. (And, of course, quoting the quote char
- *                with itself.)  Called from `pcrs_make_job'.
+ * Function    :  pcrs_strerror
  *
+ * Description :  Return a string describing a given error code.
+ *             
  * Parameters  :
- *          1  :  token = current token
- *          2  :  text = string to tokenize
- *          3  :  delimiter = single character deliminter
- *          4  :  quote_char = character to cause quoting
+ *          1  :  error = the error code
  *
- * Returns     :  -1 => failure, else the length of the token found.
- *                In the latter case, *text is the token's start.
+ * Returns     :  char * to the descriptive string
  *
  *********************************************************************/
-int my_strsep(char *token, char **text, char delimiter, char quote_char)
+const char *pcrs_strerror(const int error)
 {
-   int i, k=0, limit, quoted = FALSE;
-
-   limit = strlen(*text);
-   if ( 0 == limit )
+   if (error < 0)
    {
-      return -1;
-   }
-
-   token[0] = '\0';
-
-   for (i=0; i < limit; i++)
-   {
-      if (text[0][i] == delimiter && !quoted)
+      switch (error)
       {
-         *text += 1;
-         break;
-      }
-      else if (text[0][i] == quote_char && !quoted && i+1 < limit && text[0][i+1] == delimiter)
-      {
-         quoted = TRUE;
-         continue;
+         /* Passed-through PCRE error: */
+         case PCRE_ERROR_NOMEMORY:     return "(pcre:) No memory";
+
+         /* Shouldn't happen unless PCRE or PCRS bug, or user messed with compiled job: */
+         case PCRE_ERROR_NULL:         return "(pcre:) NULL code or subject or ovector";
+         case PCRE_ERROR_BADOPTION:    return "(pcre:) Unrecognized option bit";
+         case PCRE_ERROR_BADMAGIC:     return "(pcre:) Bad magic number in code";
+         case PCRE_ERROR_UNKNOWN_NODE: return "(pcre:) Bad node in pattern";
+
+         /* Can't happen / not passed: */
+         case PCRE_ERROR_NOSUBSTRING:  return "(pcre:) Fire in power supply"; 
+         case PCRE_ERROR_NOMATCH:      return "(pcre:) Water in power supply";
+
+         /* PCRS errors: */
+         case PCRS_ERR_NOMEM:          return "(pcrs:) No memory";
+         case PCRS_ERR_CMDSYNTAX:      return "(pcrs:) Syntax error while parsing command";
+         case PCRS_ERR_STUDY:          return "(pcrs:) PCRE error while studying the pattern";
+         case PCRS_ERR_BADJOB:         return "(pcrs:) Bad job - NULL job, pattern or substitute";
+         case PCRS_WARN_BADREF:        return "(pcrs:) Backreference out of range";
+
+         /* What's that? */
+         default:  return "Unknown error";
       }
-      token[k++] = text[0][i];
-      quoted = FALSE;
    }
-   token[k] = '\0';
-   *text += i;
-   return k;
+   /* error >= 0: No error */
+   return "(pcrs:) Everything's just fine. Thanks for asking.";
 
 }
 
 
 /*********************************************************************
  *
- * Function    :  pcrs_compile_perl_options
+ * Function    :  pcrs_parse_perl_options
  *
  * Description :  This function parses a string containing the options to
  *                Perl's s/// operator. It returns an integer that is the
  *                pcre equivalent of the symbolic optstring.
- *                Since pcre doesn't know about Perl's 'g' (global) option,
- *                but pcrs needs it, the globalflag integer is set if 'g'
- *                is encountered.
- *
+ *                Since pcre doesn't know about Perl's 'g' (global) or pcrs',
+ *                'T' (trivial) options but pcrs needs them, the corresponding
+ *                flags are set if 'g'or 'T' is encountered.
+ *                Note: The 'T' and 'U' options do not conform to Perl.
+ *             
  * Parameters  :
  *          1  :  optstring = string with options in perl syntax
- *          2  :  globalflag = see description
+ *          2  :  flags = see description
  *
  * Returns     :  option integer suitable for pcre 
  *
  *********************************************************************/
-int pcrs_compile_perl_options(char *optstring, int *globalflag)
+static int pcrs_parse_perl_options(const char *optstring, int *flags)
 {
-   int i, rc = 0;
-   *globalflag = 0;
-   for (i=0; i < strlen(optstring); i++)
+   size_t i;
+   int rc = 0;
+   *flags = 0;
+
+   if (NULL == optstring) return 0;
+
+   for (i = 0; i < strlen(optstring); i++)
    {
       switch(optstring[i])
       {
-         case 'e': break;
-         case 'g': *globalflag = 1; break;
+         case 'e': break; /* ToDo ;-) */
+         case 'g': *flags |= PCRS_GLOBAL; break;
          case 'i': rc |= PCRE_CASELESS; break;
          case 'm': rc |= PCRE_MULTILINE; break;
          case 'o': break;
          case 's': rc |= PCRE_DOTALL; break;
          case 'x': rc |= PCRE_EXTENDED; break;
-         default:  break;
+         case 'U': rc |= PCRE_UNGREEDY; break;
+         case 'T': *flags |= PCRS_TRIVIAL; break;
+         default: break;
       }
    }
    return rc;
@@ -141,7 +250,11 @@ int pcrs_compile_perl_options(char *optstring, int *globalflag)
  * Parameters  :
  *          1  :  replacement = replacement part of s/// operator
  *                              in perl syntax
- *          2  :  errptr = pointer to an integer in which error
+ *          2  :  trivialflag = Flag that causes backreferences to be
+ *                              ignored.
+ *          3  :  capturecount = Number of capturing subpatterns in
+ *                               the pattern. Needed for $+ handling.
+ *          4  :  errptr = pointer to an integer in which error
  *                         conditions can be returned.
  *
  * Returns     :  pcrs_substitute data structure, or NULL if an
@@ -149,82 +262,178 @@ int pcrs_compile_perl_options(char *optstring, int *globalflag)
  *                the reason.
  *
  *********************************************************************/
-pcrs_substitute *pcrs_compile_replacement(char *replacement, int *errptr)
+static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag, int capturecount, int *errptr)
 {
-   int length, i, k = 0, l = 0, quoted = 0, idx;
-   char *text, *num_ptr, *numbers = "0123456789";
+   int i, k, l, quoted;
+   size_t length;
+   char *text;
    pcrs_substitute *r;
 
-   r = (pcrs_substitute *)malloc(sizeof(pcrs_substitute));
-   if (r == NULL) return NULL;
-   memset(r, '\0', sizeof(pcrs_substitute));
+   i = k = l = quoted = 0;
+
+   /*
+    * Sanity check
+    */
+   if (NULL == replacement)
+   {
+      replacement = "";
+   }
 
-   text = strdup(replacement);      /* must be free()d by caller */
-   if (text  == NULL)
+   /*
+    * Get memory or fail
+    */
+   if (NULL == (r = (pcrs_substitute *)malloc(sizeof(pcrs_substitute))))
    {
       *errptr = PCRS_ERR_NOMEM;
-      free(r);
       return NULL;
    }
+   memset(r, '\0', sizeof(pcrs_substitute));
 
    length = strlen(replacement);
 
-   for (i=0; i < length; i++)
+   if (NULL == (text = (char *)malloc(length + 1)))
    {
-      /* Backslash treatment */
-      if (replacement[i] == '\\')
-      {
-         if (quoted)
-         {
-            text[k++] = replacement[i];
-            quoted = 0;
-         }
-         else
-         {
-            quoted = 1;
-         }
-         continue;
-      }
+      free(r);
+      *errptr = PCRS_ERR_NOMEM;
+      return NULL;
+   }
+   memset(text, '\0', length + 1);
+   
+
+   /*
+    * In trivial mode, just copy the substitute text
+    */
+   if (trivialflag)
+   {
+      text = strncpy(text, replacement, length + 1);
+      k = length;
+   }
 
-      /* Dollar treatment */
-      if (replacement[i] == '$' && !quoted && i < length - 1)
+   /*
+    * Else, parse, cut out and record all backreferences
+    */
+   else
+   {
+      while (i < (int)length)
       {
-         if (strchr("0123456789&", replacement[i + 1]) == NULL)
+         /* Quoting */
+         if (replacement[i] == '\\')
          {
-            text[k++] = replacement[i];
+            if (quoted)
+            {
+               text[k++] = replacement[i++];
+               quoted = 0;
+            }
+            else
+            {
+               if (replacement[i+1] && strchr("tnrfae0", replacement[i+1]))
+               {
+                  switch (replacement[++i])
+                  {
+                  case 't':
+                     text[k++] = '\t';
+                     break;
+                  case 'n':
+                     text[k++] = '\n';
+                     break;
+                  case 'r':
+                     text[k++] = '\r';
+                     break;
+                  case 'f':
+                     text[k++] = '\f';
+                     break;
+                  case 'a':
+                     text[k++] = 7;
+                     break;
+                  case 'e':
+                     text[k++] = 27;
+                     break;
+                  case '0':
+                     text[k++] = '\0';
+                     break;
+                  }
+                  i++;
+               }
+               else
+               {
+                  quoted = 1;
+                  i++;
+               }
+            }
+            continue;
          }
-         else
+
+         /* Backreferences */
+         if (replacement[i] == '$' && !quoted && i < (int)(length - 1))
          {
+            char *symbol, symbols[] = "'`+&";
             r->block_length[l] = k - r->block_offset[l];
-            r->backref[l] = 0;
-            if (replacement[i + 1] != '&')
+
+            /* Numerical backreferences */
+            if (isdigit((int)replacement[i + 1]))
             {
-               while ((num_ptr = strchr(numbers, replacement[++i])) != NULL && i < length)
+               while (i < (int)length && isdigit((int)replacement[++i]))
+               {
+                  r->backref[l] = r->backref[l] * 10 + replacement[i] - 48;
+               }
+               if (r->backref[l] > capturecount)
                {
-                  idx = num_ptr - numbers;
-                  r->backref[l] = r->backref[l] * 10 + idx;
+                  *errptr = PCRS_WARN_BADREF;
                }
-               i--;
             }
+
+            /* Symbolic backreferences: */
+            else if (NULL != (symbol = strchr(symbols, replacement[i + 1])))
+            {
+               
+               if (symbol - symbols == 2) /* $+ */
+               {
+                  r->backref[l] = capturecount;
+               }
+               else if (symbol - symbols == 3) /* $& */
+               {
+                  r->backref[l] = 0;
+               }
+               else /* $' or $` */
+               {
+                  r->backref[l] = PCRS_MAX_SUBMATCHES + 1 - (symbol - symbols);
+               }
+               i += 2;
+            }
+
+            /* Invalid backref -> plain '$' */
             else
-               i++;
-            if (r->backref[l] < PCRS_MAX_SUBMATCHES)
+            {
+               goto plainchar;
+            }
+
+            /* Valid and in range? -> record */
+            if (r->backref[l] < PCRS_MAX_SUBMATCHES + 2)
+            {
                r->backref_count[r->backref[l]] += 1;
-            l++;
-            r->block_offset[l] = k;
+               r->block_offset[++l] = k;
+            }
+            else
+            {
+               *errptr = PCRS_WARN_BADREF;
+            }   
+            continue;
          }
-         continue;
+         
+plainchar:
+         /* Plain chars are copied */
+         text[k++] = replacement[i++];
+         quoted = 0;
       }
+   } /* -END- if (!trivialflag) */
 
-      /* Plain char treatment */
-      text[k++] = replacement[i];
-      quoted = 0;
-   }
-
-   text[k] = '\0';
+   /*
+    * Finish & return
+    */
    r->text = text;
    r->backrefs = l;
    r->block_length[l] = k - r->block_offset[l];
+
    return r;
 
 }
@@ -235,14 +444,13 @@ pcrs_substitute *pcrs_compile_replacement(char *replacement, int *errptr)
  * Function    :  pcrs_free_job
  *
  * Description :  Frees the memory used by a pcrs_job struct and its
- *                dependant structures. Returns a pointer to the next
- *                job, if there was any, or NULL otherwise.
+ *                dependant structures.
  *
  * Parameters  :
  *          1  :  job = pointer to the pcrs_job structure to be freed
  *
- * Returns     : a pointer to the next job, if there was any, or
- *               NULL otherwise. 
+ * Returns     :  a pointer to the next job, if there was any, or
+ *                NULL otherwise. 
  *
  *********************************************************************/
 pcrs_job *pcrs_free_job(pcrs_job *job)
@@ -272,12 +480,35 @@ pcrs_job *pcrs_free_job(pcrs_job *job)
 
 /*********************************************************************
  *
- * Function    :  pcrs_make_job
+ * Function    :  pcrs_free_joblist
+ *
+ * Description :  Iterates through a chained list of pcrs_job's and
+ *                frees them using pcrs_free_job.
+ *
+ * Parameters  :
+ *          1  :  joblist = pointer to the first pcrs_job structure to
+ *                be freed
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void pcrs_free_joblist(pcrs_job *joblist)
+{
+   while ( NULL != (joblist = pcrs_free_job(joblist)) ) {};
+
+   return;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  pcrs_compile_command
  *
- * Description :  Main entry point. Takes a string with a Perl-style
- *                s/// command and returns a corresponding pcrs_job,
- *                or NULL if compiling the job fails at any stage.
- *                Diagnostics could obviously be improved.
+ * Description :  Parses a string with a Perl-style s/// command, 
+ *                calls pcrs_compile, and returns a corresponding
+ *                pcrs_job, or NULL if parsing or compiling the job
+ *                fails.
  *
  * Parameters  :
  *          1  :  command = string with perl-style s/// command
@@ -289,81 +520,139 @@ pcrs_job *pcrs_free_job(pcrs_job *job)
  *                has the reason.
  *
  *********************************************************************/
-pcrs_job *pcrs_make_job(char *command, int *errptr)
+pcrs_job *pcrs_compile_command(const char *command, int *errptr)
 {
-   char *dummy, *token, delimiter;
-   const char *error;
-   int i = 0, globalflag;
+   int i, k, l, quoted = FALSE;
+   size_t limit;
+   char delimiter;
+   char *tokens[4];   
    pcrs_job *newjob;
-
-   /* Get and init memory */
-   if ((newjob = (pcrs_job *)malloc(sizeof(pcrs_job))) == NULL)
+   
+   i = k = l = 0;
+   
+   /*
+    * Tokenize the perl command
+    */
+   limit = strlen(command);
+   if (limit < 4)
    {
-      *errptr = PCRS_ERR_NOMEM;
+      *errptr = PCRS_ERR_CMDSYNTAX;
       return NULL;
    }
-   memset(newjob, '\0', sizeof(pcrs_job));
-
-   /* Command too short? */
-   if (strlen(command) < 4)
+   else
    {
-      *errptr = PCRS_ERR_CMDSYNTAX;
-      pcrs_free_job(newjob);
-      return NULL;
+      delimiter = command[1];
    }
 
-   /* Split command into tokens and handle them */
-   delimiter = command[1];
-   token = (char *)malloc(strlen(command)); /* current token */
-   dummy = (char *)malloc(strlen(command)); /* must store pattern, since we can't */
-                                            /* use it until the options are known */
-   while (my_strsep(token, &command, delimiter, '\\') >= 0)
+   tokens[l] = (char *) malloc(limit + 1);
+
+   for (i = 0; i <= (int)limit; i++)
    {
-      switch (i)
+      
+      if (command[i] == delimiter && !quoted)
       {
-  /* We don't care about the command and assume 's' */
-         case 0:
+         if (l == 3)
+         {
+            l = -1;
             break;
+         }
+         tokens[0][k++] = '\0';
+         tokens[++l] = tokens[0] + k;
+         continue;
+      }
+      
+      else if (command[i] == '\\' && !quoted)
+      {
+         quoted = TRUE;
+         if (command[i+1] == delimiter) continue;
+      }
+      else
+      {
+         quoted = FALSE;
+      }
+      tokens[0][k++] = command[i];
+   }
 
-         /* The pattern */
-         case 1:
-            strcpy(dummy, token);
-            break;
+   /*
+    * Syntax error ?
+    */
+   if (l != 3)
+   {
+      *errptr = PCRS_ERR_CMDSYNTAX;
+      free(tokens[0]);
+      return NULL;
+   }
+   
+   newjob = pcrs_compile(tokens[1], tokens[2], tokens[3], errptr);
+   free(tokens[0]);
+   return newjob;
+   
+}
 
-         /* The substitute */
-         case 2:
-            newjob->substitute = pcrs_compile_replacement(token, errptr);
-            if (newjob->substitute == NULL)
-            {
-               pcrs_free_job(newjob);
-               return NULL;
-            }
-            break;
 
-         /* The options */
-         case 3:
-            newjob->options = pcrs_compile_perl_options(token, &globalflag);
-            newjob->globalflag = globalflag;
-            break;
+/*********************************************************************
+ *
+ * Function    :  pcrs_compile
+ *
+ * Description :  Takes the three arguments to a perl s/// command
+ *                and compiles a pcrs_job structure from them.
+ *
+ * Parameters  :
+ *          1  :  pattern = string with perl-style pattern
+ *          2  :  substitute = string with perl-style substitute
+ *          3  :  options = string with perl-style options
+ *          4  :  errptr = pointer to an integer in which error
+ *                         conditions can be returned.
+ *
+ * Returns     :  a corresponding pcrs_job data structure, or NULL
+ *                if an error was encountered. In that case, *errptr
+ *                has the reason.
+ *
+ *********************************************************************/
+pcrs_job *pcrs_compile(const char *pattern, const char *substitute, const char *options, int *errptr)
+{
+   pcrs_job *newjob;
+   int flags;
+   int capturecount;
+   const char *error;
 
-         /* There shouldn't be anything else! */
-         default:
-            *errptr = PCRS_ERR_CMDSYNTAX;
-            pcrs_free_job(newjob);
-            return NULL;
-      }
-      i++;
+   *errptr = 0;
+
+   /* 
+    * Handle NULL arguments
+    */
+   if (pattern == NULL) pattern = "";
+   if (substitute == NULL) substitute = "";
+
+
+   /* 
+    * Get and init memory
+    */
+   if (NULL == (newjob = (pcrs_job *)malloc(sizeof(pcrs_job))))
+   {
+      *errptr = PCRS_ERR_NOMEM;
+      return NULL;
    }
-   free(token);
+   memset(newjob, '\0', sizeof(pcrs_job));
 
-   /* Compile the pattern */
-   newjob->pattern = pcre_compile(dummy, newjob->options, &error, errptr, NULL);
+
+   /*
+    * Evaluate the options
+    */
+   newjob->options = pcrs_parse_perl_options(options, &flags);
+   newjob->flags = flags;
+
+
+   /*
+    * Compile the pattern
+    */
+   newjob->pattern = pcre_compile(pattern, newjob->options, &error, errptr, NULL);
    if (newjob->pattern == NULL)
    {
       pcrs_free_job(newjob);
       return NULL;
    }
-   free(dummy);
+
 
    /*
     * Generate hints. This has little overhead, since the
@@ -376,7 +665,28 @@ pcrs_job *pcrs_make_job(char *command, int *errptr)
       pcrs_free_job(newjob);
       return NULL;
    }
+
+   /* 
+    * Determine the number of capturing subpatterns. 
+    * This is needed for handling $+ in the substitute.
+    */
+   if (0 > (*errptr = pcre_fullinfo(newjob->pattern, newjob->hints, PCRE_INFO_CAPTURECOUNT, &capturecount)))
+   {
+      pcrs_free_job(newjob);
+      return NULL;
+   }
 
+   /*
+    * Compile the substitute
+    */
+   if (NULL == (newjob->substitute = pcrs_compile_replacement(substitute, newjob->flags & PCRS_TRIVIAL, capturecount, errptr)))
+   {
+      pcrs_free_job(newjob);
+      return NULL;
+   }
    return newjob;
 
 }
@@ -384,95 +694,170 @@ pcrs_job *pcrs_make_job(char *command, int *errptr)
 
 /*********************************************************************
  *
- * Function    :  create_pcrs_job
+ * Function    :  pcrs_execute_list
  *
- * Description :  Create a job from all its components, if you don't
- *                have a Perl command to start from. Rather boring.
+ * Description :  This is a multiple job wrapper for pcrs_execute().
+ *                Apply the regular substitutions defined by the jobs in
+ *                the joblist to the subject.
+ *                The subject itself is left untouched, memory for the result
+ *                is malloc()ed and it is the caller's responsibility to free
+ *                the result when it's no longer needed.
  *
  * Parameters  :
- *          1  :  pattern = pointer to pcre pattern
- *          2  :  hints = pointer to pcre hints
- *          3  :  options = options in pcre format
- *          4  :  globalflag = flag that indicates if global matching is desired
- *          5  :  substitute = pointer to pcrs_substitute data structure
- *          2  :  errptr = pointer to an integer in which error
- *                         conditions can be returned.
+ *          1  :  joblist = the chained list of pcrs_jobs to be executed
+ *          2  :  subject = the subject string
+ *          3  :  subject_length = the subject's length 
+ *                INCLUDING the terminating zero, if string!
+ *          4  :  result = char** for returning  the result 
+ *          5  :  result_length = size_t* for returning the result's length
  *
- * Returns     :  pcrs_job structure, or NULL if an error was encountered.
- *                In that case, *errptr has the reason why.
+ * Returns     :  On success, the number of substitutions that were made.
+ *                 May be > 1 if job->flags contained PCRS_GLOBAL
+ *                On failiure, the (negative) pcre error code describing the
+ *                 failiure, which may be translated to text using pcrs_strerror().
  *
  *********************************************************************/
-pcrs_job *create_pcrs_job(pcre *pattern, pcre_extra *hints, int options, int globalflag, pcrs_substitute *substitute, int *errptr)
+int pcrs_execute_list(pcrs_job *joblist, char *subject, size_t subject_length, char **result, size_t *result_length)
 {
-   pcrs_job *newjob;
-
-   if ((newjob = (pcrs_job *)malloc(sizeof(pcrs_job))) == NULL)
+   pcrs_job *job;
+   char *old, *new;
+   int hits, total_hits;
+   old = subject;
+   *result_length = subject_length;
+   hits = total_hits = 0;
+
+   for (job = joblist; job != NULL; job = job->next)
    {
-      *errptr = PCRS_ERR_NOMEM;
-      return NULL;
-   }
-   memset(newjob, '\0', sizeof(pcrs_job));
+      hits = pcrs_execute(job, old, *result_length, &new, result_length);
+
+      if (old != subject) free(old);
 
-   newjob->pattern = pattern;
-   newjob->hints = hints;
-   newjob->options = options;
-   newjob->globalflag = globalflag;
-   newjob->substitute = substitute;
+      if (hits < 0)
+      {
+         return(hits);
+      }
+      else
+      {
+         total_hits += hits;
+         old = new;
+      }
+   }
 
-   return(newjob);
+   *result = new;
+   return(total_hits);
 
 }
 
 
 /*********************************************************************
  *
- * Function    :  pcrs_exec_substitution
+ * Function    :  pcrs_execute
  *
- * Description :  Modify the subject by executing the regular substitution
- *                defined by the job. Since the result may be longer than
- *                the subject, its space requirements are precalculated in
- *                the matching phase and new memory is allocated accordingly.
- *                It is the caller's responsibility to free the result when
- *                it's no longer needed.
+ * Description :  Apply the regular substitution defined by the job to the
+ *                subject.
+ *                The subject itself is left untouched, memory for the result
+ *                is malloc()ed and it is the caller's responsibility to free
+ *                the result when it's no longer needed.
  *
  * Parameters  :
  *          1  :  job = the pcrs_job to be executed
  *          2  :  subject = the subject (== original) string
- *          3  :  subject_length = the subject's length
+ *          3  :  subject_length = the subject's length 
+ *                INCLUDING the terminating zero, if string!
  *          4  :  result = char** for returning  the result 
- *          5  :  result_length = int* for returning the result's length
+ *          5  :  result_length = size_t* for returning the result's length
  *
- * Returns     :  the number of substitutions that were made. May be > 1
- *                if job->globalflag was set
+ * Returns     :  On success, the number of substitutions that were made.
+ *                 May be > 1 if job->flags contained PCRS_GLOBAL
+ *                On failiure, the (negative) pcre error code describing the
+ *                 failiure, which may be translated to text using pcrs_strerror().
  *
  *********************************************************************/
-int pcrs_exec_substitution(pcrs_job *job, char *subject, int subject_length, char **result, int *result_length)
+int pcrs_execute(pcrs_job *job, char *subject, size_t subject_length, char **result, size_t *result_length)
 {
    int offsets[3 * PCRS_MAX_SUBMATCHES],
-      offset = 0, i=0, k, matches_found, newsize, submatches;
-   pcrs_match matches[PCRS_MAX_MATCHES];
+       offset,
+       i, k,
+       matches_found,
+       submatches,
+       max_matches = PCRS_MAX_MATCH_INIT;
+   size_t newsize;
+   pcrs_match *matches, *dummy;
    char *result_offset;
 
-   newsize=subject_length;
+   offset = i = k = 0;
+
+   /* 
+    * Sanity check & memory allocation
+    */
+   if (job == NULL || job->pattern == NULL || job->substitute == NULL)
+   {
+      *result = NULL;
+      return(PCRS_ERR_BADJOB);
+   }
+
+   if (NULL == (matches = (pcrs_match *)malloc(max_matches * sizeof(pcrs_match))))
+   {
+      *result = NULL;
+      return(PCRS_ERR_NOMEM);
+   }
+   memset(matches, '\0', max_matches * sizeof(pcrs_match));
+
 
-   /* Find.. */
-   while ((submatches = pcre_exec(job->pattern, job->hints, subject, subject_length, offset, 0, offsets, 99)) > 0)
+   /*
+    * Find the pattern and calculate the space
+    * requirements for the result
+    */
+   newsize = subject_length;
+
+   while ((submatches = pcre_exec(job->pattern, job->hints, subject, (int)subject_length, offset, 0, offsets, 3 * PCRS_MAX_SUBMATCHES)) > 0)
    {
+      job->flags |= PCRS_SUCCESS;
       matches[i].submatches = submatches;
-      for (k=0; k < submatches; k++)
+
+      for (k = 0; k < submatches; k++)
       {
          matches[i].submatch_offset[k] = offsets[2 * k];
-         matches[i].submatch_length[k] = offsets[2 * k + 1] - offsets[2 * k]; /* Non-found optional submatches have length -1-(-1)==0 */
-         newsize += matches[i].submatch_length[k] * job->substitute->backref_count[k]; /* reserve mem for each submatch as often as it is ref'd */
+
+         /* Note: Non-found optional submatches have length -1-(-1)==0 */
+         matches[i].submatch_length[k] = offsets[2 * k + 1] - offsets[2 * k]; 
+
+         /* reserve mem for each submatch as often as it is ref'd */
+         newsize += matches[i].submatch_length[k] * job->substitute->backref_count[k]; 
+      }
+      /* plus replacement text size minus match text size */
+      newsize += strlen(job->substitute->text) - matches[i].submatch_length[0]; 
+
+      /* chunk before match */
+      matches[i].submatch_offset[PCRS_MAX_SUBMATCHES] = 0;
+      matches[i].submatch_length[PCRS_MAX_SUBMATCHES] = offsets[0];
+      newsize += offsets[0] * job->substitute->backref_count[PCRS_MAX_SUBMATCHES];
+
+      /* chunk after match */
+      matches[i].submatch_offset[PCRS_MAX_SUBMATCHES + 1] = offsets[1];
+      matches[i].submatch_length[PCRS_MAX_SUBMATCHES + 1] = subject_length - offsets[1] - 1;
+      newsize += (subject_length - offsets[1]) * job->substitute->backref_count[PCRS_MAX_SUBMATCHES + 1];
+
+      /* Storage for matches exhausted? -> Extend! */
+      if (++i >= max_matches)
+      {
+         max_matches = (int)(max_matches * PCRS_MAX_MATCH_GROW);
+         if (NULL == (dummy = (pcrs_match *)realloc(matches, max_matches * sizeof(pcrs_match))))
+         {
+            free(matches);
+            *result = NULL;
+            return(PCRS_ERR_NOMEM);
+         }
+         matches = dummy;
       }
-      newsize += strlen(job->substitute->text) - matches[i].submatch_length[0]; /* plus replacement text size minus match text size */
 
       /* Non-global search or limit reached? */
-      if (++i >= PCRS_MAX_MATCHES || !job->globalflag ) break;
+      if (!(job->flags & PCRS_GLOBAL)) break;
 
       /* Don't loop on empty matches */
       if (offsets[1] == offset)
-         if (offset < subject_length)
+         if ((size_t)offset < subject_length)
             offset++;
          else
             break;
@@ -480,39 +865,52 @@ int pcrs_exec_substitution(pcrs_job *job, char *subject, int subject_length, cha
       else
          offset = offsets[1];
    }
-   if (submatches < -1) return submatches;   /* Pass pcre error through */
+   /* Pass pcre error through if (bad) failiure */
+   if (submatches < PCRE_ERROR_NOMATCH)
+   {
+      free(matches);
+      return submatches;   
+   }
    matches_found = i;
 
-   /* ..get memory ..*/
+
+   /* 
+    * Get memory for the result
+    */
    if ((*result = (char *)malloc(newsize)) == NULL)   /* must be free()d by caller */
    {
+      free(matches);
       return PCRS_ERR_NOMEM;
    }
 
-   /* ..and replace */
+
+   /* 
+    * Replace
+    */
    offset = 0;
    result_offset = *result;
 
-   for (i=0; i < matches_found; i++)
+   for (i = 0; i < matches_found; i++)
    {
-      memcpy(result_offset, subject + offset, matches[i].submatch_offset[0] - offset); /* copy the chunk preceding the match */
+      /* copy the chunk preceding the match */
+      memcpy(result_offset, subject + offset, (size_t)matches[i].submatch_offset[0] - offset); 
       result_offset += matches[i].submatch_offset[0] - offset;
 
       /* For every segment of the substitute.. */
-      for (k=0; k <= job->substitute->backrefs; k++)
+      for (k = 0; k <= job->substitute->backrefs; k++)
       {
          /* ...copy its text.. */
          memcpy(result_offset, job->substitute->text + job->substitute->block_offset[k], job->substitute->block_length[k]);
          result_offset += job->substitute->block_length[k];
 
-         /* ..plus, if it's not the last chunk (i.e.: There IS a backref).. */
+         /* ..plus, if it's not the last chunk, i.e.: There *is* a backref.. */
          if (k != job->substitute->backrefs
-             /* ..and a nonempty match.. */
-             && matches[i].submatch_length[job->substitute->backref[k]] > 0
-             /* ..and in legal range, ... */
-             && job->substitute->backref[k] <= PCRS_MAX_SUBMATCHES)
+             /* ..in legal range.. */
+             && job->substitute->backref[k] < PCRS_MAX_SUBMATCHES + 2
+             /* ..and referencing a nonempty match.. */
+             && matches[i].submatch_length[job->substitute->backref[k]] > 0)
          {
-            /* copy the submatch that is ref'd. */
+            /* ..copy the submatch that is ref'd. */
             memcpy(
                result_offset,
                subject + matches[i].submatch_offset[job->substitute->backref[k]],
@@ -528,6 +926,7 @@ int pcrs_exec_substitution(pcrs_job *job, char *subject, int subject_length, cha
    memcpy(result_offset, subject + offset, subject_length - offset);
 
    *result_length = newsize;
+   free(matches);
    return matches_found;
 
 }
diff --git a/pcrs.h b/pcrs.h
index ba77c38..a14b816 100644 (file)
--- a/pcrs.h
+++ b/pcrs.h
@@ -1,31 +1,50 @@
-#ifndef _PCRS_H
-#define _PCRS_H
+#ifndef PCRS_H_INCLUDED
+#define PCRS_H_INCLUDED
 
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/pcrs.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/pcrs.h,v $
  *
- * Purpose     :  This is the pre-pre-alpha realease of libpcrs. It is only
- *                published at this (ugly) stage of development, because it is
- *                needed for a new feature in JunkBuster.
+ * Purpose     :  Header file for pcrs.c
  *
- *                Apart from the code being quite a mess, no inconsistencies,
- *                memory leaks or functional bugs **should** be present.
+ * Copyright   :  see pcrs.c
  *
- *                While you ROTFL at the code, you could just as well mail me
- *                (oes@paradis.rhein.de) with advice for improvement.
+ * Revisions   :
+ *    $Log: pcrs.h,v $
+ *    Revision 1.10  2002/03/08 13:44:48  oes
+ *    Hiding internal functions, preventing double inclusion of pcre.h
  *
- *                pcrs is a supplement to the brilliant pcre library by Philip
- *                Hazel (ph10@cam.ac.uk) and adds Perl-style substitution. That
- *                is, it mimics Perl's 's' operator.
+ *    Revision 1.9  2001/08/18 11:35:29  oes
+ *    - Introduced pcrs_strerror()
+ *    - added pcrs_execute_list()
  *
- *                Currently, there's no documentation besides comments and the
- *                source itself ;-)
+ *    Revision 1.8  2001/08/15 15:32:50  oes
+ *    Replaced the hard limit for the maximum number of matches
+ *    by dynamic reallocation
  *
- * Copyright   :  Written and copyright 2001 by Sourceforge IJBSWA team.
+ *    Revision 1.7  2001/08/05 13:13:11  jongfoster
+ *    Making parameters "const" where possible.
+ *
+ *    Revision 1.6  2001/07/29 18:52:06  jongfoster
+ *    Renaming _PCRS_H, and adding "extern C {}"
+ *
+ *    Revision 1.5  2001/07/18 17:27:00  oes
+ *    Changed interface; Cosmetics
+ *
+ *    Revision 1.4  2001/06/29 13:33:19  oes
+ *    - Cleaned up, commented and adapted to reflect the
+ *      changes in pcrs.c
+ *    - Introduced the PCRS_* flags
+ *
+ *    Revision 1.3  2001/06/09 10:58:57  jongfoster
+ *    Removing a single unused #define which referenced BUFSIZ
+ *
+ *    Revision 1.2  2001/05/25 11:03:55  oes
+ *    Added sanity check for NULL jobs to pcrs_exec_substitution
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:02  oes
+ *    Initial import of version 2.9.3 source tree
  *
- * Revisions   :
- *    $Log: pcrs.h,v $
  *    Revision 1.4  2001/05/11 01:57:02  rodney
  *    Added new file header standard w/RCS control tags.
  *
  *
  *********************************************************************/
 
-#define PCRS_H_VERSION "$Id: pcrs.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
+#define PCRS_H_VERSION "$Id: pcrs.h,v 1.10 2002/03/08 13:44:48 oes Exp $"
 \f
 
-
+#ifndef _PCRE_H
 #include <pcre.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Constants:
+ */
 
 #define FALSE 0
 #define TRUE 1
-#define PCRS_MAX_MATCHES 300
-#define PCRS_MAX_SUBMATCHES 33
-#define CHARBUFSIZ BUFSIZ * sizeof(char)
 
+/* Capacity */
+#define PCRS_MAX_SUBMATCHES  33     /* Maximum number of capturing subpatterns allowed. MUST be <= 99! FIXME: Should be dynamic */
+#define PCRS_MAX_MATCH_INIT  40     /* Initial amount of matches that can be stored in global searches */
+#define PCRS_MAX_MATCH_GROW  1.6    /* Factor by which storage for matches is extended if exhausted */
+
+/* Error codes */
 #define PCRS_ERR_NOMEM     -10      /* Failed to acquire memory. */
 #define PCRS_ERR_CMDSYNTAX -11      /* Syntax of s///-command */
 #define PCRS_ERR_STUDY     -12      /* pcre error while studying the pattern */
+#define PCRS_ERR_BADJOB    -13      /* NULL job pointer, pattern or substitute */
+#define PCRS_WARN_BADREF   -14      /* Backreference out of range */
+
+/* Flags */
+#define PCRS_GLOBAL          1      /* Job should be applied globally, as with perl's g option */
+#define PCRS_TRIVIAL         2      /* Backreferences in the substitute are ignored */
+#define PCRS_SUCCESS         4      /* Job did previously match */
 
-typedef struct S_PCRS_SUBSTITUTE {
-  char *text;
-  int backrefs;
-  int block_offset[PCRS_MAX_SUBMATCHES];
-  int block_length[PCRS_MAX_SUBMATCHES];
-  int backref[PCRS_MAX_SUBMATCHES];
-  int backref_count[PCRS_MAX_SUBMATCHES];
+
+/*
+ * Data types:
+ */
+
+/* A compiled substitute */
+
+typedef struct {
+  char  *text;                                   /* The plaintext part of the substitute, with all backreferences stripped */
+  int    backrefs;                               /* The number of backreferences */
+  int    block_offset[PCRS_MAX_SUBMATCHES];      /* Array with the offsets of all plaintext blocks in text */
+  size_t block_length[PCRS_MAX_SUBMATCHES];      /* Array with the lengths of all plaintext blocks in text */
+  int    backref[PCRS_MAX_SUBMATCHES];           /* Array with the backref number for all plaintext block borders */
+  int    backref_count[PCRS_MAX_SUBMATCHES + 2]; /* Array with the number of references to each backref index */
 } pcrs_substitute;
 
-typedef struct S_PCRS_MATCH {
-  /* char *buffer; */
-  int submatches;
-  int submatch_offset[PCRS_MAX_SUBMATCHES];
-  int submatch_length[PCRS_MAX_SUBMATCHES];
+
+/*
+ * A match, including all captured subpatterns (submatches)
+ * Note: The zeroth is the whole match, the PCRS_MAX_SUBMATCHES + 0th
+ * is the range before the match, the PCRS_MAX_SUBMATCHES + 1th is the
+ * range after the match.
+ */
+
+typedef struct {
+  int    submatches;                               /* Number of captured subpatterns */
+  int    submatch_offset[PCRS_MAX_SUBMATCHES + 2]; /* Offset for each submatch in the subject */
+  size_t submatch_length[PCRS_MAX_SUBMATCHES + 2]; /* Length of each submatch in the subject */
 } pcrs_match;
 
-typedef struct S_PCRS_JOB {
-  pcre *pattern;
-  pcre_extra *hints;
-  int options;
-  int globalflag;
-  int successflag;
-  pcrs_substitute *substitute;
-  struct S_PCRS_JOB *next;
+
+/* A PCRS job */
+
+typedef struct PCRS_JOB {
+  pcre *pattern;                            /* The compiled pcre pattern */
+  pcre_extra *hints;                        /* The pcre hints for the pattern */
+  int options;                              /* The pcre options (numeric) */
+  int flags;                                /* The pcrs and user flags (see "Flags" above) */
+  pcrs_substitute *substitute;              /* The compiled pcrs substitute */
+  struct PCRS_JOB *next;                    /* Pointer for chaining jobs to joblists */
 } pcrs_job;
 
-extern int              pcrs_compile_perl_options(char *optstring, int *globalflag);
-extern pcrs_substitute *pcrs_compile_replacement(char *replacement, int *errptr);
+
+/*
+ * Prototypes:
+ */
+
+/* Main usage */
+extern pcrs_job        *pcrs_compile_command(const char *command, int *errptr);
+extern pcrs_job        *pcrs_compile(const char *pattern, const char *substitute, const char *options, int *errptr);
+extern int              pcrs_execute(pcrs_job *job, char *subject, size_t subject_length, char **result, size_t *result_length);
+extern int              pcrs_execute_list(pcrs_job *joblist, char *subject, size_t subject_length, char **result, size_t *result_length);
+
+/* Freeing jobs */
 extern pcrs_job        *pcrs_free_job(pcrs_job *job);
-extern pcrs_job        *pcrs_make_job(char *command, int *errptr);
-extern pcrs_job        *create_pcrs_job(pcre *pattern, pcre_extra *hints, int options, int globalflag, pcrs_substitute *substitute, int *errptr);
-extern int              pcrs_exec_substitution(pcrs_job *job, char *subject, int subject_length, char **result, int *result_length);
+extern void             pcrs_free_joblist(pcrs_job *joblist);
+
+/* Info on errors: */
+extern const char *pcrs_strerror(const int error);
+
 
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
 
-#endif /* ndef _PCRS_H */
+#endif /* ndef PCRS_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/popup b/popup
deleted file mode 100644 (file)
index 07f0c36..0000000
--- a/popup
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# $Id: popup,v 1.1 2001/04/16 21:10:38 rodney Exp $
-#
-#  This is the configuration file for blocking Javascript popup windows,
-# it specifies both hosts to block from, and hosts to allow the popups
-# from.
-#
-#  The format is the hostname to block, or allow.
-#
-#  eg:
-#
-#  www.geocities.com       # block all popups from geocities.
-#
-#  ~www.trusted-host.com   # Allow popups from the trusted host domain.
-#
-#
-#   If a site is not explicitly blocked popups will be allowed, the
-# "allowable" syntax with "~" exists as a marker that you've explicitly
-# allowed something.
-#
-#   Order is not relevant - an allowable entry overrides a blocked entry,
-# e.g.
-#  ~myhost.com    # Allows myhost.com
-#  myhost.com     # _Still_ allowed.
-#
-#  Steve Kemp
-#  ---
-#  http://www.tardis.ed.ac.uk/~skx/junk/   for more details.
-#
-#
-
-
-
-# This is for the test page, at http://www.tardis.ed.ac.uk/~skx/junk/
-www.tardis.ed.ac.uk
-
-#
-# Samples, uncomment to use:
-#
-
-# members.tripod.co.uk
-# www.geocities.com
-# ~windowsupdates.microsoft.com
-# ~updates.microsoft.com
\ No newline at end of file
diff --git a/privoxy-rh.spec b/privoxy-rh.spec
new file mode 100644 (file)
index 0000000..994a241
--- /dev/null
@@ -0,0 +1,955 @@
+# $Id: privoxy-rh.spec,v 1.32 2002/05/16 01:37:29 hal9 Exp $
+#
+# Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Based on the Internet Junkbuster originally written
+# by and Copyright (C) 1997 Anonymous Coders and 
+# Junkbusters Corporation.  http://www.junkbusters.com
+#
+# This program is free software; you can redistribute it 
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.  See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file.  If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+# Defines should happen in the begining of the file
+%define veryoldname junkbust
+%define oldname junkbuster
+%define privoxyconf %{_sysconfdir}/%{name}
+%define privoxy_uid 73
+%define privoxy_gid 73
+
+Name: privoxy
+# ATTENTION
+# Version and release should be updated acordingly on configure.in and
+# configure. Otherwise, the package can be build with the wrong value
+Version: 2.9.15
+Release: 1
+Summary: Privoxy - privacy enhancing proxy
+License: GPL
+Vendor: Privoxy.Org
+Source0: http://www.waldherr.org/%{name}/%{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+Group: Networking/Utilities
+URL: http://www.privoxy.org/
+Obsoletes: junkbuster-raw junkbuster-blank junkbuster
+# Prereq: /usr/sbin/useradd , /sbin/chkconfig , /sbin/service 
+Prereq: shadow-utils, chkconfig, initscripts, sh-utils
+BuildRequires: perl gzip sed libtool autoconf 
+Conflicts: junkbuster-raw junkbuster-blank junkbuster
+
+%description 
+Privoxy is a web proxy with advanced filtering capabilities for
+protecting privacy, filtering web page content, managing cookies,
+controlling access, and removing ads, banners, pop-ups and other
+obnoxious Internet junk. Privoxy has a very flexible configuration and
+can be customized to suit individual needs and tastes. Privoxy has application
+for both stand-alone systems and multi-user networks.
+
+Privoxy is based on the Internet Junkbuster.
+
+%prep
+%setup -q -c
+
+%build
+
+# We check to see if versions match
+VERSION_MAJOR=2
+VERSION_MINOR=9
+VERSION_POINT=15
+
+CONFIG_VERSION=`cat configure.in | sed -n -e 's/^VERSION_MAJOR=\([0-9]*\)/\1./p' -e 's/^VERSION_MINOR=\([0-9]*\)/\1./p' -e 's/^VERSION_POINT=\([0-9]*\)/\1/p' | awk '{printf $1}'`
+if [ "%{version}" != "${CONFIG_VERSION}" ]; then
+       echo "The version declared on the specfile does not match the version"
+       echo "declared on configure.in. This should not happen. The build will"
+       echo "be interrupted now, so you can fix it."
+       exit 1
+fi
+autoheader
+autoconf
+%configure --disable-dynamic-pcre
+make 
+# Docs are in CVS and tarball now.
+#%%make dok
+
+## Explicitily stripping is not recomended.
+## This is handled altomaticaly by RPM, and can couse troubles if
+## anyone wants to build an unstriped version - morcego
+#strip %{name}
+
+%install
+[ "%{buildroot}" != "/" ] && rm -rf %{buildroot}
+mkdir -p %{buildroot}%{_sbindir} \
+         %{buildroot}%{_mandir}/man1 \
+         %{buildroot}%{_localstatedir}/log/%{name} \
+         %{buildroot}%{privoxyconf}/templates \
+         %{buildroot}%{_sysconfdir}/logrotate.d \
+         %{buildroot}%{_sysconfdir}/rc.d/init.d 
+
+## Manual gziping of manpages should not be done, once it can
+## break the building on some distributions. Anyway, rpm does it
+## automagicaly these days
+## Gziping the documentation files is not recomended - morcego
+#gzip README AUTHORS ChangeLog %{name}.1 || /bin/true
+
+install -s -m 744 %{name} %{buildroot}%{_sbindir}/%{name}
+
+cp -f %{name}.1 %{buildroot}%{_mandir}/man1/%{name}.1
+cp -f *.action %{buildroot}%{privoxyconf}/
+cp -f default.filter %{buildroot}%{privoxyconf}/default.filter
+cp -f trust %{buildroot}%{privoxyconf}/trust
+cp -f templates/*  %{buildroot}%{privoxyconf}/templates/
+cp -f %{name}.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
+install -m 755 %{name}.init %{buildroot}%{_sysconfdir}/rc.d/init.d/%{name}
+install -m 711 -d %{buildroot}%{_localstatedir}/log/%{name}
+
+# verify all file locations, etc. in the config file
+# don't start with ^ or commented lines are not replaced
+## Changing the sed paramter delimiter to @, so we don't have to
+## escape the slashes
+cat config | \
+    sed 's@^confdir.*@confdir %{privoxyconf}@g' | \
+#    sed 's/^permissionsfile.*/permissionsfile \/etc\/%{name}\/permissionsfile/g' | \
+#    sed 's/^filterfile.*/default.filter \/etc\/%{name}\/default.filter/g' | \
+#    sed 's/^logfile.*/logfile \%{_localstatedir}\/log\/%{name}\/logfile/g' | \
+#    sed 's/^jarfile.*/jarfile \%{_localstatedir}\/log\/%{name}\/jarfile/g' | \
+#    sed 's/^forward.*/forward \/etc\/%{name}\/forward/g' | \
+#    sed 's/^aclfile.*/aclfile \/etc\/%{name}\/aclfile/g' > \
+    sed 's@^logdir.*@logdir %{_localstatedir}/log/%{name}@g' > \
+    %{buildroot}%{privoxyconf}/config
+perl -pe 's/{-no-cookies}/{-no-cookies}\n\.redhat.com/' default.action >\
+    %{buildroot}%{privoxyconf}/default.action
+
+
+# Creating ghost init files
+mkdir -p %{buildroot}/%{_sysconfdir}/rc.d/rc{0,1,2,3,4,5,6}.d
+for i in 0 1 4 6
+do
+ln -sf ../init.d/%{name} %{buildroot}/%{_sysconfdir}/rc.d/rc${i}.d/K09%{name}
+done
+for i in 2 3 5
+do
+ln -sf ../init.d/%{name} %{buildroot}/%{_sysconfdir}/rc.d/rc${i}.d/S84%{name}
+done
+
+## Macros are expanded even on commentaries. So, we have to use %%
+## -- morcego
+#%%makeinstall
+
+%pre
+# This is where we handle old usernames (junkbust and junkbuster)
+# I'm not sure we should do that, but this is the way we have been
+# doing it for some time now -- morcego
+# We should do it for the group as well -- morcego
+# Doing it by brute force. Much cleaner (no more Mr. Nice Guy) -- morcego
+
+# Change the group name. Remove anything left behind.
+groupmod -g %{privoxy_gid} -n %{name} %{oldname} > /dev/null 2>&1 ||:
+groupmod -g %{privoxy_gid} -n %{name} %{veryoldname} > /dev/null 2>&1 ||:
+groupdel %{oldname} > /dev/null 2>&1 ||:
+groupdel %{veryoldname} > /dev/null 2>&1 ||:
+
+# Same for username
+usermod -u %{privoxy_uid} -g %{privoxy_gid} -l %{name} -d %{_sysconfdir}/%{name} -s "" %{oldname} > /dev/null 2>&1 || :
+usermod -u %{privoxy_uid} -g %{privoxy_gid} -l %{name} -d %{_sysconfdir}/%{name} -s "" %{veryoldname} > /dev/null 2>&1 || :
+userdel %{oldname} > /dev/null 2>&1 ||:
+userdel %{veryoldname} > /dev/null 2>&1 ||:
+
+# Doublecheck to see if the group exist, and that it has the correct gid
+/bin/grep -E '^%{name}:' /etc/group > /dev/null 2>&1
+if [ $? -eq 1 ]; then
+       # Looks like it does not exist. Create it
+       groupadd -g %{privoxy_gid} %{name} > /dev/null 2>&1
+else
+       /bin/grep -E '^%{name}:[^:]*:%{privoxy_gid}:' /etc/group > /dev/null 2>&1
+       if [ $? -eq 1 ]; then
+               # The group exists, but does not have the correct gid
+               groupmod -g %{privoxy_gid} %{name} > /dev/null 2>&1
+       fi
+fi
+
+# Check to see if everything is okey. Create user if it still does not
+# exist
+id %{name} > /dev/null 2>&1
+if [ $? -eq 1 ]; then
+       /usr/sbin/useradd -u %{privoxy_uid} -g %{privoxy_gid} -d %{_sysconfdir}/%{name} -r -s "" %{name} > /dev/null 2>&1 
+fi
+
+# Double check that the group has the correct uid
+P_UID=`id -u %{name} 2>/dev/null`
+if [ $P_UID -ne %{privoxy_uid} ]; then
+       /usr/sbin/usermod -u %{privoxy_uid} %{name}
+fi
+
+# The same for the gid
+P_GID=`id -g %{name} 2>/dev/null`
+if [ $P_GID -ne %{privoxy_gid} ]; then
+       /usr/sbin/usermod -g %{privoxy_gid} %{name}
+fi
+
+%post
+# for upgrade from 2.0.x
+[ -f %{_localstatedir}/log/%{oldname}/logfile ] &&\
+ mv -f %{_localstatedir}/log/%{oldname}/logfile %{_localstatedir}/log/%{name}/logfile || /bin/true
+[ -f %{_localstatedir}/log/%{name}/%{name} ] &&\
+ mv -f %{_localstatedir}/log/%{name}/%{name} %{_localstatedir}/log/%{name}/logfile || /bin/true
+chown -R %{name}:%{name} %{_localstatedir}/log/%{name} 2>/dev/null
+chown -R %{name}:%{name} /etc/%{name} 2>/dev/null
+if [ "$1" = "1" ]; then
+       /sbin/service %{name} condrestart > /dev/null 2>&1
+fi
+
+%preun
+/sbin/service %{veryoldname} stop > /dev/null 2>&1 ||:
+/sbin/service %{oldname} stop > /dev/null 2>&1 ||:
+
+if [ "$1" = "0" ]; then
+       /sbin/service %{name} stop > /dev/null 2>&1 ||:
+       # No need to use chkconfig. The %%ghost files will handle it
+fi
+
+%postun
+#if [ "$1" -ge "1" ]; then
+#      /sbin/service %{name} condrestart > /dev/null 2>&1
+#fi
+# We only remove it we this is not an upgrade
+if [ "$1" = "0" ]; then
+       /bin/grep -E '^%{name}:' /etc/group > /dev/null && /usr/sbin/groupdel %{name} || /bin/true
+       id privoxy > /dev/null 2>&1 && /usr/sbin/userdel privoxy || /bin/true
+fi
+
+%clean
+[ "%{buildroot}" != "/" ] && rm -rf %{buildroot}
+
+%files
+%defattr(0644,root,root,0755)
+%doc README AUTHORS ChangeLog LICENSE 
+%doc doc/text/developer-manual.txt doc/text/user-manual.txt doc/text/faq.txt
+%doc doc/webserver/developer-manual
+%doc doc/webserver/user-manual
+%doc doc/webserver/faq
+%doc doc/webserver/p_doc.css doc/webserver/p_web.css doc/webserver/index.html
+%doc doc/webserver/images
+
+%dir %{privoxyconf}
+%dir %{privoxyconf}/templates
+%attr(0744,%{name},%{name}) %dir %{_localstatedir}/log/%{name}
+
+%attr(0744,%{name},%{name})%{_sbindir}/%{name}
+
+# WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING !
+# We should not use wildchars here. This could mask missing files problems
+# -- morcego
+# WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING !
+%config(noreplace) %{privoxyconf}/config
+%config %{privoxyconf}/standard.action
+%config(noreplace) %{privoxyconf}/user.action
+%config %{privoxyconf}/default.action
+%config %{privoxyconf}/default.filter
+%config %{privoxyconf}/trust
+
+# Please keep these alphabetized so its easier to find one that 
+# is not included.
+%config %{privoxyconf}/templates/blocked
+%config %{privoxyconf}/templates/cgi-error-404
+%config %{privoxyconf}/templates/cgi-error-bad-param
+%config %{privoxyconf}/templates/cgi-error-disabled
+%config %{privoxyconf}/templates/cgi-error-file
+%config %{privoxyconf}/templates/cgi-error-file-read-only
+%config %{privoxyconf}/templates/cgi-error-modified
+%config %{privoxyconf}/templates/cgi-error-parse
+%config %{privoxyconf}/templates/cgi-style.css
+%config %{privoxyconf}/templates/connect-failed
+%config %{privoxyconf}/templates/default
+%config %{privoxyconf}/templates/edit-actions-add-url-form
+%config %{privoxyconf}/templates/edit-actions-for-url
+%config %{privoxyconf}/templates/edit-actions-for-url-filter
+%config %{privoxyconf}/templates/edit-actions-list
+%config %{privoxyconf}/templates/edit-actions-list-button
+%config %{privoxyconf}/templates/edit-actions-list-section
+%config %{privoxyconf}/templates/edit-actions-list-url
+%config %{privoxyconf}/templates/edit-actions-remove-url-form
+%config %{privoxyconf}/templates/edit-actions-url-form
+%config %{privoxyconf}/templates/mod-local-help
+%config %{privoxyconf}/templates/mod-support-and-service
+%config %{privoxyconf}/templates/mod-title
+%config %{privoxyconf}/templates/mod-unstable-warning
+%config %{privoxyconf}/templates/no-such-domain
+%config %{privoxyconf}/templates/show-request
+%config %{privoxyconf}/templates/show-status
+%config %{privoxyconf}/templates/show-status-file
+%config %{privoxyconf}/templates/show-url-info
+%config %{privoxyconf}/templates/show-version
+%config %{privoxyconf}/templates/toggle
+%config %{privoxyconf}/templates/toggle-mini
+%config %{privoxyconf}/templates/untrusted
+
+%config %{_sysconfdir}/logrotate.d/%{name}
+%config %attr(0744,root,root) %{_sysconfdir}/rc.d/init.d/%{name}
+%ghost %attr(-,root,root) %{_sysconfdir}/rc.d/rc0.d/K09%{name}
+%ghost %attr(-,root,root) %{_sysconfdir}/rc.d/rc1.d/K09%{name}
+%ghost %attr(-,root,root) %{_sysconfdir}/rc.d/rc2.d/S84%{name}
+%ghost %attr(-,root,root) %{_sysconfdir}/rc.d/rc3.d/S84%{name}
+%ghost %attr(-,root,root) %{_sysconfdir}/rc.d/rc4.d/K09%{name}
+%ghost %attr(-,root,root) %{_sysconfdir}/rc.d/rc5.d/S84%{name}
+%ghost %attr(-,root,root) %{_sysconfdir}/rc.d/rc6.d/K09%{name}
+
+%{_mandir}/man1/%{name}.*
+
+%changelog
+* Fri May 24 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.15-1
+- Add another template and alphabetize these for easier tracking.
+- Add doc/images directory.
+
+* Wed May 15 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.15-1
+- Add templates/edit-actions-list-button
+
+* Fri May 03 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.15-1
+- Version bump
+- Adding noreplace for %%{privoxyconf}/config
+- Included a method to verify if the versions declared on the specfile and
+  configure.in match. Interrupt the build if they don't.
+
+* Fri Apr 26 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.14-3
+- Changing Vendor to Privoxy.Org
+
+* Tue Apr 23 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.14-2
+- Adjust for new *actions files.
+
+* Mon Apr 22 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.14-2
+- Removed the redhat hack that prevented the user and group from
+  being dealocated. That was a misundestanding of my part regarding
+  redhat policy.
+
+* Mon Apr 22 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.14-2
+- Using macros to define uid and gid values
+- Bumping release
+
+* Mon Apr 22 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.14-1
+- Changes to fixate the uid and gid values as (both) 73. This is a 
+  value we hope to standarize for all distributions. RedHat already
+  uses it, and Conectiva should start as soon as I find where the heck
+  I left my cluebat :-)
+- Only remove the user and group on uninstall if this is not redhat, once
+  redhat likes to have the values allocated even if the package is not 
+  installed
+
+* Tue Apr 16 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-6
+- Add --disable-dynamic-pcre to configure.
+
+* Wed Apr 10 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.13-5
+- Relisting template files on the %%files section
+
+* Tue Apr 09 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-4
+- Removed 'make dok'. Docs are all maintained in CVS (and tarball) now.
+
+* Mon Apr 08 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-4
+- Add templates/cgi-style.css, faq.txt, p_web.css, LICENSE
+- Remove templates/blocked-compact.
+- Add more docbook stuff to Builderquires.
+
+* Thu Mar 28 2002 Sarantis Paskalis <sarantis@cnl.di.uoa.gr>
++ privoxy-2.9.13-3
+- Include correct documentation file.
+
+* Tue Mar 26 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-3
+- Fix typo in Description.
+
+* Tue Mar 26 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.13-3
+- Added commentary asking to update the release value on the configure
+  script
+
+* Tue Mar 25 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-3
+- Added the missing edit-actions-for-url-filter to templates.
+
+* Mon Mar 25 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-2.9.13-2
+- Fixing Release number
+
+* Sun Mar 24 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-2
+- Added faq to docs.
+
+* Sun Mar 24 2002 Rodrigo Barbosa <rodrigob@suespammers.org>
++ privoxy-2.9.13-2
+- Fixed the init files entries. Now we use %%ghost
+- improved username (and groupname) handling on the %%pre section. By improved
+  I mean: we do it by brute force now. Much easier to maintain. Yeah, you
+  got it right. No more Mr. Nice Guy.
+- Removed the userdel call on %%post. No need, once it's complety handled on
+  the %%pre section
+
+* Sun Mar 24 2002 Hal Burgiss <hal@foobox.net>
++ junkbusterng-2.9.13-1
+  Added autoheader. Added autoconf to buildrequires.
+
+* Sun Mar 24 2002 Hal Burgiss <hal@foobox.net>
++ junkbusterng-2.9.13-1
+- Fixed build problems re: name conflicts with man page and logrotate.
+- Commented out rc?d/* configs for time being, which are causing a build 
+- failure. /etc/junkbuster is now /etc/privoxy. Stefan did other name 
+- changes. Fixed typo ';' should be ':' causing 'rpm -e' to fail.
+
+* Fri Mar 22 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ junkbusterng-2.9.13-1
+- References to the expression ijb where changed where possible
+- New package name: junkbusterng (all in lower case, acording to
+  the LSB recomendation)
+- Version changed to: 2.9.13
+- Release: 1
+- Added: junkbuster to obsoletes and conflicts (Not sure this is
+  right. If it obsoletes, why conflict ? Have to check it later)
+- Summary changed: Stefan, please check and aprove it
+- Changes description to use the new name
+- Sed string was NOT changed. Have to wait to the manpage to
+  change first
+- Keeping the user junkbuster for now. It will require some aditional
+  changes on the script (scheduled for the next specfile release)
+- Added post entry to move the old logfile to the new log directory
+- Removing "chkconfig --add" entry (not good to have it automaticaly
+  added to the startup list).
+- Added preun section to stop the service with the old name, as well
+  as remove it from the startup list
+- Removed the chkconfig --del entry from the conditional block on
+  the preun scriptlet (now handled on the %files section)
+
+* Thu Mar 21 2002 Hal Burgiss <hal@foobox.net>
+- added ijb_docs.css to docs.
+
+* Mon Mar 11 2002 Hal Burgiss <hal@foobox.net>
++ junkbuster-2.9.11-8 
+- Take out --enable-no-gifs, breaks some browsers.
+
+* Sun Mar 10 2002 Hal Burgiss <hal@foobox.net>
++ junkbuster-2.9.11-8 
+- Add --enable-no-gifs to configure.
+
+* Fri Mar 08 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ junkbuster-2.9.11-7
+- Added BuildRequires to libtool.
+
+* Tue Mar 06 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ junkbuster-2.9.11-6
+- Changed the routined that handle the junkbust and junkbuster users on
+  %%pre and %%post to work in a smoother manner
+- %%files now uses hardcoded usernames, to avoid problems with package
+  name changes in the future
+
+* Tue Mar 05 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ junkbuster-2.9.11-5
+- Added "make redhat-dok" to the build process
+- Added docbook-utils to BuildRequires
+
+* Tue Mar 05 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ junkbuster-2.9.11-4
+- Changing man section in the manpage from 1 to 8
+- We now require packages, not files, to avoid issues with apt
+
+* Mon Mar 04 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ junkbuster-2.9.11-3
+- Fixing permissions of the init script
+
+* Mon Mar 04 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ junkbuster-2.9.11-2
+- General specfile fixup, using the best recomended practices, including:
+       - Adding -q to %%setup
+       - Using macros whereever possible
+       - Not using wildchars on %%files section
+       - Doubling the percentage char on changelog and comments, to
+         avoid rpm expanding them
+
+* Sun Mar 03 2002 Hal Burgiss <hal@foobox.net>
+- /bin/false for shell causes init script to fail. Reverting.
+
+* Wed Jan 09 2002 Hal Burgiss <hal@foobox.net>
+- Removed UID 73. Included user-manual and developer-manual in docs.
+  Include other actions files. Default shell is now /bin/false.
+  Userdel user=junkbust. ChangeLog was not zipped. Removed 
+  RPM_OPT_FLAGS kludge.
+
+* Fri Dec 28 2001 Thomas Steudten <thomas@steudten.ch>
+- add paranoia check for 'rm -rf %%{buildroot}'
+- add gzip to 'BuildRequires'
+
+* Sat Dec  1 2001 Hal Burgiss <hal@foobox.net>
+- actionsfile is now ijb.action.
+
+* Tue Nov  6 2001 Thomas Steudten <thomas@steudten.ch>
+- Compress manpage
+- Add more documents for installation
+- Add version string to name and source
+
+* Wed Oct 24 2001 Hal Burigss <hal@foobox.net>
+- Back to user 'junkbuster' and fix configure macro.
+
+* Wed Oct 10 2001 Hal Burigss <hal@foobox.net>
+- More changes for user 'junkbust'. Init script had 'junkbuster'.
+
+* Sun Sep 23 2001 Hal Burgiss <hal@foobox.net>
+- Change of $RPM_OPT_FLAGS handling. Added new HTML doc files.
+- Changed owner of /etc/junkbuster to shut up PAM/xauth log noise.
+
+* Thu Sep 13 2001 Hal Burgiss <hal@foobox.net>
+- Added $RPM_OPT_FLAGS support, renaming of old logfile, and 
+- made sure no default shell exists for user junkbust.
+
+* Sun Jun  3 2001 Stefan Waldherr <stefan@waldherr.org>
+- rework of RPM
+
+* Mon Sep 25 2000 Stefan Waldherr <stefan@waldherr.org>
+- CLF Logging patch by davep@cyw.uklinux.net
+- Hal DeVore <haldevore@earthling.net> fix akamaitech in blocklist
+
+* Sun Sep 17 2000 Stefan Waldherr <stefan@waldherr.org>
+- Steve Kemp skx@tardis.ed.ac.uk's javascript popup patch.
+- Markus Breitenbach breitenb@rbg.informatik.tu-darmstadt.de supplied
+  numerous fixes and enhancements for Steve's patch.
+- adamlock@netscape.com (Adam Lock) in the windows version:
+  - Taskbar activity spinner always spins even when logging is
+  turned off (which is the default) - people who don't
+  like the spinner can turn it off from a menu option.
+  - Taskbar popup menu has a options submenu - people can now
+  open the settings files for cookies, blockers etc.
+  without opening the JB window.
+  - Logging functionality works again
+  - Buffer overflow is fixed - new code uses a bigger buffer
+  and snprintf so it shouldn't overflow anymore.
+- Fixed userid swa, group learning problem while installing.
+  root must build RPM.
+- Added patch by Benjamin Low <ben@snrc.uow.edu.au> that prevents JB to
+  core dump when there is no log file.
+- Tweaked SuSE startup with the help of mohataj@gmx.net and Doc.B@gmx.de.
+- Fixed man page to include imagefile and popupfile.
+- Sanity check for the statistics function added.
+- "Patrick D'Cruze" <pdcruze@orac.iinet.net.au>: It seems Microsoft
+ are transitioning Hotmail from FreeBSD/Apache to Windows 2000/IIS.
+ With IIS/5, it appears to omit the trailing \r\n from http header
+ only messages.  eg, when I visit http://www.hotmail.com, IIS/5
+ responds with a HTTP 302 redirect header.  However, this header
+ message is missing the trailing \r\n.  IIS/5 then closes the
+ connection.  Junkbuster, unfortunately, discards the header becomes
+ it thinks it is incomplete - and it is.  MS have transmitted an
+ incomplete header!
+- Added bug reports and patch submission forms in the docs.
+
+* Mon Mar 20 2000 Stefan Waldherr <stefan@waldherr.org>
+       Andrew <anw@tirana.freewire.co.uk> extended the JB:
+       Display of statistics of the total number of requests and the number
+       of requests filtered by junkbuster, also the percentage of requests
+       filtered. Suppression of the listing of files on the proxy-args page.
+       All stuff optional and configurable.
+
+* Sun Sep 12 1999 Stefan Waldherr <stefan@waldherr.org>
+       Jan Willamowius (jan@janhh.shnet.org) fixed a bug in the 
+       code which prevented the JB from handling URLs of the form
+       user:password@www.foo.com. Fixed.
+
+* Mon Aug  2 1999 Stefan Waldherr <stefan@waldherr.org>
+       Blank images are no longer cached, thanks to a hint from Markus 
+        Breitenbach <breitenb@rbg.informatik.tu-darmstadt.de>. The user 
+        agent is NO longer set by the Junkbuster. Sadly, many sites depend 
+        on the correct browser version nowadays. Incorporated many 
+       suggestions from Jan "Yenya" Kasprzak <kas@fi.muni.cz> for the
+        spec file. Fixed logging problem and since runlevel 2 does not 
+        use networking, I replaced /etc/rc.d/rc2.d/S84junkbuster with
+        /etc/rc.d/rc2.d/K09junkbuster thanks to Shaw Walker 
+        <walker@netgate.net>. You should now be able to build this RPM as 
+        a non-root user (mathias@weidner.sem.lipsia.de).
+
+* Sun Jan 31 1999 Stefan Waldherr <stefan@waldherr.org>
+       %%{_localstatedir}/log/junkbuster set to nobody. Added /etc/junkbuster/imagelist
+       to allow more sophisticated matching of blocked images. Logrotate
+       logfile. Added files for auto-updating the blocklist et al.
+
+* Wed Dec 16 1998 Stefan Waldherr <stefan@waldherr.org>
+       Configure blank version via config file. No separate blank
+       version anymore. Added Roland's <roland@spinnaker.rhein.de>
+       patch to show a logo instead of a blank area. Added a suggestion
+       from Alex <alex@cocoa.demon.co.uk>: %%{_localstatedir}/lock/subsys/junkbuster.
+       More regexps in the blocklist. Prepared the forwardfile for
+       squid. Extended image regexp with help from gabriel 
+       <somlo@CS.ColoState.EDU>.
+
+* Thu Nov 19 1998 Stefan Waldherr <stefan@waldherr.org>
+       All RPMs now identify themselves in the show-proxy-args page.
+       Released Windoze version. Run junkbuster as nobody instead of
+       root. 
+
+* Fri Oct 30 1998 Stefan Waldherr <stefan@waldherr.org>
+       Newest version. First release (hence the little version number
+       mixture -- 2.0.2-0 instead of 2.0-7). This version tightens 
+       security over 2.0.1; some multi-user sites will need to change 
+       the listen-address in the configuration file. The blank version of
+        the Internet Junkbuster has a more sophisticated way of replacing
+       images. All RPMs identify themselves in the show-proxy-args page.
+
+* Thu Sep 23 1998 Stefan Waldherr <stefan@waldherr.org>
+       Modified the blocking feature, so that only GIFs and JPEGs are
+       blocked and replaced but not HTML pages. Thanks to 
+       "Gerd Flender" <plgerd@informatik.uni-siegen.de> for this nice
+       idea. Added numerous stuff to the blocklist. Keep patches in
+        seperate files and no longer in diffs (easier to maintain).
+
+* Tue Jun 16 1998 Stefan Waldherr <swa@cs.cmu.edu>
+        Moved config files to /etc/junkbuster directory, moved man page,
+       added BuildRoot directive (Thanks to Alexey Nogin <ayn2@cornell.edu>)
+        Made new version junkbuster-raw (which is only a stripped version of 
+        the junkuster rpm, i.e. without my blocklist, etc.)
+
+* Tue Jun 16 1998 (2.0-1)
+       Uhm, not that much. Just a new junkbuster version that
+       fixes a couple of bugs ... and of course a bigger 
+       blocklist with the unique Now-less-ads-than-ever(SM)
+       feature.
+       Oh, one thing: I changed the default user agent to Linux -- no 
+       need anymore to support Apple.
+
+* Tue Jun 16 1998 (2.0-0)
+       Now-less-ads-than-ever (SM)
+       compiled with gcc instead of cc
+       compiled with -O3, thus it should be a little faster
+       show-proxy-args now works
+       /etc/junkbuster.init wasn't necessary
+
+* Tue Jun 16 1998 (1.4)
+       some more config files were put into /etc
+       The junkbuster-blank rpm returns a 1x1 pixel image, that gets 
+       displayed by Netscape instead of the blocked image.
+       Read http://www.waldherr.org/junkbuster/ for
+       further info.
+
+* Tue Jun 16 1998 (1.3)
+       The program has been moved to /usr/sbin (from /usr/local/bin)
+       Init- and stopscripts (/etc/rc.d/rc*) have been added so
+       that the junkbuster starts automatically during bootup.
+       The /etc/blocklist file is much more sophisticated. Theoretically
+       one should e.g. browse all major US and German newspapers without
+       seeing one annoying ad.
+       junkbuster.init was modified. It now starts junkbuster with an
+       additional "-r @" flag.
+
+# $Log: privoxy-rh.spec,v $
+# Revision 1.32  2002/05/16 01:37:29  hal9
+# Add new template file so CGI stuff works :)
+#
+# Revision 1.31  2002/05/03 17:14:35  morcego
+# *.spec: Version bump to 2.9.15
+# -rh.spec: noreplace for %%{privoxyconf}/config
+#           Will interrupt the build if versions from configure.in and
+#              specfile do not match
+#
+# Revision 1.30  2002/04/26 15:51:05  morcego
+# Changing Vendor value to Privoxy.Org
+#
+# Revision 1.29  2002/04/24 03:13:51  hal9
+# New actions files changes.
+#
+# Revision 1.28  2002/04/22 18:51:33  morcego
+# user and group now get removed on rh too.
+#
+# Revision 1.27  2002/04/22 16:32:31  morcego
+# configure.in, *.spec: Bumping release to 2 (2.9.14-2)
+# -rh.spec: uid and gid are now macros
+# -suse.spec: Changing the header Copyright to License (Copyright is
+#             deprecable)
+#
+# Revision 1.26  2002/04/22 16:24:36  morcego
+# - Changes to fixate the uid and gid values as (both) 73. This is a
+#   value we hope to standarize for all distributions. RedHat already
+#   uses it, and Conectiva should start as soon as I find where the heck
+#   I left my cluebat :-)
+# - Only remove the user and group on uninstall if this is not redhat, once
+#   redhat likes to have the values allocated even if the package is not
+#   installed
+#
+# Revision 1.25  2002/04/17 01:59:12  hal9
+# Add --disable-dynamic-pcre.
+#
+# Revision 1.24  2002/04/11 10:09:20  oes
+# Version 2.9.14
+#
+# Revision 1.23  2002/04/10 18:14:45  morcego
+# - (privoxy-rh.spec only) Relisting template files on the %%files section
+# - (configure.in, privoxy-rh.spec) Bumped package release to 5
+#
+# Revision 1.22  2002/04/09 22:06:12  hal9
+# Remove 'make dok'.
+#
+# Revision 1.21  2002/04/09 02:52:26  hal9
+# - Add templates/cgi-style.css, faq.txt, p_web.css, LICENSE
+# - Remove templates/blocked-compact.
+# - Add more docbook stuff to Buildrequires.
+#
+# Revision 1.20  2002/04/08 20:27:45  swa
+# fixed JB spelling
+#
+# Revision 1.19  2002/03/27 22:44:59  sarantis
+# Include correct documentation file.
+#
+# Revision 1.18  2002/03/27 22:10:14  sarantis
+# bumped Hal's last commit 1 day to the future to make rpm build again.
+#
+# Revision 1.17  2002/03/27 00:48:23  hal9
+# Fix up descrition.
+#
+# Revision 1.16  2002/03/26 22:29:55  swa
+# we have a new homepage!
+#
+# Revision 1.15  2002/03/26 17:39:54  morcego
+# Adding comment on the specfile to remember the packager to update
+# the release number on the configure script
+#
+# Revision 1.14  2002/03/26 14:25:15  hal9
+# Added edit-actions-for-url-filter to templates in %%config
+#
+# Revision 1.13  2002/03/25 13:31:04  morcego
+# Bumping Release tag.
+#
+# Revision 1.12  2002/03/25 03:11:40  hal9
+# Do it right way this time :/
+#
+# Revision 1.11  2002/03/25 03:09:51  hal9
+# Added faq to docs.
+#
+# Revision 1.10  2002/03/24 22:16:14  morcego
+# Just removing some old commentaries.
+#
+# Revision 1.9  2002/03/24 22:03:22  morcego
+# Should be working now. See %changelog for details
+#
+# Revision 1.8  2002/03/24 21:13:01  morcego
+# Tis broken.
+#
+# Revision 1.7  2002/03/24 21:07:18  hal9
+# Add autoheader, etc.
+#
+# Revision 1.6  2002/03/24 19:56:40  hal9
+# /etc/junkbuster is now /etc/privoxy. Fixed ';' typo.
+#
+# Revision 1.4  2002/03/24 13:32:42  swa
+# name change related issues
+#
+# Revision 1.3  2002/03/24 12:56:21  swa
+# name change related issues.
+#
+# Revision 1.2  2002/03/24 11:40:14  swa
+# name change
+#
+# Revision 1.1  2002/03/24 11:23:44  swa
+# name change
+#
+# Revision 1.1  2002/03/22 20:53:03  morcego
+# - Ongoing process to change name to JunkbusterNG
+# - configure/configure.in: no change needed
+# - GNUmakefile.in:
+#         - TAR_ARCH = /tmp/JunkbusterNG-$(RPM_VERSION).tar.gz
+#         - PROGRAM    = jbng@EXEEXT@
+#         - rh-spec now references as junkbusterng-rh.spec
+#         - redhat-upload: references changed to junkbusterng-* (package names)
+#         - tarball-dist: references changed to JunkbusterNG-distribution-*
+#         - tarball-src: now JunkbusterNG-*
+#         - install: initscript now junkbusterng.init and junkbusterng (when
+#                    installed)
+# - junkbuster-rh.spec: renamed to junkbusterng-rh.spec
+# - junkbusterng.spec:
+#         - References to the expression ijb where changed where possible
+#         - New package name: junkbusterng (all in lower case, acording to
+#           the LSB recomendation)
+#         - Version changed to: 2.9.13
+#         - Release: 1
+#         - Added: junkbuster to obsoletes and conflicts (Not sure this is
+#           right. If it obsoletes, why conflict ? Have to check it later)
+#         - Summary changed: Stefan, please check and aprove it
+#         - Changes description to use the new name
+#         - Sed string was NOT changed. Have to wait to the manpage to
+#           change first
+#         - Keeping the user junkbuster for now. It will require some aditional
+#           changes on the script (scheduled for the next specfile release)
+#         - Added post entry to move the old logfile to the new log directory
+#         - Removing "chkconfig --add" entry (not good to have it automaticaly
+#           added to the startup list).
+#         - Added preun section to stop the service with the old name, as well
+#           as remove it from the startup list
+#         - Removed the chkconfig --del entry from the conditional block on
+#           the preun scriptlet (now handled on the %files section)
+# - junkbuster.init: renamed to junkbusterng.init
+# - junkbusterng.init:
+#         - Changed JB_BIN to jbng
+#         - Created JB_OBIN with the old value of JB_BIN (junkbuster), to
+#           be used where necessary (config dir)
+#
+# Aditional notes:
+# - The config directory is /etc/junkbuster yet. Have to change it on the
+# specfile, after it is changes on the code
+# - The only files that got renamed on the cvs tree were the rh specfile and
+# the init file. Some file references got changes on the makefile and on the
+# rh-spec (as listed above)
+#
+# Revision 1.43  2002/03/21 16:04:10  hal9
+# added ijb_docs.css to %doc
+#
+# Revision 1.42  2002/03/12 13:41:18  sarantis
+# remove hard-coded "ijbswa" string in build phase
+#
+# Revision 1.41  2002/03/11 22:58:32  hal9
+# Remove --enable-no-gifs
+#
+# Revision 1.39  2002/03/08 18:57:29  swa
+# remove user junkbuster after de-installation.
+#
+# Revision 1.38  2002/03/08 13:45:27  morcego
+# Adding libtool to Buildrequires
+#
+# Revision 1.37  2002/03/07 19:23:49  swa
+# i hate to scroll. suse: wrong configdir.
+#
+# Revision 1.36  2002/03/07 05:06:54  morcego
+# Fixed %pre scriptlet. And, as a bonus, you can even understand it now. :-)
+#
+# Revision 1.34  2002/03/07 00:11:57  morcego
+# Few changes on the %pre and %post sections of the rh specfile to handle
+# usernames more cleanly
+#
+# Revision 1.33  2002/03/05 13:13:57  morcego
+# - Added "make redhat-dok" to the build phase
+# - Added docbook-utils to BuildRequires
+#
+# Revision 1.32  2002/03/05 12:34:24  morcego
+# - Changing section internaly on the manpage from 1 to 8
+# - We now require packages, not files, to avoid issues with apt
+#
+# Revision 1.31  2002/03/04 18:06:09  morcego
+# SPECFILE: fixing permissing of the init script (broken by the last change)
+#
+# Revision 1.30  2002/03/04 16:18:03  morcego
+# General cleanup of the rh specfile.
+#
+# %changelog
+# * Mon Mar 04 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
+# + junkbuster-2.9.11-2
+# - General specfile fixup, using the best recomended practices, including:
+#         - Adding -q to %%setup
+#         - Using macros whereever possible
+#         - Not using wildchars on %%files section
+#         - Doubling the percentage char on changelog and comments, to
+#           avoid rpm expanding them
+#
+# Revision 1.29  2002/03/03 19:21:22  hal9
+# Init script fails if shell is /bin/false.
+#
+# Revision 1.28  2002/01/09 18:34:03  hal9
+# nit.
+#
+# Revision 1.27  2002/01/09 18:32:02  hal9
+# Removed RPM_OPT_FLAGS kludge.
+#
+# Revision 1.26  2002/01/09 18:21:10  hal9
+# A few minor updates.
+#
+# Revision 1.25  2001/12/28 01:45:36  steudten
+# Add paranoia check and BuildReq: gzip
+#
+# Revision 1.24  2001/12/01 21:43:14  hal9
+# Allowed for new ijb.action file.
+#
+# Revision 1.23  2001/11/06 12:09:03  steudten
+# Compress doc files. Install README and AUTHORS at last as document.
+#
+# Revision 1.22  2001/11/05 21:37:34  steudten
+# Fix to include the actual version for name.
+# Let the 'real' packager be included - sorry stefan.
+#
+# Revision 1.21  2001/10/31 19:27:27  swa
+# consistent description. new name for suse since
+# we had troubles with rpms of identical names
+# on the webserver.
+#
+# Revision 1.20  2001/10/24 15:45:49  hal9
+# To keep Thomas happy (aka correcting my  mistakes)
+#
+# Revision 1.19  2001/10/15 03:23:59  hal9
+# Nits.
+#
+# Revision 1.17  2001/10/10 18:59:28  hal9
+# Minor change for init script.
+#
+# Revision 1.16  2001/09/24 20:56:23  hal9
+# Minor changes.
+#
+# Revision 1.13  2001/09/10 17:44:43  swa
+# integrate three pieces of documentation. needs work.
+# will not build cleanly under redhat.
+#
+# Revision 1.12  2001/09/10 16:25:04  swa
+# copy all templates. version updated.
+#
+# Revision 1.11  2001/07/03 11:00:25  sarantis
+# replaced permissionsfile with actionsfile
+#
+# Revision 1.10  2001/07/03 09:34:44  sarantis
+# bumped up version number.
+#
+# Revision 1.9  2001/06/12 18:15:29  swa
+# the %% in front of configure (see tag below) confused
+# the rpm build process on 7.1.
+#
+# Revision 1.8  2001/06/12 17:15:56  swa
+# fixes, because a clean build on rh6.1 was impossible.
+# GZIP confuses make, %% configure confuses rpm, etc.
+#
+# Revision 1.7  2001/06/11 12:17:26  sarantis
+# fix typo in %%post
+#
+# Revision 1.6  2001/06/11 11:28:25  sarantis
+# Further optimizations and adaptations in the spec file.
+#
+# Revision 1.5  2001/06/09 09:14:11  swa
+# shamelessly adapted RPM stuff from the newest rpm that
+# RedHat provided for the JB.
+#
+# Revision 1.4  2001/06/08 20:54:18  swa
+# type with status file. remove forward et. al from file list.
+#
+# Revision 1.3  2001/06/07 17:28:10  swa
+# cosmetics
+#
+# Revision 1.2  2001/06/04 18:31:58  swa
+# files are now prefixed with either `confdir' or `logdir'.
+# `make redhat-dist' replaces both entries confdir and logdir
+# with redhat values
+#
+# Revision 1.1  2001/06/04 10:44:57  swa
+# `make redhatr-dist' now works. Except for the paths
+# in the config file.
+#
+#
+#
diff --git a/privoxy-suse.spec b/privoxy-suse.spec
new file mode 100644 (file)
index 0000000..cca70d0
--- /dev/null
@@ -0,0 +1,456 @@
+# $Id: privoxy-suse.spec,v 1.19 2002/05/03 17:14:36 morcego Exp $
+#
+# Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Based on the Internet Junkbuster originally written
+# by and Copyright (C) 1997 Anonymous Coders and 
+# Junkbusters Corporation.  http://www.junkbusters.com
+#
+# This program is free software; you can redistribute it 
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.  See the GNU General Public 
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file.  If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+# do not set to %{name}
+%define privoxyconf %{_sysconfdir}/privoxy
+%define privoxy_uid 73
+%define privoxy_gid 73
+
+
+Summary:      Privoxy - privacy enhancing proxy
+Vendor:       Privoxy.Org
+Name:         privoxy-suse
+Distribution: defineme
+Version: 2.9.15
+Release: 1
+# Needs makefile change: Source: http://prdownloads.sourceforge.net/ijbswa/privoxy-%{version}-%{status}-src.tar.gz
+Source: http://prdownloads.sourceforge.net/ijbswa/privoxy-%{version}.tar.gz
+# not sure if this works
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+Packager:     Stefan Waldherr <stefan@waldherr.org>
+License:     GPL
+Group:        Networking/Utilities
+URL:          http://www.privoxy.org/
+Autoreqprov:  on
+BuildRequires: perl gzip libtool autoconf
+Conflicts: junkbuster-raw junkbuster-blank junkbuster-suse junkbuster privoxy
+
+#
+# -----------------------------------------------------------------------------
+#
+%description
+Privoxy is a web proxy with advanced filtering capabilities for
+protecting privacy, filtering web page content, managing cookies,
+controlling access, and removing ads, banners, pop-ups and other
+obnoxious Internet junk. Privoxy has a very flexible configuration and
+can be customized to suit individual needs and tastes. Privoxy has 
+application for both stand-alone systems and multi-user networks.
+
+Privoxy is based on the  Internet Junkbuster.
+
+Authors:
+--------
+    http://www.privoxy.org/
+
+SuSE series: n
+
+#
+# -----------------------------------------------------------------------------
+#
+%prep
+%setup -c
+
+#
+# -----------------------------------------------------------------------------
+#
+%build
+autoheader
+autoconf
+./configure --disable-dynamic-pcre
+make
+
+
+## Explicitily stripping is not recomended.
+## This is handled altomaticaly by RPM, and can couse troubles if
+## anyone wants to build an unstriped version - morcego
+#strip privoxy
+
+#
+# -----------------------------------------------------------------------------
+#
+%install
+[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+mkdir -p ${RPM_BUILD_ROOT}%{_sbindir} \
+         ${RPM_BUILD_ROOT}%{_mandir}/man8 \
+         ${RPM_BUILD_ROOT}/var/log/privoxy \
+         ${RPM_BUILD_ROOT}%{privoxyconf}/templates \
+         ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d \
+         ${RPM_BUILD_ROOT}%{_sysconfdir}/init.d
+gzip README AUTHORS ChangeLog privoxy.1 LICENSE || /bin/true
+install -s -m 744 privoxy $RPM_BUILD_ROOT%{_sbindir}/privoxy
+cp -f privoxy.1.gz $RPM_BUILD_ROOT%{_mandir}/man8/privoxy.8.gz
+cp -f *.action $RPM_BUILD_ROOT%{privoxyconf}/
+cp -f default.filter $RPM_BUILD_ROOT%{privoxyconf}/default.filter
+cp -f trust $RPM_BUILD_ROOT%{privoxyconf}/trust
+cp -f templates/*  $RPM_BUILD_ROOT%{privoxyconf}/templates/
+cp -f privoxy.logrotate $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/privoxy
+install -m 755 privoxy.init.suse $RPM_BUILD_ROOT%{_sysconfdir}/init.d/privoxy
+install -m 711 -d $RPM_BUILD_ROOT/var/log/privoxy
+ln -sf /etc/init.d/privoxy $RPM_BUILD_ROOT/usr/sbin/rcprivoxy
+
+# verify all file locations, etc. in the config file
+# don't start with ^ or commented lines are not replaced
+cat config | \
+    sed 's/^confdir.*/confdir \/etc\/privoxy/g' | \
+#    sed 's/^permissionsfile.*/permissionsfile \/etc\/privoxy\/permissionsfile/g' | \
+#    sed 's/^filterfile.*/default.filter \/etc\/privoxy\/default.filter/g' | \
+#    sed 's/^logfile.*/logfile \/var\/log\/privoxy\/logfile/g' | \
+#    sed 's/^jarfile.*/jarfile \/var\/log\/privoxy\/jarfile/g' | \
+#    sed 's/^forward.*/forward \/etc\/privoxy\/forward/g' | \
+#    sed 's/^aclfile.*/aclfile \/etc\/privoxy\/aclfile/g' > \
+    sed 's/^logdir.*/logdir \/var\/log\/privoxy/g' > \
+    $RPM_BUILD_ROOT%{privoxyconf}/config
+
+#
+# -----------------------------------------------------------------------------
+#
+%pre
+# We check to see if the user privoxy exists.
+# If it does, we do nothing
+# If we don't, we check to see if the user junkbust exist and, in case it
+# does, we change it do privoxy. If it also does not exist, we create the
+# privoxy user -- morcego
+id privoxy > /dev/null 2>&1 
+if [ $? -eq 1 ]; then
+       id junkbust > /dev/null 2>&1 
+       if [ $? -eq 0 ]; then
+               /usr/sbin/usermod -u %{privoxy_uid} -g %{privoxy_gid} -l privoxy -d %{_sysconfdir}/privoxy -s "" junkbust  > /dev/null 2>&1
+       else
+# -r does not work on suse.
+               /usr/sbin/groupadd -g %{privoxy_gid} privoxy
+               /usr/sbin/useradd -u %{privoxy_uid} -d %{_sysconfdir}/privoxy -g privoxy -s "" privoxy > /dev/null 2>&1 
+       fi
+fi
+
+#
+# -----------------------------------------------------------------------------
+#
+%post
+[ -f /var/log/privoxy/privoxy ] &&\
+ mv -f /var/log/privoxy/privoxy /var/log/privoxy/logfile || /bin/true
+chown -R privoxy:privoxy /var/log/privoxy 2>/dev/null
+chown -R privoxy:privoxy /etc/privoxy 2>/dev/null
+# not available on suse
+#if [ "$1" = "1" ]; then
+#     /sbin/chkconfig --add privoxy
+#      /sbin/service privoxy condrestart > /dev/null 2>&1
+#fi
+# 01/09/02 HB, getting rid of any user=junkbust
+# Changed by morcego to use the id command.
+id junkbust > /dev/null 2>&1 && /usr/sbin/userdel junkbust || /bin/true
+sbin/insserv etc/init.d/privoxy
+
+#
+# -----------------------------------------------------------------------------
+#
+%preun
+# need to stop the service on suse. swa.
+#if [ "$1" = "0" ]; then
+#      /sbin/service privoxy stop > /dev/null 2>&1 ||:
+#fi
+
+#
+# -----------------------------------------------------------------------------
+#
+%postun
+sbin/insserv etc/init.d/
+# dont forget to remove user and group privoxy
+id privoxy > /dev/null 2>&1 && /usr/sbin/userdel privoxy || /bin/true
+
+#
+# -----------------------------------------------------------------------------
+#
+%clean
+[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+
+#
+# -----------------------------------------------------------------------------
+#
+%files
+%defattr(-,root,root)
+%doc README.gz AUTHORS.gz ChangeLog.gz LICENSE.gz
+%doc doc/webserver/developer-manual
+%doc doc/webserver/user-manual
+%doc doc/webserver/faq
+%doc doc/webserver/p_doc.css
+%doc doc/webserver/p_web.css
+%doc doc/webserver/index.html
+%doc doc/webserver/images
+#%doc privoxy.weekly privoxy.monthly AUTHORS
+%dir %{privoxyconf}
+%config %{privoxyconf}/*
+%attr(0744,privoxy,privoxy) %dir /var/log/privoxy
+%config %{_sysconfdir}/logrotate.d/privoxy
+%attr(0755,root,root)/usr/sbin/privoxy
+%{_mandir}/man8/*
+%config %{_sysconfdir}/init.d/privoxy
+/usr/sbin/rcprivoxy
+
+#
+# -----------------------------------------------------------------------------
+#
+%changelog
+* Fri May 24 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.15-1
+- Add doc/images directory.
+
+* Fri May 03 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-suse-2.9.15-1
+- Version bump
+
+* Fri Apr 26 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-suse-2.9.14-3
+- Changing Vendor to Privoxy.Org
+
+* Mon Apr 22 2002 Rodrigo Barbosa <rodrigob@tisbrasil.com.br>
++ privoxy-suse-2.9.14-2
+- Bumping release to reflect the new value on configure.in
+- Taking the oportunity to change the header Copyright to License. The
+  Copyright headers is deprecated, and after all, GPL is a license, not a
+  Copyright
+
+* Mon Apr 08 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-4
+- Add LICENSE.gz, p_web.css, and index.html. Add autoconf
+- to Buildrequires.
+
+* Wed Mar 27 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-3
+- Doc css has changed names.
+
+* Tue Mar 25 2002 Hal Burgiss <hal@foobox.net>
++ privoxy-2.9.13-3
+- Minor fix to description.
+
+* Sun Mar 24 2002 Hal Burgiss <hal@foobox.net>
+- added faq to docs.
+
+* Thu Mar 21 2002 Hal Burgiss <hal@foobox.net>
+- added ijb_docs.css to docs.
+
+* Mon Mar 11 2002 Hal Burgiss <hal@foobox.net>
+- Remove --enable-no-gifs from configure.
+
+* Sun Mar 03 2002 Hal Burgiss <hal@foobox.net>
+- /bin/false for shell causes init script to fail. Reverting.
+
+* Wed Jan 09 2002 Hal Burgiss <hal@foobox.net>
+- Removed UID 73. Included user-manual and developer-manual in docs.
+  Include other actions files. Default shell is now /bin/false.
+  Userdel user=junkbust. ChangeLog was not zipped. Removed
+  RPM_OPT_FLAGS kludge.
+
+* Fri Dec 28 2001 Thomas Steudten <thomas@steudten.ch>
+- add paranoia check for 'rm -rf $RPM_BUILD_ROOT'
+- add gzip to 'BuildRequires'
+
+* Sat Dec  1 2001 Hal Burgiss <hal@foobox.net>
+- actionsfile is now ijb.action.
+
+* Tue Nov  6 2001 Thomas Steudten <thomas@steudten.ch>
+- Compress manpage
+- Add more documents for installation
+- Add version string to name and source
+
+* Wed Oct 24 2001 Hal Burigss <hal@foobox.net>
+- Back to user 'junkbuster' and fix configure macro.
+
+* Wed Oct 10 2001 Hal Burigss <hal@foobox.net>
+- More changes for user 'junkbust'. Init script had 'junkbuster'.
+
+* Sun Sep 23 2001 Hal Burgiss <hal@foobox.net>
+- Change of $RPM_OPT_FLAGS handling. Added new HTML doc files.
+- Changed owner of /etc/junkbuster to shut up PAM/xauth log noise.
+
+* Thu Sep 13 2001 Hal Burgiss <hal@foobox.net>
+- Added $RPM_OPT_FLAGS support, renaming of old logfile, and
+- made sure no default shell exists for user junkbust.
+
+* Sun Jun  3 2001 Stefan Waldherr <stefan@waldherr.org>
+- rework of RPM
+* Wed Feb 14 2001 - uli@suse.de
+- fixed init script
+* Wed Dec 06 2000 - bjacke@suse.de
+- renamed package to junkbuster
+- fixed copyright tag
+* Thu Nov 30 2000 - uli@suse.de
+- moved init script to /etc/init.d
+* Wed Feb 16 2000 - kukuk@suse.de
+- Move /usr/man -> /usr/share/man
+- Mark /etc/ijb as "config(noreplace)"
+* Mon Sep 20 1999 - uli@suse.de
+- fixed init script
+* Mon Sep 13 1999 - bs@suse.de
+- ran old prepare_spec on spec file to switch to new prepare_spec.
+* Thu Apr 01 1999 - daniel@suse.de
+- do not start ijb as root (security)
+* Tue Mar 30 1999 - daniel@suse.de
+- don´t use saclfile.ini
+* Tue Mar 30 1999 - daniel@suse.de
+- small fix to whitelist-configuration,
+  version is and was 2.0.2 WITHOUT Stefan Waldherr's patches
+  (http://www.waldherr.org/junkbuster/)
+* Mon Mar 01 1999 - daniel@suse.de
+- new package: version 2.0
+
+# $Log: privoxy-suse.spec,v $
+# Revision 1.19  2002/05/03 17:14:36  morcego
+# *.spec: Version bump to 2.9.15
+# -rh.spec: noreplace for %%{privoxyconf}/config
+#           Will interrupt the build if versions from configure.in and
+#              specfile do not match
+#
+# Revision 1.18  2002/04/27 20:26:59  swa
+# uid, gui 73 incorporated
+#
+# Revision 1.17  2002/04/26 15:51:05  morcego
+# Changing Vendor value to Privoxy.Org
+#
+# Revision 1.16  2002/04/22 16:32:31  morcego
+# configure.in, *.spec: Bumping release to 2 (2.9.14-2)
+# -rh.spec: uid and gid are now macros
+# -suse.spec: Changing the header Copyright to License (Copyright is
+#             deprecable)
+#
+# Revision 1.15  2002/04/16 18:49:07  oes
+# Build with static built-in pcre
+#
+# Revision 1.14  2002/04/11 17:57:40  oes
+# Fixed(?) Conflicts: Provides: Obsoletes:
+#
+# Revision 1.13  2002/04/11 10:09:20  oes
+# Version 2.9.14
+#
+# Revision 1.12  2002/04/09 13:29:43  swa
+# build suse and gen-dist with html docs. do not generate docs while building rpm
+#
+# Revision 1.11  2002/04/09 03:12:37  hal9
+# Add LICENSE, p_web.css and index.html. Add autoconf to buildrequires.
+#
+# Revision 1.10  2002/04/08 20:24:13  swa
+# fixed JB spelling
+#
+# Revision 1.9  2002/03/30 09:01:52  swa
+# new release
+#
+# Revision 1.8  2002/03/27 23:46:41  hal9
+# ijb_docs.css to p_doc.css
+#
+# Revision 1.7  2002/03/27 00:49:39  hal9
+# Minor fix to description.
+#
+# Revision 1.6  2002/03/26 22:29:55  swa
+# we have a new homepage!
+#
+# Revision 1.5  2002/03/25 03:10:50  hal9
+# Added faq to docs.
+#
+# Revision 1.4  2002/03/24 12:56:21  swa
+# name change related issues.
+#
+# Revision 1.3  2002/03/24 12:44:31  swa
+# new version string
+#
+# Revision 1.2  2002/03/24 11:40:14  swa
+# name change
+#
+# Revision 1.1  2002/03/24 11:23:44  swa
+# name change
+#
+# Revision 1.21  2002/03/21 16:04:33  hal9
+# added ijb_docs.css to %%doc
+#
+# Revision 1.20  2002/03/12 13:42:14  sarantis
+# remove hardcoded "ijbswa" from build phase
+#
+# Revision 1.19  2002/03/11 22:59:05  hal9
+# Remove --enable-no-gifs
+#
+# Revision 1.18  2002/03/11 12:30:31  swa
+# be consistent with rh spec file
+#
+# Revision 1.17  2002/03/08 19:30:23  swa
+# remove user junkbuster after de-installation.
+# synced suse with rh-specfile. installation
+# and de-installation seem to work.
+#
+# Revision 1.16  2002/03/08 18:40:44  swa
+# build requires tools. useradd and del works
+# now.
+#
+# Revision 1.15  2002/03/07 19:23:50  swa
+# i hate to scroll. suse: wrong configdir.
+#
+# Revision 1.14  2002/03/07 19:10:21  swa
+# builds cleanly. thanks to kukuk@suse.de
+# not yet tested.
+#
+# Revision 1.13  2002/03/07 18:25:56  swa
+# synced redhat and suse build process
+#
+# Revision 1.12  2002/03/02 15:50:04  swa
+# 2.9.11 version. more input for docs.
+#
+# Revision 1.11  2001/12/02 10:29:26  swa
+# New version made these changes necessary.
+#
+# Revision 1.10  2001/10/31 19:27:27  swa
+# consistent description. new name for suse since
+# we had troubles with rpms of identical names
+# on the webserver.
+#
+# Revision 1.9  2001/10/26 18:17:23  swa
+# new version string
+#
+# Revision 1.8  2001/09/13 16:22:42  swa
+# man page is legacy. suse rpm now contains html
+# documentation.
+#
+# Revision 1.7  2001/09/10 17:44:22  swa
+# integrate three pieces of documentation.
+#
+# Revision 1.6  2001/09/10 16:29:23  swa
+# binary contained debug info.
+# buildroot definition fucks up the build process under suse.
+# program needs to write in varlogjunkbuster
+# install all templates
+# create varlogjunkbuster
+#
+# Revision 1.5  2001/06/09 09:13:29  swa
+# description shorter
+#
+# Revision 1.4  2001/06/08 20:53:36  swa
+# use buildroot, export init to separate file (better manageability)
+#
+# Revision 1.3  2001/06/07 17:28:10  swa
+# cosmetics
+#
+# Revision 1.2  2001/06/07 17:18:44  swa
+# header fixed
+#
+#
diff --git a/privoxy.1 b/privoxy.1
new file mode 100644 (file)
index 0000000..19cc5e2
--- /dev/null
+++ b/privoxy.1
@@ -0,0 +1,304 @@
+.\" This manpage has been automatically generated by docbook2man 
+.\" from a DocBook document.  This tool can be found at:
+.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> 
+.\" Please send any bug reports, improvements, comments, patches, 
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "PRIVOXY" "1" "14 May 2002" "Privoxy 2.9.15 beta" ""
+.SH NAME
+privoxy \- Privacy Enhancing Proxy
+.SH SYNOPSIS
+
+\fBprivoxy\fR [\fB--help\fR]  [\fB--version\fR]  [\fB--no-daemon\fR]  [\fB--pidfile \fIpidfile\fB\fR]  [\fB--user \fIuser[.group]\fB\fR]  [\fB\fIconfigfile\fB\fR] \fB(UNIX)\fR
+
+
+\fBprivoxy.exe\fR [\fB\fIconfigfile\fB\fR] \fB(Windows)\fR
+
+.SH "OPTIONS"
+.PP
+\fBPrivoxy\fR may be invoked with the following command line
+options:
+.TP
+\fB--help\fR
+Print brief usage info and exit.
+.TP
+\fB--version\fR
+Print version info and exit.
+.TP
+\fB--no-daemon\fR
+Don't  become  a daemon, i.e. don't fork and become process group
+leader, don't detach from controlling tty, and do all logging there.
+.TP
+\fB--pidfile \fIpidfile\fB\fR
+On startup, write the process ID to \fIpidfile\fR.
+Delete the \fIpidfile\fR on exit.
+Failiure to create or delete the \fIpidfile\fR
+is non-fatal. If no \fB--pidfile\fR option is given, no PID file will be used.
+.TP
+\fB--user \fIuser[.group]\fB\fR
+After (optionally) writing the PID file, assume the user ID of
+\fIuser\fR and the GID of
+\fIgroup\fR, or, if the optional
+\fIgroup\fR was not given, the default group of
+\fIuser\fR. Exit if the privileges are not
+sufficient to do so.
+.PP
+If the \fIconfigfile\fR is not specified on  the  command  line,
+\fBPrivoxy\fR  will  look for a file named
+\fIconfig\fR in the current directory (except on Win32 where
+it will try \fIconfig.txt\fR). If no
+\fIconfigfile\fR is found, \fBPrivoxy\fR will 
+fail to start.
+.SH "DESCRIPTION"
+.PP
+\fBPrivoxy\fR is a web proxy with advanced filtering
+capabilities for protecting privacy, filtering web page content, managing
+cookies, controlling access, and removing ads, banners, pop-ups and other
+obnoxious Internet junk. \fBPrivoxy\fR has a very
+flexible configuration and can be customized to suit individual needs and
+tastes. \fBPrivoxy\fR has application for both
+stand-alone systems and multi-user networks.
+.PP
+\fBPrivoxy\fR is based on \fBInternet
+Junkbuster\fR (tm).
+.SH "INSTALLATION AND USAGE"
+.PP
+Browsers must be individually configured to use \fBPrivoxy\fR as
+a HTTP proxy.  The default setting is  for  localhost,  on port  8118
+(configurable in the main config file).  To set the HTTP proxy in Netscape
+and Mozilla, go through:  \fBEdit\fR;
+\fBPreferences\fR;  \fBAdvanced\fR;
+\fBProxies\fR;  \fBManual Proxy Configuration\fR;
+\fBView\fR. 
+.PP
+For Internet Explorer, go through: \fBTools\fR; 
+\fBInternet Properties\fR; \fBConnections\fR;
+\fBLAN Settings\fR. 
+.PP
+The Secure (SSL) Proxy should also be set to the same values, otherwise
+https: URLs will not be proxied. 
+.PP
+For other browsers, check the documentation.
+.SH "CONFIGURATION"
+.PP
+\fBPrivoxy\fR can be configured with the various configuration
+files. The default configuration files are: \fIconfig\fR,
+\fIdefault.filter\fR, and
+\fIdefault.action\fR. \fIuser.action\fR should 
+be used for locally defined exceptions to the default rules of
+\fIdefault.action\fR These are all well commented.  On Unix
+and Unix-like systems, these are located in
+\fI/etc/privoxy/\fR by default. On Windows, OS/2 and AmigaOS,
+these files are in the same directory as the \fBPrivoxy\fR
+executable.
+.PP
+The name and number of configuration files has changed from previous
+versions, and is subject to change as development progresses. In fact, the
+configuration itself is changed  and  much more sophisticated. See the
+user-manual for a
+complete explanation of all configuration options and general usage.
+.PP
+The actions list (ad blocks, etc) can also be configured with your
+web browser at http://config.privoxy.org/.
+\fBPrivoxy's\fR configuration parameters  can also  be viewed at
+the same page. In addition, \fBPrivoxy\fR can be toggled on/off.
+This is an internal page.
+.SH "SAMPLE CONFIGURATION"
+.PP
+A brief example of what a simple \fIdefault.action\fR
+configuration might look like:
+
+.nf
+ # Define a few useful custom aliases for later use
+ {{alias}}
+
+ # Useful aliases
+ +crunch-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+ -crunch-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ +imageblock      = +block +handle-as-image
+
+ # Fragile sites should have the minimum changes
+ fragile     = -block -deanimate-gifs -fast-redirects -filter \\
+               -hide-referer -prevent-cookies -kill-popups
+
+ ## Turn some actions on ################################
+ { \\
+ -add-header \\
+ -block \\
+ +deanimate-gifs{last} \\
+ -downgrade-http-version \\
+ -fast-redirects \\
+ +filter{html-annoyances} \\
+ +filter{js-annoyances} \\
+ +filter{content-cookies} \\
+ +filter{webbugs} \\
+ +filter{banners-by-size} \\
+ +hide-forwarded-for-headers \\
+ +hide-from-header{block} \\
+ +hide-referrer{forge} \\
+ -hide-user-agent \\
+ -handle-as-image \\
+ +set-image-blocker{pattern} \\
+ -limit-connect \\
+ +prevent-compression \\
+ +session-cookies-only \\
+ -crunch-cookies \\
+ -kill-popups \\
+ }
+ /   # '/' Matches *all* URL patterns
+ # Block, and treat these URL patterns as if they were 'images'.
+ # We would expect these to be ads.
+ {+imageblock}
+  .ad.doubleclick.net
+  .a[0-9].yimg.com/(?:(?!/i/).)*$
+  ad.*.doubleclick.net
+
+ # Block any URLs that match these patterns
+ {+block}
+  ad*.
+  .*ads.
+  banner?.
+  /.*count(er)?\\.(pl|cgi|exe|dll|asp|php[34]?)
+  .hitbox.com 
+
+ # Make exceptions for these harmless ones that would be 
+ # caught by our +block patterns just above.
+ {-block}
+  adsl.
+  advice.
+  .*downloads.
+.fi
+.PP
+Then for a \fIuser.action\fR, we would put local,
+narrowly defined exceptions:
+
+.nf
+ # Re-define aliases as needed here
+ {{alias}}
+
+ # Useful aliases
+ -crunch-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ # Set personal exceptions to the policies in default.action #######
+
+ # Sites where we want persistant cookies, so allow *all* cookies
+ {-crunch-cookies -session-cookies-only}
+  .redhat.com
+  .sun.com
+  .msdn.microsoft.com
+ # This site breaks easily.
+ {-block -fast-redirects}
+  .forbes.com
+.fi
+.PP
+See the comments in the configuration files themselves, or the 
+\fIuser-manual\fR
+for explanations of the above syntax, and other \fBPrivoxy\fR
+configuration options.
+.SH "FILES"
+
+.nf
+ \fI/usr/sbin/privoxy\fR
+ \fI/etc/privoxy/config\fR
+ \fI/etc/privoxy/default.action\fR
+ \fI/etc/privoxy/standard.action\fR
+ \fI/etc/privoxy/user.action\fR
+ \fI/etc/privoxy/default.filter\fR
+ \fI/etc/privoxy/trust\fR
+ \fI/etc/privoxy/templates/*\fR
+ \fI/var/log/privoxy/logfile\fR
+.fi
+.PP
+Various other files should be included, but may vary depending on platform
+and build configuration. More documentation should be included in the local
+documentation directory.
+.SH "SIGNALS"
+.PP
+\fBPrivoxy\fR terminates on the \fBSIGINT\fR,
+\fBSIGTERM\fR and \fBSIGABRT\fR signals. Log
+rotation scripts may cause a re-opening of the logfile by sending a 
+\fBSIGHUP\fR to \fBPrivoxy\fR. Note that unlike
+other daemons,  \fBPrivoxy\fR does not need to be made aware of
+config file changes by \fBSIGHUP\fR -- it will detect them
+automatically. 
+.SH "NOTES"
+.PP
+This is a beta version of \fBPrivoxy\fR. Not 
+all features are well tested.
+.PP
+Please see the \fIuser-manual\fR on how to contact the
+developers for feature requests, reporting problems, and other questions.
+.SH "SEE ALSO"
+.PP
+Other references and sites of interest to \fBPrivoxy\fR
+users:
+.PP
+
+http://www.privoxy.org/, 
+The \fBPrivoxy\fR Home page. 
+
+http://sourceforge.net/projects/ijbswa, 
+the Project Page for \fBPrivoxy\fR on 
+Sourceforge.
+
+http://p.p/, access
+\fBPrivoxy\fR from your browser. Alternately, 
+http://config.privoxy.org
+may work in some situations where the first does not.
+
+http://p.p/ to submit ``misses'' to the developers. 
+
+http://www.junkbusters.com/ht/en/cookies.html
+
+http://www.waldherr.org/junkbuster/
+
+http://privacy.net/analyze/
+
+http://www.squid-cache.org/
+.SH "DEVELOPMENT TEAM"
+
+.nf
+ Jon Foster
+ Andreas Oesterhelt
+ Stefan Waldherr
+ Thomas Steudten
+ Rodney Stromlund
+ Rodrigo Barbosa (RPM specfiles)
+ Hal Burgiss (docs)
+ Alexander Lazic
+ Gábor Lipták
+ Guy
+ Haroon Rafique
+ David Schmidt (OS/2, Mac OSX ports)
+ Joerg Strohmayer
+ Sarantis Paskalis
+.fi
+.SH "COPYRIGHT AND LICENSE"
+.SS "COPYRIGHT"
+.PP
+Copyright (C) 2001, 2002 by Privoxy Developers <developers@privoxy.org>
+.PP
+Some source code is based on code Copyright (C) 1997 by Anonymous Coders
+and Junkbusters, Inc. and licensed under the \fIGNU General Public
+License\fR.
+.SS "LICENSE"
+.PP
+\fBPrivoxy\fR is free software; you can
+redistribute it and/or modify it under the terms of the 
+\fIGNU General Public
+License\fR, version 2, as published by the Free Software Foundation.
+.PP
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the 
+\fIGNU General Public License\fR for
+more details, which is available from the Free Software Foundation, Inc, 59
+Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+.PP
+You should have received a copy of the  \fIGNU General Public License\fR
+along with this program; if not, write to the  Free Software
+Foundation, Inc. 59 Temple Place - Suite 330
+Boston, MA 02111-1307
+USA 
diff --git a/privoxy.init b/privoxy.init
new file mode 100644 (file)
index 0000000..ff05a7e
--- /dev/null
@@ -0,0 +1,259 @@
+#!/bin/sh
+#
+# This is file /etc/rc.d/init.d/privoxy and was put here 
+# by the privoxy rpm
+#
+# chkconfig: 235 84 09
+#
+# description: This shell script takes care of starting and stopping \
+#              privoxy.
+#
+
+#  ********************************************************************
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/privoxy.init,v $
+# 
+#  Purpose     :  This shell script takes care of starting and stopping
+#                 privoxy.
+# 
+#  Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                 Privoxy team. http://www.privoxy.org/
+# 
+#                 Based on the Internet Junkbuster originally written
+#                 by and Copyright (C) 1997 Anonymous Coders and
+#                 Junkbusters Corporation.  http://www.junkbusters.com
+# 
+#                 This program is free software; you can redistribute it
+#                 and/or modify it under the terms of the GNU General
+#                 Public License as published by the Free Software
+#                 Foundation; either version 2 of the License, or (at
+#                 your option) any later version.
+# 
+#                 This program is distributed in the hope that it will
+#                 be useful, but WITHOUT ANY WARRANTY; without even the
+#                 implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                 PARTICULAR PURPOSE.  See the GNU General Public
+#                 License for more details.
+# 
+#                 The GNU General Public License should be included with
+#                 this file.  If not, you can view it at
+#                 http://www.gnu.org/copyleft/gpl.html
+#                 or write to the Free Software Foundation, Inc., 59
+#                 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+# 
+#  Revisions   :
+#     $Log: privoxy.init,v $
+#     Revision 1.7  2002/04/08 14:54:51  morcego
+#     Moved the chkconfig comments to the begining of the file, couse Linuxconf
+#     was getting confused with it where it was.
+#
+#     Revision 1.6  2002/03/26 22:29:55  swa
+#     we have a new homepage!
+#
+#     Revision 1.5  2002/03/25 06:14:18  morcego
+#     Removing the OPRG definition (no longer needed)
+#
+#     Revision 1.4  2002/03/25 04:16:48  hal9
+#     Fix proper config file location.
+#
+#     Revision 1.3  2002/03/24 19:12:15  hal9
+#     Fixed some naming conflicts.
+#
+#     Revision 1.2  2002/03/24 11:40:14  swa
+#     name change
+#
+#     Revision 1.1  2002/03/24 11:23:44  swa
+#     name change
+#
+#     Revision 1.1  2002/03/22 20:53:03  morcego
+#     - Ongoing process to change name to JunkbusterNG
+#     - configure/configure.in: no change needed
+#     - GNUmakefile.in:
+#             - TAR_ARCH = /tmp/JunkbusterNG-$(RPM_VERSION).tar.gz
+#             - PROGRAM    = jbng@EXEEXT@
+#             - rh-spec now references as junkbusterng-rh.spec
+#             - redhat-upload: references changed to junkbusterng-* (package names)
+#             - tarball-dist: references changed to JunkbusterNG-distribution-*
+#             - tarball-src: now JunkbusterNG-*
+#             - install: initscript now junkbusterng.init and junkbusterng (when
+#                        installed)
+#     - junkbuster-rh.spec: renamed to junkbusterng-rh.spec
+#     - junkbusterng.spec:
+#             - References to the expression ijb where changed where possible
+#             - New package name: junkbusterng (all in lower case, acording to
+#               the LSB recomendation)
+#             - Version changed to: 2.9.13
+#             - Release: 1
+#             - Added: junkbuster to obsoletes and conflicts (Not sure this is
+#               right. If it obsoletes, why conflict ? Have to check it later)
+#             - Summary changed: Stefan, please check and aprove it
+#             - Changes description to use the new name
+#             - Sed string was NOT changed. Have to wait to the manpage to
+#               change first
+#             - Keeping the user junkbuster for now. It will require some aditional
+#               changes on the script (scheduled for the next specfile release)
+#             - Added post entry to move the old logfile to the new log directory
+#             - Removing "chkconfig --add" entry (not good to have it automaticaly
+#               added to the startup list).
+#             - Added preun section to stop the service with the old name, as well
+#               as remove it from the startup list
+#             - Removed the chkconfig --del entry from the conditional block on
+#               the preun scriptlet (now handled on the %files section)
+#     - junkbuster.init: renamed to junkbusterng.init
+#     - junkbusterng.init:
+#             - Changed JB_BIN to jbng
+#             - Created JB_OBIN with the old value of JB_BIN (junkbuster), to
+#               be used where necessary (config dir)
+#
+#     Aditional notes:
+#     - The config directory is /etc/junkbuster yet. Have to change it on the
+#     specfile, after it is changes on the code
+#     - The only files that got renamed on the cvs tree were the rh specfile and
+#     the init file. Some file references got changes on the makefile and on the
+#     rh-spec (as listed above)
+#
+#     Revision 1.15  2002/03/09 15:05:58  swa
+#     wrong user.group
+#
+#     Revision 1.14  2002/03/06 06:13:40  hal9
+#     Adapted for Andreas' changes for --user and --pidfile.
+#
+#     Revision 1.13  2002/03/05 05:10:10  oes
+#     Changed pidfile path to conform with FHS
+#
+#     Revision 1.12  2002/03/04 20:44:36  oes
+#     Changed to new cmdline syntax
+#
+#     Revision 1.11  2001/12/30 14:07:32  steudten
+#     - Add signal handling (unix)
+#     - Add SIGHUP handler (unix)
+#     - Add creation of pidfile (unix)
+#     - Add action 'top' in rc file (RH)
+#     - Add entry 'SIGNALS' to manpage
+#     - Add exit message to logfile (unix)
+#
+#     Revision 1.10  2001/11/05 21:30:23  steudten
+#     Make JB startup without & due to be a 'real' daemon right now.
+#     Make the script easy to change.
+#
+#     Revision 1.9  2001/09/15 01:53:12  steudten
+#
+#     Remove test for subsys flag in start. Some minor changes.
+#
+#     Revision 1.8  2001/06/28 13:50:36  sarantis
+#     swap ?$ with $?; remove bogus ";;"
+#
+#     Revision 1.7  2001/06/28 13:40:26  sarantis
+#     remove single quotes from $JB; it was not expanded.
+#
+#     Revision 1.6  2001/06/28 13:38:42  sarantis
+#     formatting changes; individual return values are returned from the init script.
+#
+#     Revision 1.5  2001/06/11 11:37:40  sarantis
+#     Minor editing changes.
+#
+#     Revision 1.4  2001/06/09 09:14:11  swa
+#     shamelessly adapted RPM stuff from the newest rpm that
+#     RedHat provided for the JB.
+#
+#     Revision 1.3  2001/05/25 10:12:44  oes
+#     Fixed default case in switch statement (# -> *)
+#
+#     Revision 1.2  2001/05/24 07:52:24  swa
+#     added header. removed ^M.
+#
+# 
+# ********************************************************************/
+
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+. /etc/sysconfig/network
+
+#  Check that networking is up.
+[ ${NETWORKING} = "no" ] && exit 0
+
+PRIVOXY_PRG="privoxy"
+PRIVOXY_BIN="/usr/sbin/$PRIVOXY_PRG"
+PRIVOXY_CONF="/etc/$PRIVOXY_PRG/config"
+PRIVOXY_USER="privoxy"
+PRIVOXY_PID=/var/run/$PRIVOXY_PRG.pid
+PRIVOXY_LOCK=/var/lock/subsys/$PRIVOXY_PRG
+PRIVOXY="$PRIVOXY_BIN --user $PRIVOXY_USER.$PRIVOXY_USER --pidfile $PRIVOXY_PID $PRIVOXY_CONF"
+
+# some checks for us
+! [ -x $PRIVOXY_BIN  ] && echo "Can't find $PRIVOXY_BIN, exit." && exit 0
+! [ -f $PRIVOXY_CONF ] && echo "Can't find $PRIVOXY_CONF, exit." && exit 0
+
+# See how we were called.
+
+start () {
+       # start daemon
+       echo -n $"Starting $PRIVOXY_PRG: "
+     if [ -f $PRIVOXY_PID ]; then 
+        killproc $PRIVOXY_PRG && rm -f $PRIVOXY_LOCK $PRIVOXY_PID
+        RETVAL=$?
+        [ $RETVAL != 0 ] && return $RETVAL
+     fi
+       daemon $PRIVOXY
+       RETVAL=$?
+       echo
+       [ $RETVAL = 0 ] && touch $PRIVOXY_LOCK
+       return $RETVAL
+}
+
+stop () {
+       # stop daemon
+       echo -n $"Stopping $PRIVOXY_PRG: "
+       killproc $PRIVOXY_PRG && rm -f $PRIVOXY_LOCK $PRIVOXY_PID
+       RETVAL=$?
+       echo
+       return $RETVAL
+}
+
+case "$1" in
+  start)
+       start   
+       ;;
+  stop)
+       stop
+       ;;
+  reload)
+       if [ -f $PRIVOXY_PID ] ; then
+        kill -HUP `cat $PRIVOXY_PID`
+        RETVAL=$?
+     fi
+       ;;
+  restart)
+       stop
+       start
+       RETVAL=$?
+       ;;
+  condrestart)
+       # restart only if already running
+       if [ -f $PRIVOXY_PID ] ; then
+        stop
+        start
+        RETVAL=$?
+       fi 
+       ;;
+  status)
+       status $PRIVOXY_PRG 
+       RETVAL=$?
+       ;;
+  top)
+     if [ -f $PRIVOXY_PID ]; then
+                a=""
+                for i in `pidof $PRIVOXY_PRG` ; do
+                        a="$a -p $i"
+                done
+                top $a
+     fi
+       ;;
+  *)
+       echo $"Usage: $PRIVOXY_PRG {start|stop|reload|restart|condrestart|status|top}"
+       exit 1
+esac
+
+exit $RETVAL
diff --git a/privoxy.init.suse b/privoxy.init.suse
new file mode 100644 (file)
index 0000000..7bab6de
--- /dev/null
@@ -0,0 +1,117 @@
+#! /bin/sh
+#  ********************************************************************
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/privoxy.init.suse,v $
+# 
+#  Purpose     :  This shell script takes care of starting and stopping
+#                 privoxy.
+# 
+#  Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                 Privoxy team. http://www.privoxy.org/
+# 
+#                 Based on the Internet Junkbuster originally written
+#                 by and Copyright (C) 1997 Anonymous Coders and
+#                 Junkbusters Corporation.  http://www.junkbusters.com
+# 
+#                 This program is free software; you can redistribute it
+#                 and/or modify it under the terms of the GNU General
+#                 Public License as published by the Free Software
+#                 Foundation; either version 2 of the License, or (at
+#                 your option) any later version.
+# 
+#                 This program is distributed in the hope that it will
+#                 be useful, but WITHOUT ANY WARRANTY; without even the
+#                 implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                 PARTICULAR PURPOSE.  See the GNU General Public
+#                 License for more details.
+# 
+#                 The GNU General Public License should be included with
+#                 this file.  If not, you can view it at
+#                 http://www.gnu.org/copyleft/gpl.html
+#                 or write to the Free Software Foundation, Inc., 59
+#                 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+# 
+#  Revisions   :
+#     $Log: privoxy.init.suse,v $
+#     Revision 1.2  2002/03/24 11:40:14  swa
+#     name change
+#
+#     Revision 1.1  2002/03/24 11:23:44  swa
+#     name change
+#
+#     Revision 1.7  2002/03/11 11:44:46  oes
+#     Working in suggestions by Thorsten Kukuk <kukuk@suse.de>
+#
+#     Revision 1.6  2002/03/09 14:56:34  swa
+#     wrong user.group
+#
+#     Revision 1.5  2002/03/08 21:39:59  oes
+#     setgid to nogroup
+#
+#     Revision 1.4  2002/03/05 19:54:37  oes
+#     Preliminary version of SuSE 8.0-certified init script ,-)
+#
+#     Revision 1.3  2002/03/05 05:28:05  oes
+#     Added pidfile creation
+#
+#     Revision 1.2  2001/09/10 16:25:46  swa
+#     jb did not start. none of the arguments worked. fixed.
+#
+#     Revision 1.1  2001/06/08 20:53:36  swa
+#     use buildroot, export init to separate file (better manageability)
+#
+#
+# 
+# ********************************************************************/
+### BEGIN INIT INFO
+# Provides:       privoxy
+# Required-Start: $network $syslog $remote_fs
+# Required-Stop:
+# Default-Start:  3 5
+# Default-Stop:   0 1 2 6
+# Description:    Starts Privoxy
+### END INIT INFO
+
+. /etc/rc.config
+rc_reset  
+
+case "$1" in
+    start)
+        echo -n "Starting Privoxy"
+        if [ ! -f /var/run/privoxy.pid ] || ! kill -0 `cat /var/run/privoxy.pid` 2> /dev/null; then
+           /usr/sbin/privoxy --user privoxy.privoxy --pidfile /var/run/privoxy.pid /etc/privoxy/config 2> /dev/null
+        else     
+           false 
+        fi
+       rc_status -v
+        ;;
+    stop)
+        echo -n "Shutting down Privoxy"
+        killproc -TERM /usr/sbin/privoxy && rm -f /var/run/privoxy.pid
+       rc_status -v
+        ;;
+    reload)
+        echo -n "Reloading Privoxy"
+        kill -HUP `cat /var/run/privoxy.pid`
+        rc_status -v
+        ;;
+    try-restart)
+        $0 stop && $0 start
+       rc_status
+        ;;
+    restart)
+        $0 stop
+        $0 start
+        rc_status
+        ;;           
+    status)
+       echo -n "Checking for Privoxy"
+        checkproc /usr/sbin/privoxy
+       rc_status -v
+        ;;
+    *)
+        echo "Usage: $0 {start|restart|reload|status|stop}"
+        exit 1
+esac
+
+rc_exit
diff --git a/privoxy.logrotate b/privoxy.logrotate
new file mode 100644 (file)
index 0000000..035112a
--- /dev/null
@@ -0,0 +1,96 @@
+#
+# Logrotate file for Privoxy RPM
+#
+# ********************************************************************
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/privoxy.logrotate,v $
+# 
+#  Purpose     :  Rotates all potential Privoxy logfiles
+#                 
+# 
+#  Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                 Privoxy team. http://www.privoxy.org/
+# 
+#                 Based on the Internet Junkbuster originally written
+#                 by and Copyright (C) 1997 Anonymous Coders and 
+#                 Junkbusters Corporation.  http://www.junkbusters.com
+# 
+#                 This program is free software; you can redistribute it 
+#                 and/or modify it under the terms of the GNU General
+#                 Public License as published by the Free Software
+#                 Foundation; either version 2 of the License, or (at
+#                 your option) any later version.
+# 
+#                 This program is distributed in the hope that it will
+#                 be useful, but WITHOUT ANY WARRANTY; without even the
+#                 implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                 PARTICULAR PURPOSE.  See the GNU General Public
+#                 License for more details.
+# 
+#                 The GNU General Public License should be included with
+#                 this file.  If not, you can view it at
+#                 http://www.gnu.org/copyleft/gpl.html
+#                 or write to the Free Software Foundation, Inc., 59
+#                 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+# 
+#  Revisions   :
+#     $Log: privoxy.logrotate,v $
+#     Revision 1.3  2002/03/24 15:19:57  swa
+#     name change related issue.
+#
+#     Revision 1.2  2002/03/24 11:40:14  swa
+#     name change
+#
+#     Revision 1.1  2002/03/24 11:23:44  swa
+#     name change
+#
+#     Revision 1.7  2001/12/30 14:07:32  steudten
+#     - Add signal handling (unix)
+#     - Add SIGHUP handler (unix)
+#     - Add creation of pidfile (unix)
+#     - Add action 'top' in rc file (RH)
+#     - Add entry 'SIGNALS' to manpage
+#     - Add exit message to logfile (unix)
+#
+#     Revision 1.6  2001/12/13 23:19:43  steudten
+#     Add 'restart' of junkbuster service after rotate logfiles.
+#     Better we could use the well known 'kill -HUP', but the handler
+#     isn't there at this time.
+#
+#     Revision 1.5  2001/11/05 21:31:51  steudten
+#     Change switch mode from weekly to size 1M
+#
+#     Revision 1.4  2001/06/28 13:30:22  sarantis
+#     add missingok for the jarfile entry
+#
+#     Revision 1.3  2001/06/04 18:31:58  swa
+#     files are now prefixed with either `confdir' or `logdir'.
+#     `make redhat-dist' replaces both entries confdir and logdir
+#     with redhat values
+#
+#     Revision 1.2  2001/05/24 07:52:24  swa
+#     added header. removed ^M.
+#
+#     Revision 1.3  2001/05/24 07:41:33  swa
+#     added header
+#
+# 
+# 
+# ********************************************************************/
+
+/var/log/privoxy/logfile {
+   compress
+   size 1M
+   postrotate
+        /sbin/service privoxy reload  2> /dev/null || true
+   endscript
+}
+
+/var/log/privoxy/jarfile {
+   missingok
+   compress
+   size 1M
+   postrotate
+        /sbin/service privoxy reload  2> /dev/null || true
+   endscript
+}
diff --git a/privoxy.monthly b/privoxy.monthly
new file mode 100644 (file)
index 0000000..15734dd
--- /dev/null
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+# ********************************************************************
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/privoxy.monthly,v $
+# 
+#  Purpose     :  Downloads updated configuration (blocklists, ...)
+#                 to the machine.
+# 
+#  Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                 Privoxy team. http://www.privoxy.org/
+# 
+#                 Based on the Internet Junkbuster originally written
+#                 by and Copyright (C) 1997 Anonymous Coders and 
+#                 Junkbusters Corporation.  http://www.junkbusters.com
+# 
+#                 This program is free software; you can redistribute it 
+#                 and/or modify it under the terms of the GNU General
+#                 Public License as published by the Free Software
+#                 Foundation; either version 2 of the License, or (at
+#                 your option) any later version.
+# 
+#                 This program is distributed in the hope that it will
+#                 be useful, but WITHOUT ANY WARRANTY; without even the
+#                 implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                 PARTICULAR PURPOSE.  See the GNU General Public
+#                 License for more details.
+# 
+#                 The GNU General Public License should be included with
+#                 this file.  If not, you can view it at
+#                 http://www.gnu.org/copyleft/gpl.html
+#                 or write to the Free Software Foundation, Inc., 59
+#                 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+# 
+#  Revisions   :
+#     $Log: privoxy.monthly,v $
+#     Revision 1.2  2002/03/24 11:40:14  swa
+#     name change
+#
+#     Revision 1.1  2002/03/24 11:23:44  swa
+#     name change
+#
+#     Revision 1.3  2001/05/24 07:41:33  swa
+#     added header
+#
+# 
+# 
+# ********************************************************************/
+
+set -e
+
+# blocklist
+wget -q --output-document=/etc/junkbuster/blocklist.new \
+     http://www.waldherr.org/blocklist
+
+mv -f /etc/junkbuster/blocklist.new /etc/junkbuster/blocklist
+
+if [ -f /etc/junkbuster/blocklist.local ] ; then
+   cat /etc/junkbuster/blocklist.local >> /etc/junkbuster/blocklist
+fi
+chmod 644 /etc/junkbuster/blocklist
+
+# cookiefile
+wget -q --output-document=/etc/junkbuster/cookiefile.new \
+     http://www.waldherr.org/cookiefile
+
+mv -f /etc/junkbuster/cookiefile.new /etc/junkbuster/cookiefile
+
+if [ -f /etc/junkbuster/cookiefile.local ] ; then
+   cat /etc/junkbuster/cookiefile.local >> /etc/junkbuster/cookiefile
+fi
+chmod 644 /etc/junkbuster/cookiefile
+
+# imagelist
+wget -q --output-document=/etc/junkbuster/imagelist.new \
+     http://www.waldherr.org/imagelist
+
+mv -f /etc/junkbuster/imagelist.new /etc/junkbuster/imagelist
+
+if [ -f /etc/junkbuster/imagelist.local ] ; then
+   cat /etc/junkbuster/imagelist.local >> /etc/junkbuster/imagelist
+fi
+chmod 644 /etc/junkbuster/imagelist
+
diff --git a/privoxy.weekly b/privoxy.weekly
new file mode 100644 (file)
index 0000000..81424f8
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+# ********************************************************************
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/privoxy.weekly,v $
+# 
+#  Purpose     :  Downloads updated configuration (blocklists, ...)
+#                 to the machine.
+# 
+#  Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                 Privoxy team. http://www.privoxy.org/
+# 
+#                 Based on the Internet Junkbuster originally written
+#                 by and Copyright (C) 1997 Anonymous Coders and 
+#                 Junkbusters Corporation.  http://www.junkbusters.com
+# 
+#                 This program is free software; you can redistribute it 
+#                 and/or modify it under the terms of the GNU General
+#                 Public License as published by the Free Software
+#                 Foundation; either version 2 of the License, or (at
+#                 your option) any later version.
+# 
+#                 This program is distributed in the hope that it will
+#                 be useful, but WITHOUT ANY WARRANTY; without even the
+#                 implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                 PARTICULAR PURPOSE.  See the GNU General Public
+#                 License for more details.
+# 
+#                 The GNU General Public License should be included with
+#                 this file.  If not, you can view it at
+#                 http://www.gnu.org/copyleft/gpl.html
+#                 or write to the Free Software Foundation, Inc., 59
+#                 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+# 
+#  Revisions   :
+#     $Log: privoxy.weekly,v $
+#     Revision 1.2  2002/03/24 11:40:14  swa
+#     name change
+#
+#     Revision 1.1  2002/03/24 11:23:44  swa
+#     name change
+#
+#     Revision 1.2  2001/05/24 07:52:24  swa
+#     added header. removed ^M.
+#
+#     Revision 1.3  2001/05/24 07:41:33  swa
+#     added header
+#
+# 
+# 
+# ********************************************************************/
+
+set -e
+
+# blocklist
+wget -q --output-document=/etc/junkbuster/blocklist.new \
+     http://www.waldherr.org/blocklist
+
+mv -f /etc/junkbuster/blocklist.new /etc/junkbuster/blocklist
+
+if [ -f /etc/junkbuster/blocklist.local ] ; then
+   cat /etc/junkbuster/blocklist.local >> /etc/junkbuster/blocklist
+fi
+
+chmod 644 /etc/junkbuster/blocklist
+
+
index 5f4324a..43d53d6 100644 (file)
--- a/project.h
+++ b/project.h
@@ -1,22 +1,23 @@
-#ifndef _PROJECT_H
-#define _PROJECT_H
-#define PROJECT_H_VERSION "$Id: project.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
+#ifndef PROJECT_H_INCLUDED
+#define PROJECT_H_INCLUDED
+/** Version string. */
+#define PROJECT_H_VERSION "$Id: project.h,v 1.71 2002/05/12 21:39:36 jongfoster Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/project.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/project.h,v $
  *
  * Purpose     :  Defines data structures which are widely used in the
  *                project.  Does not define any variables or functions
  *                (though it does declare some macros).
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
  *
  * Revisions   :
  *    $Log: project.h,v $
+ *    Revision 1.71  2002/05/12 21:39:36  jongfoster
+ *    - Adding Doxygen-style comments to structures and #defines.
+ *
+ *    Revision 1.70  2002/05/12 16:05:50  jongfoster
+ *    Fixing ACTION_MASK_ALL to be unsigned long rather than
+ *    just unsigned int.  I don't know if anyone is porting
+ *    Privoxy to 16-bit platforms, but if so, +limit-connect
+ *    wouldn't have worked because of this bug.
+ *
+ *    Revision 1.69  2002/05/08 16:00:16  oes
+ *    Added size member to struct iob, so it can
+ *    be alloced larger than needed.
+ *
+ *    Revision 1.68  2002/04/26 12:56:00  oes
+ *    Killed REDIRECT_URL, added USER_MANUAL_URL and HELP_LINK_PREFIX
+ *
+ *    Revision 1.67  2002/04/24 02:12:43  oes
+ *     - Jon's multiple AF patch:
+ *       - Make csp->actions_list an array
+ *       - #define MAX_ACTION_FILES
+ *     - Moved CGI_PARAM_LEN_MAX (500) here
+ *
+ *    Revision 1.66  2002/04/15 19:06:43  jongfoster
+ *    Typos
+ *
+ *    Revision 1.65  2002/04/04 00:36:36  gliptak
+ *    always use pcre for matching
+ *
+ *    Revision 1.64  2002/04/03 22:28:03  gliptak
+ *    Removed references to gnu_regex
+ *
+ *    Revision 1.63  2002/03/31 17:19:00  jongfoster
+ *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
+ *
+ *    Revision 1.62  2002/03/26 22:48:49  swa
+ *    new homepage url
+ *
+ *    Revision 1.61  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.60  2002/03/24 15:52:17  jongfoster
+ *    Changing CGI URL prefixes for new name
+ *
+ *    Revision 1.59  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
+ *    Revision 1.58  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.57  2002/03/16 20:28:34  oes
+ *    Added descriptions to the filters so users will know what they select in the cgi editor
+ *
+ *    Revision 1.56  2002/03/13 20:27:30  oes
+ *    Fixing bug with CT_TABOO
+ *
+ *    Revision 1.55  2002/03/12 01:42:50  oes
+ *    Introduced modular filters
+ *
+ *    Revision 1.54  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.53  2002/03/08 16:48:55  oes
+ *    Added FEATURE_NO_GIFS and BUILTIN_IMAGE_MIMETYPE
+ *
+ *    Revision 1.52  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.51  2002/03/05 04:52:42  oes
+ *    Deleted non-errlog debugging code
+ *
+ *    Revision 1.50  2002/03/04 19:32:07  oes
+ *    Changed default port to 8118
+ *
+ *    Revision 1.49  2002/03/04 18:28:55  oes
+ *    Deleted PID_FILE_NAME
+ *
+ *    Revision 1.48  2002/03/03 14:50:40  oes
+ *    Fixed CLF logging: Added ocmd member for client's request to struct http_request
+ *
+ *    Revision 1.47  2002/02/20 23:15:13  jongfoster
+ *    Parsing functions now handle out-of-memory gracefully by returning
+ *    an error code.
+ *
+ *    Revision 1.46  2002/01/17 21:06:09  jongfoster
+ *    Now #defining the URLs of the config interface
+ *
+ *    Minor changes to struct http_request and struct url_spec due to
+ *    standardizing that struct http_request is used to represent a URL, and
+ *    struct url_spec is used to represent a URL pattern.  (Before, URLs were
+ *    represented as seperate variables and a partially-filled-in url_spec).
+ *
+ *    Revision 1.45  2002/01/09 14:33:27  oes
+ *    Added HOSTENT_BUFFER_SIZE
+ *
+ *    Revision 1.44  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.43  2001/11/22 21:57:51  jongfoster
+ *    Making action_spec->flags into an unsigned long rather than just an
+ *    unsigned int.
+ *    Adding ACTION_NO_COOKIE_KEEP
+ *
+ *    Revision 1.42  2001/11/05 21:42:41  steudten
+ *    Include DBG() macro.
+ *
+ *    Revision 1.41  2001/10/28 19:12:06  jongfoster
+ *    Adding ijb_toupper()
+ *
+ *    Revision 1.40  2001/10/26 17:40:47  oes
+ *    Moved ijb_isspace and ijb_tolower to project.h
+ *    Removed http->user_agent, csp->referrer and csp->accept_types
+ *
+ *    Revision 1.39  2001/10/25 03:45:02  david__schmidt
+ *    Adding a (void*) cast to freez() because Visual Age C++ won't expand the
+ *    macro when called with a cast; so moving the cast to the macro def'n
+ *    seems to both eliminate compiler warnings (on darwin and OS/2, anyway) and
+ *    doesn't make macro expansion complain.  Hope this works for everyone else
+ *    too...
+ *
+ *    Revision 1.38  2001/10/23 21:19:04  jongfoster
+ *    New error-handling support: jb_err type and JB_ERR_xxx constants
+ *    CGI functions now return a jb_err, and their parameters map is const.
+ *    Support for RUNTIME_FEATUREs to enable/disable config editor
+ *    Adding a few comments
+ *
+ *    Revision 1.37  2001/10/14 22:14:01  jongfoster
+ *    Removing name_length field from struct cgi_dispatcher, as this is
+ *    now calculated at runtime from the "name" field.
+ *
+ *    Revision 1.36  2001/10/10 16:45:15  oes
+ *    Added LIMIT_CONNECT action and string
+ *    Fixed HTTP message line termination
+ *    Added CFORBIDDEN HTTP message
+ *
+ *    Revision 1.35  2001/10/07 18:06:43  oes
+ *    Added status member to struct http_request
+ *
+ *    Revision 1.34  2001/10/07 15:45:25  oes
+ *    Added url member to struct http_request and commented all
+ *      members
+ *
+ *    Added CT_TABOO
+ *
+ *    Added ACTION_DOWNGRADE and ACTION_NO_COMPRESSION
+ *
+ *    Replaced struct client_state members rejected,
+ *      force, active and toggled_on with "flags" bitmap.
+ *
+ *    Added CSP_FLAG_MODIFIED and CSP_FLAG_CHUNKED
+ *
+ *    Added buffer_limit to struct configuration_spec
+ *
+ *    Revision 1.33  2001/09/20 13:30:08  steudten
+ *
+ *    Make freez() more secure in case of: if (exp) { free(z) ; a=*z }
+ *    Last case will set z to NULL in free(z) and thats bad..
+ *
+ *    Revision 1.32  2001/09/16 23:02:51  jongfoster
+ *    Fixing warning
+ *
+ *    Revision 1.31  2001/09/16 13:20:29  jongfoster
+ *    Rewrite of list library.  Now has seperate header and list_entry
+ *    structures.  Also added a large sprinking of assert()s to the list
+ *    code.
+ *
+ *    Revision 1.30  2001/09/13 23:52:00  jongfoster
+ *    Support for both static and dynamically generated CGI pages
+ *
+ *    Revision 1.29  2001/09/13 23:29:43  jongfoster
+ *    Defining FORWARD_SPEC_INITIALIZER
+ *
+ *    Revision 1.28  2001/09/13 23:05:50  jongfoster
+ *    Changing the string paramater to the header parsers a "const".
+ *
+ *    Revision 1.27  2001/08/05 16:06:20  jongfoster
+ *    Modifiying "struct map" so that there are now separate header and
+ *    "map_entry" structures.  This means that functions which modify a
+ *    map no longer need to return a pointer to the modified map.
+ *    Also, it no longer reverses the order of the entries (which may be
+ *    important with some advanced template substitutions).
+ *
+ *    Revision 1.26  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.25  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.24  2001/07/25 17:20:27  oes
+ *    Introduced http->user_agent
+ *
+ *    Revision 1.23  2001/07/18 12:32:23  oes
+ *    - Added ACTION_STRING_DEANIMATE
+ *    - moved #define freez from jcc.h to project.h
+ *
+ *    Revision 1.22  2001/07/15 17:51:41  jongfoster
+ *    Renaming #define STATIC to STATIC_PCRE
+ *
+ *    Revision 1.21  2001/07/13 14:03:19  oes
+ *     - Reorganized regex header inclusion and #defines to
+ *       comply to the scheme in configure.in
+ *     - Added csp->content_type and its CT_* keys
+ *     - Added ACTION_DEANIMATE
+ *     - Removed all #ifdef PCRS
+ *
+ *    Revision 1.20  2001/06/29 21:45:41  oes
+ *    Indentation, CRLF->LF, Tab-> Space
+ *
+ *    Revision 1.19  2001/06/29 13:33:36  oes
+ *    - Improved comments
+ *    - Introduced http_request.host_ip_addr_str
+ *    - Introduced http_response.head_length
+ *    - Introduced config.my_ip_addr_str, config.my_hostname,
+ *      config.admin_address and config.proxy_info_url
+ *    - Removed config.proxy_args_header and config.proxy_args_trailer,
+ *      renamed config.proxy_args_invocation to config.proxy_args
+ *    - Removed HTML snipplets and GIFs
+ *    - Removed logentry from cancelled commit
+ *
+ *    Revision 1.18  2001/06/09 10:57:39  jongfoster
+ *    Adding definition of BUFFER_SIZE.
+ *    Changing struct cgi_dispatcher to use "const" strings.
+ *
+ *    Revision 1.17  2001/06/07 23:15:09  jongfoster
+ *    Merging ACL and forward files into config file.
+ *    Moving struct gateway members into struct forward_spec
+ *    Removing config->proxy_args_gateways
+ *    Cosmetic: Adding a few comments
+ *
+ *    Revision 1.16  2001/06/04 18:31:58  swa
+ *    files are now prefixed with either `confdir' or `logdir'.
+ *    `make redhat-dist' replaces both entries confdir and logdir
+ *    with redhat values
+ *
+ *    Revision 1.15  2001/06/04 11:28:53  swa
+ *    redirect did not work due to missing /
+ *
+ *    Revision 1.14  2001/06/03 11:03:48  oes
+ *    Added struct map,
+ *    added struct http_response,
+ *    changed struct interceptors to struct cgi_dispatcher,
+ *    moved HTML stuff to cgi.h
+ *
+ *    Revision 1.13  2001/06/01 20:05:36  jongfoster
+ *    Support for +image-blocker{}: added ACTION_IMAGE_BLOCKER
+ *    constant, and removed csp->tinygif.
+ *
+ *    Revision 1.12  2001/06/01 18:49:17  jongfoster
+ *    Replaced "list_share" with "list" - the tiny memory gain was not
+ *    worth the extra complexity.
+ *
+ *    Revision 1.11  2001/06/01 10:32:47  oes
+ *    Added constants for anchoring selection bitmap
+ *
+ *    Revision 1.10  2001/05/31 21:33:53  jongfoster
+ *    Changes for new actions file, replacing permissionsfile
+ *    and parts of the config file.  Also added support for
+ *    list_shared.
+ *
+ *    Revision 1.9  2001/05/31 17:32:31  oes
+ *
+ *     - Enhanced domain part globbing with infix and prefix asterisk
+ *       matching and optional unanchored operation
+ *
+ *    Revision 1.8  2001/05/29 20:09:15  joergs
+ *    HTTP_REDIRECT_TEMPLATE fixed.
+ *
+ *    Revision 1.7  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/actionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.6  2001/05/27 22:17:04  oes
+ *
+ *    - re_process_buffer no longer writes the modified buffer
+ *      to the client, which was very ugly. It now returns the
+ *      buffer, which it is then written by chat.
+ *
+ *    - content_length now adjusts the Content-Length: header
+ *      for modified documents rather than crunch()ing it.
+ *      (Length info in csp->content_length, which is 0 for
+ *      unmodified documents)
+ *
+ *    - For this to work, sed() is called twice when filtering.
+ *
+ *    Revision 1.5  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.4  2001/05/22 18:46:04  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Some minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.3  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "actionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.2  2001/05/17 23:01:01  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:03  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
 
 /*
  * Include appropriate regular expression libraries.
- *
- * PCRS           ==> Include pcre
- * REGEX && PCRE  ==> Include pcre and pcreposix
- * REGEX && !PCRE ==> Include gnu_regex
- *
- * STATIC  ==> Use  #include "pcre.h"  (compiling at same time)
- * !STATIC ==> Use  #include <pcre.h>  (System library)
- *
+ * Note that pcrs and pcre (native) are needed for cgi
+ * and are included anyway.
  */
-#if (defined(REGEX) && defined(PCRE)) || defined(PCRS)
-#  ifdef STATIC
-#    include "pcre.h"
-#  else
-#    include <pcre.h>
-#  endif
-#endif /* (defined(REGEX) && defined(PCRE)) || defined(PCRS) */
 
-#if defined(REGEX) && defined(PCRE)
-#  ifdef STATIC
-#    include "pcreposix.h"
-#  else
-#    include <pcreposix.h>
-#  endif
-#endif /* defined(REGEX) && defined(PCRE) */
+#ifdef STATIC_PCRE
+#  include "pcre.h"
+#else
+#  include <pcre.h>
+#endif
 
-#if defined(REGEX) && !defined(PCRE)
-#  include "gnu_regex.h"
+#ifdef STATIC_PCRS
+#  include "pcrs.h"
+#else
+#  include <pcrs.h>
 #endif
 
-#ifdef PCRS
-#include "pcrs.h"
-#endif /* def PCRS */
+#ifdef STATIC_PCRE
+#  include "pcreposix.h"
+#else
+#  include <pcreposix.h>
+#endif
 
-#ifdef AMIGA 
-#include "amiga.h" 
+#ifdef AMIGA
+#include "amiga.h"
 #endif /* def AMIGA */
 
+#ifdef _WIN32
+/*
+ * I don't want to have to #include all this just for the declaration
+ * of SOCKET.  However, it looks like we have to...
+ */
+#ifndef STRICT
+#define STRICT
+#endif
+#include <windows.h>
+#endif
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#ifdef _WIN32
+
+typedef SOCKET jb_socket;
+
+#define JB_INVALID_SOCKET INVALID_SOCKET
+
+#else /* ndef _WIN32 */
+
+/**
+ * The type used by sockets.  On UNIX it's an int.  Microsoft decided to
+ * make it an unsigned.
+ */
+typedef int jb_socket;
+
+/**
+ * The error value used for variables of type jb_socket.  On UNIX this
+ * is -1, however Microsoft decided to make socket handles unsigned, so
+ * they use a different value.
+ */
+
+#define JB_INVALID_SOCKET (-1)
+
+#endif /* ndef _WIN32 */
+
+
+/**
+ * A standard error code.  This should be JB_ERR_OK or one of the JB_ERR_xxx
+ * series of errors.
+ */
+typedef int jb_err;
+
+#define JB_ERR_OK         0 /**< Success, no error                        */
+#define JB_ERR_MEMORY     1 /**< Out of memory                            */
+#define JB_ERR_CGI_PARAMS 2 /**< Missing or corrupt CGI parameters        */
+#define JB_ERR_FILE       3 /**< Error opening, reading or writing a file */
+#define JB_ERR_PARSE      4 /**< Error parsing file                       */
+#define JB_ERR_MODIFIED   5 /**< File has been modified outside of the  
+                                 CGI actions editor.                      */
+
+
+/**
+ * This macro is used to free a pointer that may be NULL.
+ * It also sets the variable to NULL after it's been freed.
+ * The paramater should be a simple variable without side effects.
+ */
+#define freez(X)  { if(X) { free((void*)X); X = NULL ; } }
+
+
+/**
+ * Fix a problem with Solaris.  There should be no effect on other
+ * platforms.
+ *
+ * Solaris's isspace() is a macro which uses it's argument directly
+ * as an array index.  Therefore we need to make sure that high-bit
+ * characters generate +ve values, and ideally we also want to make
+ * the argument match the declared parameter type of "int".
+ *
+ * Note: Remember to #include <ctype.h> if you use these macros.
+ */
+#define ijb_toupper(__X) toupper((int)(unsigned char)(__X))
+#define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
+#define ijb_isspace(__X) isspace((int)(unsigned char)(__X))  
+
+/**
+ * Use for statically allocated buffers if you have no other choice.
+ * Remember to check the length of what you write into the buffer
+ * - we don't want any buffer overflows!
+ */
+#define BUFFER_SIZE 5000
+
+/**
+ * Max length of CGI parameters (arbitrary limit).
+ */
+#define CGI_PARAM_LEN_MAX 500
+
+/**
+ * Buffer size for capturing struct hostent data in the
+ * gethostby(name|addr)_r library calls. Since we don't
+ * loop over gethostbyname_r, the buffer must be sufficient
+ * to accomodate multiple IN A RRs, as used in DNS round robin
+ * load balancing. W3C's wwwlib uses 1K, so that should be
+ * good enough for us, too.
+ */
+#define HOSTENT_BUFFER_SIZE 1024
+
+/**
+ * Do not use.  Originally this was so that you can
+ * say "while (FOREVER) { ...do something... }".
+ * However, this gives a warning with some compilers (e.g. VC++).
+ * Instead, use "for (;;) { ...do something... }".
+ */
 #define FOREVER 1
 
-/* Default IP and port to listen on */
+/**
+ * Default IP address to listen on, as a string.
+ * Set to "127.0.0.1".
+ */
 #define HADDR_DEFAULT   "127.0.0.1"
-#define HADDR_PORT      8000
+
+/**
+ * Default port to listen on, as a number.
+ * Set to 8118.
+ */
+#define HADDR_PORT      8118
 
 
-/* Need this for struct gateway */
-struct client_state;
+/* Forward def for struct client_state */
+struct configuration_spec;
 
 
-struct http_request
+/**
+ * Entry in a linked list of strings.
+ */
+struct list_entry
 {
-   char *cmd;
-   char *gpc;
-   char *host;
-   int   port;
-   char *path;
-   char *ver;
-   char *hostport; /* "host[:port]" */
-   int   ssl;
+   /**
+    * The string.  The "const" is only to discourage modification,
+    * you can actually change it if you *really* want to.
+    * You can even freez() it and replace it with another
+    * malloc()d string.  If you replace it with NULL, the list
+    * functions will work, just be careful next time you iterate
+    * through the list in your own code.
+    *
+    * FIXME: Should we remove the "const"?
+    */
+   const char *str;
+   
+   /** Next entry in the linked list, or NULL if no more. */
+   struct list_entry *next;
 };
 
-
-struct gateway
+/**
+ * A header for a linked list of strings.
+ */
+struct list
 {
-   /* generic attributes */
-   char *name;
-   int (*conn)(const struct gateway *, struct http_request *, struct client_state *);
-   int   type;
+   /** First entry in the list, or NULL if the list is empty. */
+   struct list_entry *first;
 
-   /* domain specific attributes */
-   char *gateway_host;
-   int   gateway_port;
+   /** Last entry in the list, or NULL if the list is empty. */
+   struct list_entry *last;
+};
 
-   char *forward_host;
-   int   forward_port;
+
+/**
+ * An entry in a map.  This is a name=value pair.
+ */
+struct map_entry
+{
+   /** The key for the map. */
+   const char *name;
+   /** The value associated with that key. */
+   const char *value;
+   /** The next map entry, or NULL if none. */
+   struct map_entry *next;
+};
+
+/**
+ * A map from a string to another string.
+ * This is used for the paramaters passed in a HTTP GET request, and
+ * to store the exports when the CGI interface is filling in a template.
+ */
+struct map
+{
+   /** The first map entry, or NULL if the map is empty. */
+   struct map_entry *first;
+   /** The last map entry, or NULL if the map is empty. */
+   struct map_entry *last;
 };
 
 
-struct proxy_args
+/**
+ * A HTTP request.  This includes the method (GET, POST) and
+ * the parsed URL.
+ *
+ * This is also used whenever we want to match a URL against a
+ * URL pattern.  This always contains the URL to match, and never
+ * a URL pattern.  (See struct url_spec).
+ */
+struct http_request
 {
-   char *header;
-   char *invocation;
-   char *gateways;
-   char *trailer;
+   char *cmd;      /**< Whole command line: method, URL, Version */
+   char *ocmd;     /**< Backup of original cmd for CLF logging */
+   char *gpc;      /**< HTTP method: GET, POST, ... */
+   char *url;      /**< The URL */
+   char *ver;      /**< Protocol version */
+   int status;     /**< HTTP Status */
+
+   char *host;     /**< Host part of URL */
+   int   port;     /**< Port of URL or 80 (default) */
+   char *path;     /**< Path of URL */
+   char *hostport; /**< host[:port] */
+   int   ssl;      /**< Flag if protocol is https */
+
+   char *host_ip_addr_str; /**< String with dotted decimal representation
+                                of host's IP. NULL before connect_to() */
+
+   char  *dbuffer; /**< Buffer with '\0'-delimited domain name.           */
+   char **dvec;    /**< List of pointers to the strings in dbuffer.       */
+   int    dcount;  /**< How many parts to this domain? (length of dvec)   */
 };
 
 
-struct iob
+/**
+ * Response generated by CGI, blocker, or error handler
+ */
+struct http_response
+{
+  char  *status;          /**< HTTP status (string). */
+  struct list headers[1]; /**< List of header lines. */
+  char  *head;            /**< Formatted http response head. */
+  size_t head_length;     /**< Length of http response head. */
+  char  *body;            /**< HTTP document body. */
+  size_t content_length;  /**< Length of body, REQUIRED if binary body. */
+  int    is_static;       /**< Nonzero if the content will never change and
+                               should be cached by the browser (e.g. images). */
+};
+
+/**
+ * A URL pattern.
+ */
+struct url_spec
 {
-   char *buf;
-   char *cur;
-   char *eod;
+   /** The string which was parsed to produce this url_spec.
+       Used for debugging or display only.  */
+   char  *spec;
+
+   char  *dbuffer;     /**< Buffer with '\0'-delimited domain name, or NULL to match all hosts. */
+   char **dvec;        /**< List of pointers to the strings in dbuffer.       */
+   int    dcount;      /**< How many parts to this domain? (length of dvec)   */
+   int    unanchored;  /**< Bitmap - flags are ANCHOR_LEFT and ANCHOR_RIGHT.  */
+
+   int   port;         /**< The port number, or 0 to match all ports.         */
+
+   char *path;         /**< The source for the regex.                         */
+   int   pathlen;      /**< ==strlen(path).  Needed for prefix matching.  FIXME: Now obsolete?     */
+   regex_t *preg;      /**< Regex for matching path part                      */
 };
 
+/**
+ * If you declare a static url_spec, this is the value to initialize it to zero.
+ */
+#define URL_SPEC_INITIALIZER { NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL }
+
+/**
+ * Constant for host part matching in URLs.  If set, indicates that the start of
+ * the pattern must match the start of the URL.  E.g. this is not set for the
+ * pattern ".example.com", so that it will match both "example.com" and
+ * "www.example.com".  It is set for the pattern "example.com", which makes it
+ * match "example.com" only, not "www.example.com".
+ */
+#define ANCHOR_LEFT  1
 
-struct list
+/**
+ * Constant for host part matching in URLs.  If set, indicates that the end of
+ * the pattern must match the end of the URL.  E.g. this is not set for the
+ * pattern "ad.", so that it will match any host called "ad", irrespective
+ * of how many subdomains are in the fully-qualified domain name.
+ */
+#define ANCHOR_RIGHT 2
+
+
+/**
+ * An I/O buffer.  Holds a string which can be appended to, and can have data
+ * removed from the beginning.
+ */
+struct iob
 {
-   char *str;
-   struct list *last;
-   struct list *next;
+   char *buf;    /**< Start of buffer        */
+   char *cur;    /**< Start of relevant data */
+   char *eod;    /**< End of relevant data   */
+   size_t size;  /**< Size as malloc()ed     */
 };
 
+
+/**
+ * Return the number of bytes in the I/O buffer associated with the passed
+ * client_state pointer.
+ * May be zero.
+ */
 #define IOB_PEEK(CSP) ((CSP->iob->cur > CSP->iob->eod) ? (CSP->iob->eod - CSP->iob->cur) : 0)
+
+
+/**
+ * Remove any data in the I/O buffer associated with the passed
+ * client_state pointer.
+ */
 #define IOB_RESET(CSP) if(CSP->iob->buf) free(CSP->iob->buf); memset(CSP->iob, '\0', sizeof(CSP->iob));
 
+/* Bits for csp->content_type */
+#define CT_TEXT   1 /**< csp->content_type bitmask:
+                         Suitable for pcrs filtering. */
+#define CT_GIF    2 /**< csp->content_type bitmask:
+                         Suitable for GIF filtering.  */
+#define CT_TABOO  4 /**< csp->content_type bitmask:
+                         DO NOT filter, irrespective of other flags. */
+
+/**
+ * The mask which includes all actions.
+ */
+#define ACTION_MASK_ALL        (~0UL)
+
+/**
+ * The most compatible set of actions - i.e. none.
+ */
+#define ACTION_MOST_COMPATIBLE 0x00000000UL
+
+/** Action bitmap: Block the request. */
+#define ACTION_BLOCK           0x00000001UL
+/** Action bitmap: Deanimate if it's a GIF. */
+#define ACTION_DEANIMATE       0x00000002UL
+/** Action bitmap: Downgrade HTTP/1.1 to 1.0. */
+#define ACTION_DOWNGRADE       0x00000004UL
+/** Action bitmap: Fast redirects. */
+#define ACTION_FAST_REDIRECTS  0x00000008UL
+/** Action bitmap: Remove existing "Forwarded" header, and do not add another. */
+#define ACTION_HIDE_FORWARDED  0x00000010UL
+/** Action bitmap: Hide "From" header. */
+#define ACTION_HIDE_FROM       0x00000020UL
+/** Action bitmap: Hide "Referer" header.  (sic - follow HTTP, not English). */
+#define ACTION_HIDE_REFERER    0x00000040UL
+/** Action bitmap: Hide "User-Agent" and similar headers. */
+#define ACTION_HIDE_USER_AGENT 0x00000080UL
+/** Action bitmap: This is an image. */
+#define ACTION_IMAGE           0x00000100UL
+/** Action bitmap: Sets the image blocker. */
+#define ACTION_IMAGE_BLOCKER   0x00000200UL
+/** Action bitmap: Prevent compression. */
+#define ACTION_NO_COMPRESSION  0x00000400UL
+/** Action bitmap: Change cookies to session only cookies. */
+#define ACTION_NO_COOKIE_KEEP  0x00000800UL
+/** Action bitmap: Block rending cookies. */
+#define ACTION_NO_COOKIE_READ  0x00001000UL
+/** Action bitmap: Block setting cookies. */
+#define ACTION_NO_COOKIE_SET   0x00002000UL
+/** Action bitmap: Filter out popups. */
+#define ACTION_NO_POPUPS       0x00004000UL
+/** Action bitmap: Send a vanilla wafer. */
+#define ACTION_VANILLA_WAFER   0x00008000UL
+/** Action bitmap: Limit CONNECT requests to safe ports. */
+#define ACTION_LIMIT_CONNECT   0x00010000UL
+
+/** Action string index: How to deanimate GIFs */
+#define ACTION_STRING_DEANIMATE     0
+/** Action string index: Replacement for "From:" header */
+#define ACTION_STRING_FROM          1
+/** Action string index: How to block images */
+#define ACTION_STRING_IMAGE_BLOCKER 2
+/** Action string index: Replacement for "Referer:" header */
+#define ACTION_STRING_REFERER       3
+/** Action string index: Replacement for "User-Agent:" header */
+#define ACTION_STRING_USER_AGENT    4
+/** Action string index: Legal CONNECT ports. */
+#define ACTION_STRING_LIMIT_CONNECT 5
+/** Number of string actions. */
+#define ACTION_STRING_COUNT         6
+
+/** Index into current_action_spec::multi[] for headers to add. */
+#define ACTION_MULTI_ADD_HEADER     0
+/** Index into current_action_spec::multi[] for headers to add. */
+#define ACTION_MULTI_WAFER          1
+/** Index into current_action_spec::multi[] for filters to apply. */
+#define ACTION_MULTI_FILTER         2
+/** Number of multi-string actions. */
+#define ACTION_MULTI_COUNT          3
+
+
+/**
+ * This structure contains a list of actions to apply to a URL.
+ * It only contains positive instructions - no "-" options.
+ * It is not used to store the actions list itself, only for
+ * url_actions() to return the current values.
+ */
+struct current_action_spec
+{
+   /** Actions to apply.  A bit set to "1" means perform the action. */
+   unsigned long flags;
+
+   /**
+    * Paramaters for those actions that require them.
+    * Each entry is valid if & only if the corresponding entry in "flags" is
+    * set.
+    */
+   char * string[ACTION_STRING_COUNT];
 
-/* Constants defining bitmask for csp->accept_types */
+   /** Lists of strings for multi-string actions. */
+   struct list multi[ACTION_MULTI_COUNT][1];
+};
 
-#ifdef DETECT_MSIE_IMAGES
 
-/* MSIE detected by user-agent string */
-#define ACCEPT_TYPE_IS_MSIE     0x0001
+/**
+ * This structure contains a set of changes to actions.
+ * It can contain both positive and negative instructions.
+ * It is used to store an entry in the actions list.
+ */
+struct action_spec
+{
+   unsigned long mask; /**< Actions to keep. A bit set to "0" means remove action. */
+   unsigned long add;  /**< Actions to add.  A bit set to "1" means add action.    */
 
-/*
- * *If* this is MSIE, it wants an image.  (Or this is a shift-reload, or
- * it's got an image from this URL before...  yuck!)
- * Only meaningful if ACCEPT_TYPE_IS_MSIE set 
+   /**
+    * Paramaters for those actions that require them.
+    * Each entry is valid if & only if the corresponding entry in "flags" is
+    * set.
+    */
+   char * string[ACTION_STRING_COUNT];
+
+   /** Lists of strings to remove, for multi-string actions. */
+   struct list multi_remove[ACTION_MULTI_COUNT][1];
+
+   /** If nonzero, remove *all* strings from the multi-string action. */
+   int         multi_remove_all[ACTION_MULTI_COUNT];
+
+   /** Lists of strings to add, for multi-string actions. */
+   struct list multi_add[ACTION_MULTI_COUNT][1];
+};
+
+
+/**
+ * This structure is used to store the actions list.
+ *
+ * It contains a URL pattern, and the chages to the actions.
+ * It is a linked list.
  */
-#define ACCEPT_TYPE_MSIE_IMAGE  0x0002
+struct url_actions
+{
+   struct url_spec url[1];        /**< URL pattern. */
+
+   struct action_spec action[1];  /**< Actions. */
+
+   struct url_actions * next;     /**< Next action in file, or NULL. */
+};
+
 
 /*
- * *If* this is MSIE, it wants a HTML document.
- * Only meaningful if ACCEPT_TYPE_IS_MSIE set
+ * Flags for use in csp->flags
+ */
+/**
+ * Flag for csp->flags: Set if this client is processing data.
+ * Cleared when the thread associated with this structure dies.
  */
-#define ACCEPT_TYPE_MSIE_HTML   0x0004
+#define CSP_FLAG_ACTIVE     0x01
 
-#endif /* def DETECT_MSIE_IMAGES */
+/**
+ * Flag for csp->flags: Set if the server's reply is in "chunked"
+ * transfer encoding
+ */
+#define CSP_FLAG_CHUNKED    0x02
+
+/**
+ * Flag for csp->flags: Set if this request was enforced, although it would
+ * normally have been blocked.
+ */
+#define CSP_FLAG_FORCED     0x04
 
+/**
+ * Flag for csp->flags: Set if any modification to the body was done.
+ */
+#define CSP_FLAG_MODIFIED   0x08
+
+/**
+ * Flag for csp->flags: Set if request was blocked.
+ */
+#define CSP_FLAG_REJECTED   0x10
+
+/**
+ * Flag for csp->flags: Set if we are toggled on (FEATURE_TOGGLE).
+ */
+#define CSP_FLAG_TOGGLED_ON 0x20
+
+
+/**
+ * Maximum number of actions files.  This limit is arbitrary - it's just used
+ * to size an array.
+ */
+#define MAX_ACTION_FILES 10
 
+/**
+ * The state of a Privoxy processing thread.
+ */
 struct client_state
 {
-   int  send_user_cookie;
-   int  accept_server_cookie;
-   int  cfd;
-   int  sfd;
-
-#ifdef STATISTICS
-   /* 1 if this URL was rejected, 0 otherwise. Allows actual stats inc to 
-    * occur in main thread only for thread-safety. 
-    */
-   int  rejected;
-#endif /* def STATISTICS */
-
-#ifdef FORCE_LOAD
-   int force;
-#endif /* def FORCE_LOAD */
-
-#ifdef TOGGLE
-   /*
-    * by haroon - most of credit to srt19170
-    * We add an "on/off" toggle here that is used to effectively toggle
-    * the Junkbuster off or on
-    */
-   int   toggled_on;
-#endif
+   /** The proxy's configuration */
+   struct configuration_spec * config;
+
+   /** The actions to perform on the current request */
+   struct current_action_spec  action[1];
+
+   /** socket to talk to client (web browser) */
+   jb_socket cfd;
 
+   /** socket to talk to server (web server or proxy) */
+   jb_socket sfd;
+
+   /** Multi-purpose flag container, see CSP_FLAG_* above */
+   unsigned short int flags;
+
+   /** Client PC's IP address, as reported by the accept() function.
+       As a string. */
    char *ip_addr_str;
+   /** Client PC's IP address, as reported by the accept() function.
+       As a number. */
    long  ip_addr_long;
-   char *referrer;
 
-#if defined(DETECT_MSIE_IMAGES)
-   /* Types the client will accept.
-    * Bitmask - see ACCEPT_TYPE_XXX constants.
-    */
-   int accept_types;
-#endif /* defined(DETECT_MSIE_IMAGES) */
+   /** Our IP address. I.e. the IP address that the client used to reach us,
+       as a string. */
+   char *my_ip_addr_str;
 
-   const struct gateway *gw;
+   /** Our hostname. I.e. the reverse DNS of the IP address that the client
+       used to reach us, as a string. */
+   char *my_hostname;
+
+   /** The URL that was requested */
    struct http_request http[1];
 
+   /** An I/O buffer used for buffering data read from the network */
    struct iob iob[1];
 
+   /** List of all headers for this request */
    struct list headers[1];
+
+   /** List of all cookies for this request */
    struct list cookie_list[1];
-#ifdef PCRS
-   int is_text;
-#endif /* def PCRS */
 
-   char   *x_forwarded;
+   /** MIME-Type key, see CT_* above */
+   unsigned short int content_type;
 
-   int active;
+   /** The "X-Forwarded-For:" header sent by the client */
+   char   *x_forwarded;
 
-   /* files associated with this client */
-   struct file_list *blist;   /* blockfile */
-   struct file_list *clist;   /* cookiefile */
-   struct file_list *flist;   /* forwardfile */
+   /** Actions files associated with this client */
+   struct file_list *actions_list[MAX_ACTION_FILES];
 
-#ifdef ACL_FILES
-   struct file_list *alist;   /* aclfile */
-#endif /* def ACL_FILES */
+   /** pcrs job file. */
+   struct file_list *rlist;
 
-#ifdef USE_IMAGE_LIST
-   struct file_list *ilist;   /* imagefile */
-#endif /* def USE_IMAGE_LIST */
+   /** Length after content modification. */
+   size_t content_length;
 
-#ifdef KILLPOPUPS
-   struct file_list *plist;   /* kill popup file */
-#endif /* def KILLPOPUPS */
+#ifdef FEATURE_TRUST
 
-#ifdef PCRS
-     struct file_list *rlist;   /* Perl re_filterfile */
-#endif /* def PCRS */
+   /** Trust file. */
+   struct file_list *tlist;
 
-#ifdef TRUST_FILES
-   struct file_list *tlist;   /* trustfile */
-#endif /* def TRUST_FILES */
+#endif /* def FEATURE_TRUST */
 
+   /** Next thread in linked list. Only read or modify from the main thread! */
    struct client_state *next;
 };
 
 
+/**
+ * A function to add a header
+ */
+typedef jb_err (*add_header_func_ptr)(struct client_state *);
+
+/**
+ * A function to process a header
+ */
+typedef jb_err (*parser_func_ptr    )(struct client_state *, char **);
+
+
+/**
+ * List of functions to run on a list of headers
+ */
 struct parsers
 {
-   char *str;
-   char  len;
-   char *(*parser)(const struct parsers *, char *, struct client_state *);
+   /** The header prefix to match */
+   char   *str;
+   
+   /** The length of the prefix to match */
+   size_t len;
+   
+   /** The function to apply to this line */
+   parser_func_ptr parser;
 };
 
 
-struct interceptors
+/**
+ * List of available CGI functions.
+ */
+struct cgi_dispatcher
 {
-   char *str;
-   char  len;
-   char *(*interceptor)(struct http_request *http, struct client_state *csp);
-};
-
+   /** The URL of the CGI, relative to the CGI root. */
+   const char * const name;
 
-/* this allows the proxy to permit/block access to any host and/or path */
+   /** The handler function for the CGI */
+   jb_err    (* const handler)(struct client_state *csp, struct http_response *rsp, const struct map *parameters);
 
-struct url_spec
-{
-   char  *spec;
-   char  *domain;
-   char  *dbuf;
-   char **dvec;
-   int    dcnt;
-   int    toplevel;
-
-   char *path;
-   int   pathlen;
-   int   port;
-#ifdef REGEX
-   regex_t *preg;
-#endif
+   /** The description of the CGI, to appear on the main menu, or NULL to hide it. */
+   const char * const description;
 };
 
 
+/**
+ * A data file used by Privoxy.  Kept in a linked list.
+ */
 struct file_list
 {
-   /*
-    * this is a pointer to the data structures associated with the file.
+   /**
+    * This is a pointer to the data structures associated with the file.
     * Read-only once the structure has been created.
     */
    void *f;
-   
-   /* Normally NULL.  When we are finished with file (i.e. when we have
+
+   /**
+    * The unloader function.
+    * Normally NULL.  When we are finished with file (i.e. when we have
     * loaded a new one), set to a pointer to an unloader function.
     * Unloader will be called by sweep() (called from main loop) when
-    * all clients using this file are done.  This prevents threading 
+    * all clients using this file are done.  This prevents threading
     * problems.
     */
    void (*unloader)(void *);
 
-   /* Used internally by sweep().  Do not access from elsewhere. */
-   int active;
-
-#ifndef SPLIT_PROXY_ARGS
-   /* String to be displayed as part of show-proxy-args display.
-    * Read-only once the structure has been created.
+   /**
+    * Used internally by sweep().  Do not access from elsewhere.
     */
-   char *proxy_args;
-#endif /* ndef SPLIT_PROXY_ARGS */
+   int active;
 
-   /* Following variables allow us to check if file has been changed.
+   /**
+    * File last-modified time, so we can check if file has been changed.
     * Read-only once the structure has been created.
     */
    time_t lastmodified;
+   
+   /**
+    * The full filename.
+    */
    char * filename;
 
-   /* Pointer to next entry in the linked list of all "file_list"s.
+   /**
+    * Pointer to next entry in the linked list of all "file_list"s.
     * This linked list is so that sweep() can navigate it.
     * Since sweep() can remove items from the list, we must be careful
     * to only access this value from main thread (when we know sweep
@@ -340,105 +1136,295 @@ struct file_list
 };
 
 
+#ifdef FEATURE_TRUST
+
+/**
+ * The format of a trust file when loaded into memory.
+ */
 struct block_spec
 {
-   struct url_spec url[1];
-   int   reject;
-   struct block_spec *next;
+   struct url_spec url[1];   /**< The URL pattern              */
+   int    reject;            /**< FIXME: Please document this! */
+   struct block_spec *next;  /**< Next entry in linked list    */
 };
 
+#endif /* def FEATURE_TRUST */
 
-struct cookie_spec
-{
-   struct url_spec url[1];
-   int   send_user_cookie;
-   int   accept_server_cookie;
-   struct cookie_spec *next;
-};
+
+#define SOCKS_NONE    0    /**< Don't use a SOCKS server               */
+#define SOCKS_4      40    /**< original SOCKS 4 protocol              */
+#define SOCKS_4A     41    /**< as modified for hosts w/o external DNS */
 
 
+/**
+ * How to forward a connection to a parent proxy.
+ */
 struct forward_spec
 {
+   /** URL pattern that this forward_spec is for. */
    struct url_spec url[1];
-   int   reject;
-   struct gateway gw[1];
+
+   /** Connection type.  Must be SOCKS_NONE, SOCKS_4, or SOCKS_4A. */
+   int   type;
+
+   /** SOCKS server hostname.  Only valid if "type" is SOCKS_4 or SOCKS_4A. */
+   char *gateway_host;
+
+   /** SOCKS server port. */
+   int   gateway_port;
+
+   /** Parent HTTP proxy hostname, or NULL for none. */
+   char *forward_host;
+
+   /** Parent HTTP proxy port. */
+   int   forward_port;
+
+   /** Next entry in the linked list. */
    struct forward_spec *next;
 };
 
 
-#ifdef PCRS
+/**
+ * Initializer for a static struct forward_spec.
+ */
+#define FORWARD_SPEC_INITIALIZER { { URL_SPEC_INITIALIZER }, 0, NULL, 0, NULL, 0, NULL }
+
+
+/**
+ * This struct represents one filter (one block) from
+ * the re_filterfile. If there is more than one filter
+ * in the file, the file will be represented by a
+ * chained list of re_filterfile specs.
+ */
 struct re_filterfile_spec
 {
-   struct list patterns[1];
-   /* See README.re_filter */
-   pcrs_job *joblist;
+   char *name;                      /**< Name from FILTER: statement in re_filterfile. */
+   char *description;               /**< Description from FILTER: statement in re_filterfile. */
+   struct list patterns[1];         /**< The patterns from the re_filterfile. */
+   pcrs_job *joblist;               /**< The resulting compiled pcrs_jobs. */
+   struct re_filterfile_spec *next; /**< The pointer for chaining. */
 };
-#endif /* def PCRS */
 
 
-#ifdef KILLPOPUPS
-/* Entries on popup blocklist */
-struct popup_blocklist
+#ifdef FEATURE_ACL
+
+#define ACL_PERMIT   1  /**< Accept connection request */
+#define ACL_DENY     2  /**< Reject connection request */
+
+/**
+ * An IP address pattern.  Used to specify networks in the ACL.
+ */
+struct access_control_addr
 {
-   char *host_name;
-   struct popup_blocklist *next;
+   unsigned long addr;  /**< The IP address as an integer. */
+   unsigned long mask;  /**< The network mask as an integer. */
+   unsigned long port;  /**< The port number. */
 };
 
-/* Actual type used in file object */
-struct popup_settings
+/**
+ * An access control list (ACL) entry.
+ *
+ * This is a linked list.
+ */
+struct access_control_list
 {
-   struct popup_blocklist *blocked;
-   struct popup_blocklist *allowed;
+   struct access_control_addr src[1];  /**< Client IP address */
+   struct access_control_addr dst[1];  /**< Website or parent proxy IP address */
+
+   short action;                       /**< ACL_PERMIT or ACL_DENY */
+   struct access_control_list *next;   /**< The next entry in the ACL. */
 };
-#endif /* def KILLPOPUPS */
 
-#ifdef ACL_FILES
-#define ACL_PERMIT   1  /* accept connection request */
-#define ACL_DENY     2  /* reject connection request */
+#endif /* def FEATURE_ACL */
 
-struct access_control_addr
-{
-   unsigned long addr;
-   unsigned long mask;
-   unsigned long port;
-};
 
-struct access_control_list
+/** Maximum number of loaders (actions, re_filter, ...) */
+#define NLOADERS 8
+
+
+/** configuration_spec::feature_flags: CGI actions editor. */
+#define RUNTIME_FEATURE_CGI_EDIT_ACTIONS  1
+
+/** configuration_spec::feature_flags: Web-based toggle. */
+#define RUNTIME_FEATURE_CGI_TOGGLE        2
+
+
+/**
+ * Data loaded from the configuration file.
+ *
+ * (Anomaly: toggle is still handled through a global, not this structure)
+ */
+struct configuration_spec
 {
-   struct access_control_addr src[1];
-   struct access_control_addr dst[1];
+   /** What to log */
+   int debug;
+   
+   /** Nonzero to enable multithreading. */
+   int multi_threaded;
+
+   /**
+    * Bitmask of features that can be enabled/disabled through the config
+    * file.  Currently defined bits:
+    *
+    * - RUNTIME_FEATURE_CGI_EDIT_ACTIONS
+    * - RUNTIME_FEATURE_CGI_TOGGLE
+    */
+   unsigned feature_flags;
+
+   /** The log file name. */
+   const char *logfile;
+
+   /** The config file directory. */
+   const char *confdir;
+
+   /** The log file directory. */
+   const char *logdir;
+
+   /** The full paths to the actions files. */
+   const char *actions_file[MAX_ACTION_FILES];
+
+   /** The short names of the actions files. */
+   const char *actions_file_short[MAX_ACTION_FILES];
 
-   short action;
-   struct access_control_list *next;
+   /** The administrator's email address */
+   char *admin_address;
+
+   /** A URL with info on this proxy */
+   char *proxy_info_url;
+
+   /** URL to the user manual (on our website or local copy) */
+   char *usermanual;
+
+   /** The file name of the pcre filter file */
+   const char *re_filterfile;
+
+#ifdef FEATURE_COOKIE_JAR
+
+   /** The file name of the cookie jar file */
+   const char * jarfile;
+
+   /** The handle to the cookie jar file */
+   FILE * jar;
+
+#endif /* def FEATURE_COOKIE_JAR */
+
+   /** IP address to bind to.  Defaults to HADDR_DEFAULT == 127.0.0.1. */
+   const char *haddr;
+
+   /** Port to bind to.  Defaults to HADDR_PORT == 8118. */
+   int         hport;
+
+   /** Size limit for IOB */
+   size_t buffer_limit;
+
+#ifdef FEATURE_TRUST
+
+   /** The file name of the trust file. */
+   const char * trustfile;
+
+   /** FIXME: DOCME: Document this. */
+   struct list trust_info[1];
+
+   /** FIXME: DOCME: Document this. */
+   struct url_spec *trust_list[64];
+
+#endif /* def FEATURE_TRUST */
+
+#ifdef FEATURE_ACL
+
+   /** The access control list (ACL). */
+   struct access_control_list *acl;
+
+#endif /* def FEATURE_ACL */
+
+   /** Information about parent proxies (forwarding). */
+   struct forward_spec *forward;
+
+   /** All options from the config file, HTML-formatted. */
+   char *proxy_args;
+
+   /** The configuration file object. */
+   struct file_list *config_file_list;
+
+   /** List of loaders */
+   int (*loaders[NLOADERS])(struct client_state *);
+
+   /** Nonzero if we need to bind() to the new port. */
+   int need_bind;
 };
-#endif /* def ACL_FILES */
 
+/** Calculates the number of elements in an array, using sizeof. */
 #define SZ(X)  (sizeof(X) / sizeof(*X))
 
-#define WHITEBG   "<body bgcolor=\"#ffffff\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
-#define BODY      "<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
-#define BANNER    "<strong>Internet J<small>UNK<i><font color=\"red\">BUSTER</font></i></small></strong>"
-
-#ifdef FORCE_LOAD
-/*\r
- * FIXME: Unfortunately, IE lowercases the domain name.  JunkBuster does\r
- * a case-sensitive compare.  JunkBuster should be modified to do a\r
- * case-insensitive compatison.  As a temporary workaround, I've lowercased\r
- * the FORCE_PREFIX.\r
- *\r
- * #define FORCE_PREFIX "IJB-FORCE-LOAD-"\r
- */\r
-#define FORCE_PREFIX "ijb-force-load-"\r
-#endif /* def FORCE_LOAD */
-
-#define HOME_PAGE_URL  "http://ijbswa.sourceforge.net/"
-#define REDIRECT_URL HOME_PAGE_URL "redirect.php?v=" VERSION "&to="
+#ifdef FEATURE_FORCE_LOAD
+/** The force load URL prefix. */
+#define FORCE_PREFIX "/PRIVOXY-FORCE"
+#endif /* def FEATURE_FORCE_LOAD */
+
+#ifdef FEATURE_NO_GIFS
+/** The MIME type for images ("image/png" or "image/gif"). */
+#define BUILTIN_IMAGE_MIMETYPE "image/png"
+#else
+#define BUILTIN_IMAGE_MIMETYPE "image/gif"
+#endif /* def FEATURE_NO_GIFS */
+
+
+/* 
+ * Hardwired URLs
+ */
+
+/** URL for the Privoxy home page. */
+#define HOME_PAGE_URL     "http://www.privoxy.org/"
+
+/** URL for the Privoxy user manual. */
+#define USER_MANUAL_URL   HOME_PAGE_URL "/" VERSION "/user-manual/"
+
+/** Prefix for actions help links  (append to USER_MANUAL_URL). */
+#define ACTIONS_HELP_PREFIX "actions-file.html#"
+
+/** Prefix for config option help links (append to USER_MANUAL_URL). */
+#define CONFIG_HELP_PREFIX  "config.html#"
+
+/*
+ * The "hosts" to intercept and display CGI pages.
+ * First one is a hostname only, second one can specify host and path.
+ *
+ * Notes:
+ * 1) Do not specify the http: prefix
+ * 2) CGI_SITE_2_PATH must not end with /, one will be added automatically.
+ * 3) CGI_SITE_2_PATH must start with /, unless it is the empty string.
+ */
+#define CGI_SITE_1_HOST "p.p"
+#define CGI_SITE_2_HOST "config.privoxy.org"
+#define CGI_SITE_2_PATH ""
+
+/**
+ * The prefix for CGI pages.  Written out in generated HTML.
+ * INCLUDES the trailing slash.
+ */
+#define CGI_PREFIX  "http://" CGI_SITE_2_HOST CGI_SITE_2_PATH "/"
+
+
+/* HTTP snipplets.
+ *
+ * FIXME: This is very inefficient.  There could be one copy of these strings
+ * for each .c file!!  They should be "extern", not "static".
+ */
+static const char CSUCCEED[] =
+   "HTTP/1.0 200 Connection established\n"
+   "Proxy-Agent: Privoxy/" VERSION "\r\n\r\n";
+
+static const char CHEADER[] =
+   "HTTP/1.0 400 Invalid header received from browser\r\n\r\n";
+
+static const char CFORBIDDEN[] =
+   "HTTP/1.0 403 Connection not allowable\r\nX-Hint: If you read this message interactively, then you know why this happens ,-)\r\n\r\n";
 
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
 
-#endif /* ndef _PROJECT_H */
+#endif /* ndef PROJECT_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/re_filterfile b/re_filterfile
deleted file mode 100644 (file)
index 16c073b..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-# Filterfile for the Regular Substitution Module
-#
-# Syntax: One Perl-Style substitution per line.
-# For Details see the perlre, perlop and pcre manpages.
-# Note that you are free to choose the delimter as you
-# see fit.
-#
-
-# Kill OnUnload popups. Yummy.
-# check it out on http://www.zdnet.com/zdsubs/yahoo/tree/yfs.html
-#
-s/(<body .*?)onunload(.*?>)/$1never$2/i
-
-# Kill refresh tags. I like to refresh myself. Manually.
-# check it out on http://www.airport-cgn.de/ and go to the arrivals page.
-#
-s/<meta[^>]*http-equiv[^>]*refresh[^>]*>/<!--no refresh for me-->/i
-s/<meta[^>]*http-equiv="?page-enter"?[^>]*content=[^>]*>/<!--no page enter for me-->/i
-
-# If I allow popups, I want them to be rezizable and have a location and status bar:
-# check it out on http://www.airport-cgn.de/ and go to the arrivals page.
-#
-s/resizable="?(no|0)"?/resizable=1/ig
-s/noresize/yesresize/ig
-s/location="?(no|0)"?/location=1/ig
-s/status="?(no|0)"?/status=1/ig
-s/scrolling="?(no|0|Auto)"?/scrolling=1/ig
-s/menubar="?(no|0)"?/menubar=1/ig
-#s/framespacing="?(no|0)"?//ig
-#s/margin(height|width)=[0-9]*//gi
-
-# Remove frameborder=0 and border=0 from framesets
-s/(<frameset[ -z]+)(frame)?border="?(no|0)"?/$1/ig
-
-# The status bar is for displaying link targets, not pointless buzzwords.
-# Again, check it out on http://www.airport-cgn.de/
-#
-s/status='.*?';*//ig
-
-# Kill *all* popups a la popup.c. (But for *all* sites, so I wouldn't do that.)
-#
-# JavaScript: s/window\.open\(/who_wants_this_to.open(/ig
-# HTML      : s/target="?_blank"?/target_who/g
-
-# Fun stuff:
-#
-s/microsoft(?!.com)/<b>MicroSuck<\/b>/ig
-
-# Crude parental filtering?  (Use along with a suitable blocklist).
-# Shows how to deny access to whole page based on a keyword.
-#
-# (Note: Middlesex, Sussex and Essex are counties in the UK, not rude words)
-# (Note #2: Is 'sex' a rude word?!)
-#
-#s%^.*(?<!middle)(?<!sus)(?<!es)sex.*$%<html><head><title>Blocked</title></head><body><h3>Blocked due to possible adult content. Please see <a href="http://dmoz.org/Kids_and_Teens/">this site</a>.</h3></body></html>%is
-#s+^.*warez.*$+<html><head><title>No Warez</title></head><body><h3>You're not searching for illegal stuff, are you?</h3></body></html>+is
-
-# http://www.farscapezone.com/wwwboard/messages/1451.html
-s/(\w+) was tired/<b>$1 needed more coffee<\/b>/ig
-
-# I'm sure you'll find more uses.
-# Please send your cool additions to junkbuster-users@yahoogroups.com
diff --git a/showargs.c b/showargs.c
deleted file mode 100644 (file)
index 0a7cc2c..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-const char showargs_rcs[] = "$Id: showargs.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
-/*********************************************************************
- *
- * File        :  $Source: /home/administrator/cvs/ijb/showargs.c,v $
- *
- * Purpose     :  Contains various utility routines needed to 
- *                generate the show-proxy-args page.
- *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
- *
- *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
- *                Junkbusters Corporation.  http://www.junkbusters.com
- *
- *                This program is free software; you can redistribute it 
- *                and/or modify it under the terms of the GNU General
- *                Public License as published by the Free Software
- *                Foundation; either version 2 of the License, or (at
- *                your option) any later version.
- *
- *                This program is distributed in the hope that it will
- *                be useful, but WITHOUT ANY WARRANTY; without even the
- *                implied warranty of MERCHANTABILITY or FITNESS FOR A
- *                PARTICULAR PURPOSE.  See the GNU General Public
- *                License for more details.
- *
- *                The GNU General Public License should be included with
- *                this file.  If not, you can view it at
- *                http://www.gnu.org/copyleft/gpl.html
- *                or write to the Free Software Foundation, Inc., 59
- *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Revisions   :
- *    $Log: showargs.c,v $
- *
- *********************************************************************/
-\f
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <malloc.h>
-#include <errno.h>
-
-#include "showargs.h"
-#include "jcc.h"
-#include "encode.h"
-#include "parsers.h"
-#include "errlog.h"
-#include "miscutil.h"
-#include "gateway.h"
-
-const char showargs_h_rcs[] = SHOWARGS_H_VERSION;
-
-/*********************************************************************
- *
- * Function    :  strsav
- *
- * Description :  Reallocate "old" and append text to it.  This makes
- *                it easier to append to malloc'd strings.
- *
- * Parameters  :
- *          1  :  old = Old text that is to be extended.  Will be
- *                free()d by this routine.
- *          2  :  text_to_append = Text to be appended to old.
- *
- * Returns     :  Pointer to newly malloc'ed appended string.
- *                If there is no text to append, return old.  Caller
- *                must free().
- *
- *********************************************************************/
-char *strsav(char *old, const char *text_to_append)
-{
-   int old_len, new_len;
-   char *p;
-
-   if (( text_to_append == NULL) || (*text_to_append == '\0'))
-   {
-      return(old);
-   }
-
-   if (NULL != old)
-   {
-      old_len = strlen(old);
-   }
-   else
-   {
-      old_len = 0;
-   }
-
-   new_len = old_len + strlen(text_to_append) + 1;
-
-   if (old)
-   {
-      if ((p = realloc(old, new_len)) == NULL)
-      {
-         log_error(LOG_LEVEL_ERROR, "realloc(%d) bytes for proxy_args failed!", new_len);
-         exit(1);
-      }
-   }
-   else
-   {
-      if ((p = (char *)malloc(new_len)) == NULL)
-      {
-         log_error(LOG_LEVEL_ERROR, "malloc(%d) bytes for proxy_args failed!", new_len);
-         exit(1);
-      }
-   }
-
-   strcpy(p + old_len, text_to_append);
-   return(p);
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  savearg
- *
- * Description :  Called from `load_config'.  It saves each non-empty
- *                and non-comment line from config into a list.  This
- *                list is used to create the show-proxy-args page.
- *
- * Parameters  :
- *          1  :  c = config setting that was found
- *          2  :  o = the setting's argument (if any)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-void savearg(char *c, char *o)
-{
-   char buf[BUFSIZ];
-
-   *buf = '\0';
-
-   if ( ( NULL != c ) && ( '\0' != *c ) )
-   {
-      if ((c = html_encode(c)))
-      {
-         sprintf(buf, "<a href=\"" REDIRECT_URL "option#%s\">%s</a> ", c, c);
-      }
-      freez(c);
-   }
-   if ( ( NULL != o ) && ( '\0' != *o ) )
-   {
-      if ((o = html_encode(o)))
-      {
-         if (strncmpic(o, "http://", 7) == 0)
-         {
-            strcat(buf, "<a href=\"");
-            strcat(buf, o);
-            strcat(buf, "\">");
-            strcat(buf, o);
-            strcat(buf, "</a>");
-         }
-         else
-         {
-            strcat(buf, o);
-         }
-      }
-      freez(o);
-   }
-
-   strcat(buf, "<br>\n");
-
-   proxy_args->invocation = strsav(proxy_args->invocation, buf);
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  init_proxy_args
- *
- * Description :  Create the "top" of the show-proxy-args page.
- *
- * Parameters  :
- *          1  :  argc = argument count (same as in main)
- *          2  :  argv[] = program arguments (same as in main)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-void init_proxy_args(int argc, const char *argv[])
-{
-   const struct gateway *g;
-   int i;
-
-   freez(proxy_args->header);
-   freez(proxy_args->invocation);
-   freez(proxy_args->gateways);
-   freez(proxy_args->trailer);
-   
-
-   proxy_args->header = strsav(proxy_args->header,
-      "HTTP/1.0 200 OK\n"
-      "Server: IJ/" VERSION "\n"
-      "Content-type: text/html\n\n"
-
-      "<html>"
-      "<head>"
-      "<title>Internet Junkbuster Proxy Status</title>"
-      "</head>\n"
-      "<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
-      "<center>\n"
-      "<h1>" BANNER "\n"
-      "<a href=\"" REDIRECT_URL "faq#show\">Proxy Status</a>\n"
-      "</h1></center>\n"
-      "<h2>You are using the " BANNER " <sup><small><small>TM</small></small></sup></h2>\n"
-      "Version: " VERSION "\n"
-      "<br>Home page: <a href=\"" HOME_PAGE_URL "\">" HOME_PAGE_URL "</a>\n"\r
-      "<p>\n"
-   );
-
-   proxy_args->header = strsav(proxy_args->header,
-      "<h2>The program was invoked as follows</h2>\n");
-
-   for (i=0; i < argc; i++)
-   {
-      proxy_args->header = strsav(proxy_args->header, argv[i]);
-      proxy_args->header = strsav(proxy_args->header, " ");
-   }
-   proxy_args->header = strsav(proxy_args->header, "<br>\n");
-
-
-   proxy_args->invocation = strsav(
-      proxy_args->invocation,
-      "<br>\n"
-      "and the following options were set in the configuration file"
-      "<br><br>\n"
-   );
-
-
-   proxy_args->gateways = strsav(proxy_args->gateways,
-      "<h2>It supports the following gateway protocols:</h2>\n");
-
-   for (g = gateways; g->name; g++)
-   {
-      proxy_args->gateways = strsav(proxy_args->gateways, g->name);
-      proxy_args->gateways = strsav(proxy_args->gateways, " ");
-   }
-   proxy_args->gateways = strsav(proxy_args->gateways, "<br>\n");
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  end_proxy_args
- *
- * Description :  Create the "bottom" of the show-proxy-args page.
- *
- * Parameters  :  None
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-void end_proxy_args(void)
-{
-   char *b = NULL;
-   char buf[BUFSIZ];
-
-   /* Instead of including *all* dot h's in the project (thus creating a
-    * tremendous amount of dependencies), I will concede to declaring them
-    * as extern's.  This forces the developer to add to this list, but oh well.
-    */
-
-#ifndef SPLIT_PROXY_ARGS
-   if (suppress_blocklists && suppress_message!=NULL)
-   {
-      b = strsav(b, "<h2>File contents</h2>\n");
-      b = strsav(b, suppress_message);
-      b = strsav(b, "\n");
-   }
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-   b = strsav(b, "<h2>Source versions:</h2>\n");
-   b = strsav(b, "<pre>");
-
-#define SHOW_RCS(__x)            \
-   {                             \
-      extern const char __x[];   \
-      sprintf(buf, "%s\n", __x); \
-      b = strsav(b, buf);        \
-   }
-
-   /* In alphabetical order */
-#ifdef __MINGW32__
-   SHOW_RCS(cygwin_h_rcs)
-#endif
-   SHOW_RCS(encode_h_rcs)
-   SHOW_RCS(encode_rcs)
-   SHOW_RCS(errlog_h_rcs)
-   SHOW_RCS(errlog_rcs)
-   SHOW_RCS(filters_h_rcs)
-   SHOW_RCS(filters_rcs)
-   SHOW_RCS(gateway_h_rcs)
-   SHOW_RCS(gateway_rcs)
-#ifdef GNU_REGEX
-   SHOW_RCS(gnu_regex_h_rcs)
-   SHOW_RCS(gnu_regex_rcs)
-#endif /* def GNU_REGEX */
-   SHOW_RCS(jbsockets_h_rcs)
-   SHOW_RCS(jbsockets_rcs)
-   SHOW_RCS(jcc_h_rcs)
-   SHOW_RCS(jcc_rcs)
-#ifdef KILLPOPUPS
-   SHOW_RCS(killpopup_h_rcs)
-   SHOW_RCS(killpopup_rcs)
-#endif /* def KILLPOPUPS */
-   SHOW_RCS(loadcfg_h_rcs)
-   SHOW_RCS(loadcfg_rcs)
-   SHOW_RCS(loaders_h_rcs)
-   SHOW_RCS(loaders_rcs)
-   SHOW_RCS(miscutil_h_rcs)
-   SHOW_RCS(miscutil_rcs)
-   SHOW_RCS(parsers_h_rcs)
-   SHOW_RCS(parsers_rcs)
-#ifdef PCRS
-   SHOW_RCS(pcrs_rcs)
-   SHOW_RCS(pcrs_h_rcs)
-#endif /* def PCRS */
-   SHOW_RCS(project_h_rcs)
-   SHOW_RCS(showargs_h_rcs)
-   SHOW_RCS(showargs_rcs)
-   SHOW_RCS(ssplit_h_rcs)
-   SHOW_RCS(ssplit_rcs)
-#ifdef _WIN32
-   SHOW_RCS(w32log_h_rcs)
-   SHOW_RCS(w32log_rcs)
-   SHOW_RCS(w32res_h_rcs)
-   SHOW_RCS(w32rulesdlg_h_rcs)
-   SHOW_RCS(w32rulesdlg_rcs)
-   SHOW_RCS(w32taskbar_h_rcs)
-   SHOW_RCS(w32taskbar_rcs)
-   SHOW_RCS(win32_h_rcs)
-   SHOW_RCS(win32_rcs)
-#endif /* def _WIN32 */
-
-#undef SHOW_RCS
-
-   b = strsav(b, "</pre>\n");
-
-   b = strsav(b, "<h2>Conditional defines:</h2>\n<ul>");
-
-#ifdef REGEX
-   b = strsav(b, "  <li><code>#define <b>REGEX</b></code> - Support for regular expressions in the path specs.</li>\n");
-#else /* ifndef REGEX */
-   b = strsav(b, "  <li><code>#undef <b>REGEX</b></code> - No support for regular expressions in the path specs.</li>\n");
-#endif /* ndef REGEX */
-\r
-#ifdef PCRE\r
-   b = strsav(b, "  <li><code>#define <b>PCRE</b></code> - Use PCRE rather than old GNU regex library.</li>\n");\r
-#else /* ifndef PCRE */\r
-   b = strsav(b, "  <li><code>#undef <b>PCRE</b></code> - Use old GNU regex library rather than PCRE.</li>\n");\r
-#endif /* ndef PCRE */\r
-
-#ifdef PCRS
-   b = strsav(b, "  <li><code>#define <b>PCRS</b></code> - Enables arbitrary content modification regexps.</li>\n");
-#else /* ifndef PCRS */
-   b = strsav(b, "  <li><code>#undef <b>PCRS</b></code> - Disables arbitrary content modification regexps.</li>\n");
-#endif /* ndef PCRS */
-\r
-#ifdef TOGGLE\r
-   b = strsav(b, "  <li><code>#define <b>TOGGLE</b></code> - Allow JunkBuster to be \"disabled\" so it is just a normal non-blocking non-anonymizing proxy.</li>\n");\r
-#else /* ifndef TOGGLE */\r
-   b = strsav(b, "  <li><code>#undef <b>TOGGLE</b></code> - Do not allow JunkBuster to be \"disabled\" so it is just a normal non-blocking non-anonymizing proxy.</li>\n");\r
-#endif /* ndef TOGGLE */\r
-\r
-#ifdef FORCE_LOAD\r
-   b = strsav(b, "  <li><code>#define <b>FORCE_LOAD</b></code> - Enables bypassing filtering for a single page using the prefix \"" FORCE_PREFIX "\".</li>\n");\r
-#else /* ifndef FORCE_LOAD */\r
-   b = strsav(b, "  <li><code>#undef <b>FORCE_LOAD</b></code> - Disables bypassing filtering for a single page.</li>\n");\r
-#endif /* ndef FORCE_LOAD */\r
-
-#ifdef DENY_GZIP
-   b = strsav(b, "  <li><code>#define <b>DENY_GZIP</b></code> - Prevents requests from being compressed - required for PCRS.</li>\n");
-#else /* ifndef DENY_GZIP */
-   b = strsav(b, "  <li><code>#undef <b>DENY_GZIP</b></code> - Allows requests to be compressed if the browser and server support it.</li>\n");
-#endif /* ndef DENY_GZIP */
-
-#ifdef STATISTICS
-   b = strsav(b, "  <li><code>#define <b>STATISTICS</b></code> - Enables statistics function.</li>\n");
-#else /* ifndef STATISTICS */
-   b = strsav(b, "  <li><code>#undef <b>STATISTICS</b></code> - Disables statistics function.</li>\n");
-#endif /* ndef STATISTICS */
-
-#ifdef SPLIT_PROXY_ARGS
-   b = strsav(b, "  <li><code>#define <b>SPLIT_PROXY_ARGS</b></code> - Split this page up by placing the configuration files on separate pages.</li>\n");
-#else /* ifndef SPLIT_PROXY_ARGS */
-   b = strsav(b, "  <li><code>#undef <b>SPLIT_PROXY_ARGS</b></code> - This page contains the text of the configuration files, they are not split onto separate pages.</li>\n");
-#endif /* ndef SPLIT_PROXY_ARGS */
-
-#ifdef KILLPOPUPS
-   b = strsav(b, "  <li><code>#define <b>KILLPOPUPS</b></code> - Enables killing JavaScript popups.</li>\n");
-#else /* ifndef KILLPOPUPS */
-   b = strsav(b, "  <li><code>#undef <b>KILLPOPUPS</b></code> - Disables killing JavaScript popups.</li>\n");
-#endif /* ndef KILLPOPUPS */
-
-#ifdef WEBDAV
-   b = strsav(b, "  <li><code>#define <b>WEBDAV</b></code> - Enables support for webDAV - e.g. stops Microsoft Outlook from accessing HotMail e-mail.</li>\n");
-#else /* ifndef WEBDAV */
-   b = strsav(b, "  <li><code>#undef <b>WEBDAV</b></code> - Disables support for webDAV - e.g. so Microsoft Outlook can access HotMail e-mail.</li>\n");
-#endif /* ndef WEBDAV */
-
-#ifdef DETECT_MSIE_IMAGES
-   b = strsav(b, "  <li><code>#define <b>DETECT_MSIE_IMAGES</b></code> - Enables detecting image requests automatically for MSIE.</li>\n");
-#else /* ifndef DETECT_MSIE_IMAGES */
-   b = strsav(b, "  <li><code>#undef <b>DETECT_MSIE_IMAGES</b></code> - Disables detecting image requests automatically for MSIE.</li>\n");
-#endif /* ndef DETECT_MSIE_IMAGES */
-
-#ifdef USE_IMAGE_LIST
-   b = strsav(b, "  <li><code>#define <b>USE_IMAGE_LIST</b></code> - Enables using image list to detect images.</li>\n");
-#else /* ifndef USE_IMAGE_LIST */
-   b = strsav(b, "  <li><code>#undef <b>USE_IMAGE_LIST</b></code> - Disables using image list to detect images.</li>\n");
-#endif /* ndef USE_IMAGE_LIST */
-
-#ifdef ACL_FILES
-   b = strsav(b, "  <li><code>#define <b>ACL_FILES</b></code> - Enables the use of ACL files to control access to the proxy by IP address.</li>\n");
-#else /* ifndef ACL_FILES */
-   b = strsav(b, "  <li><code>#undef <b>ACL_FILES</b></code> - Disables the use of ACL files to control access to the proxy by IP address.</li>\n");
-#endif /* ndef ACL_FILES */
-\r
-#ifdef TRUST_FILES
-   b = strsav(b, "  <li><code>#define <b>TRUST_FILES</b></code> - Enables the use of trust files.</li>\n");
-#else /* ifndef TRUST_FILES */
-   b = strsav(b, "  <li><code>#undef <b>TRUST_FILES</b></code> - Disables the use of trust files.</li>\n");
-#endif /* ndef TRUST_FILES */
-
-#ifdef JAR_FILES\r
-   b = strsav(b, "  <li><code>#define <b>JAR_FILES</b></code> - Enables the use of jar files to capture cookies.</li>\n");\r
-#else /* ifndef JAR_FILES */\r
-   b = strsav(b, "  <li><code>#undef <b>JAR_FILES</b></code> - Disables the use of jar files to capture cookies.</li>\n");\r
-#endif /* ndef JAR_FILES */\r
-
-   b = strsav(b, "</ul>\n<br>\n");
-
-   b = strsav(b,
-      "<small><small><p>\n"
-      "Code and documentation of the " BANNER " Proxy"
-      "<sup><small>TM</small></sup>\n"
-      "<a href=\"http://www.junkbusters.com/ht/en/legal.html#copy\">\n" "Copyright</a>&#169; 1997 Junkbusters Corporation\n"
-      "<a href=\"http://www.junkbusters.com/ht/en/legal.html#marks\"><sup><small>TM</small></sup></a><br>\n"
-      "Copying and distribution permitted under the"
-      "<a href=\"http://www.gnu.org/copyleft/gpl.html\">\n"
-      "<small>GNU</small></a> "
-      "General Public License.\n"
-      "</small>"
-      "<address><kbd>webmaster@junkbusters.com</kbd></address>"
-      "</small>"
-      "</body></html>\n"
-   );
-
-   proxy_args->trailer = b;
-
-}
-
-
-/*
-  Local Variables:
-  tab-width: 3
-  end:
-*/
diff --git a/showargs.h b/showargs.h
deleted file mode 100644 (file)
index 82b511c..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _SHOWARGS_H
-#define _SHOWARGS_H
-#define SHOWARGS_H_VERSION "$Id: showargs.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
-/*********************************************************************
- *
- * File        :  $Source: /home/administrator/cvs/ijb/showargs.h,v $
- *
- * Purpose     :  Contains various utility routines needed to 
- *                generate the show-proxy-args page.
- *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
- *
- *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
- *                Junkbusters Corporation.  http://www.junkbusters.com
- *
- *                This program is free software; you can redistribute it 
- *                and/or modify it under the terms of the GNU General
- *                Public License as published by the Free Software
- *                Foundation; either version 2 of the License, or (at
- *                your option) any later version.
- *
- *                This program is distributed in the hope that it will
- *                be useful, but WITHOUT ANY WARRANTY; without even the
- *                implied warranty of MERCHANTABILITY or FITNESS FOR A
- *                PARTICULAR PURPOSE.  See the GNU General Public
- *                License for more details.
- *
- *                The GNU General Public License should be included with
- *                this file.  If not, you can view it at
- *                http://www.gnu.org/copyleft/gpl.html
- *                or write to the Free Software Foundation, Inc., 59
- *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Revisions   :
- *    $Log: showargs.h,v $
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char *strsav(char *old, const char *text_to_append);
-extern void savearg(char *c, char *o);
-
-extern void init_proxy_args(int argc, const char *argv[]);
-extern void end_proxy_args(void);
-
-/* Revision control strings from this header and associated .c file */
-extern const char showargs_rcs[];
-extern const char showargs_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef _SHOWARGS_H */
index 81246fd..ff36256 100644 (file)
--- a/ssplit.c
+++ b/ssplit.c
@@ -1,12 +1,12 @@
-const char ssplit_rcs[] = "$Id: ssplit.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
+const char ssplit_rcs[] = "$Id: ssplit.c,v 1.5 2002/03/24 13:25:43 swa Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/ssplit.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/ssplit.c,v $
  *
  * Purpose     :  A function to split a string at specified deliminters.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
@@ -32,6 +32,24 @@ const char ssplit_rcs[] = "$Id: ssplit.c,v 1.1 2001/05/13 21:57:07 administrator
  *
  * Revisions   :
  *    $Log: ssplit.c,v $
+ *    Revision 1.5  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.4  2001/11/13 00:16:38  jongfoster
+ *    Replacing references to malloc.h with the standard stdlib.h
+ *    (See ANSI or K&R 2nd Ed)
+ *
+ *    Revision 1.3  2001/05/29 08:54:25  jongfoster
+ *    Rewrote the innards of ssplit() to be easier to understand,
+ *    faster, and to use less memory.  Didn't change the interface
+ *    except to give the parameters meaningful names.
+ *
+ *    Revision 1.2  2001/05/17 23:01:01  oes
+ *     - Cleaned CRLF's from the sources and related files
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:04  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -39,11 +57,7 @@ const char ssplit_rcs[] = "$Id: ssplit.c,v 1.1 2001/05/13 21:57:07 administrator
 #include "config.h"
 
 #include <string.h>
-#include <stdlib.h>\r
-
-#ifdef _WIN32
-#include <malloc.h>
-#endif
+#include <stdlib.h>
 
 #include "ssplit.h"
 #include "miscutil.h"
@@ -51,180 +65,139 @@ const char ssplit_rcs[] = "$Id: ssplit.c,v 1.1 2001/05/13 21:57:07 administrator
 const char ssplit_h_rcs[] = SSPLIT_H_VERSION;
 
 /* Define this for lots of debugging information to stdout */
-/* #define SSPLIT_VERBOSE */
-
-#ifdef SSPLIT_VERBOSE
-/*********************************************************************
- *
- * Function    :  print
- *
- * Description :  Debugging routine to spit info on stdout.  Not very
- *                useful to the non-console based IJB compiles.
- *
- * Parameters  :
- *          1  :  v = an array of strings
- *          2  :  n = number of strings in `v' to dump to stdout
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void print(char **v, int n)
-{
-   int i;
-   printf("dump %d strings\n", n);
-   for (i=0; i < n; i++)
-   {
-      printf("%d '%s'\n", i, v[i]);
-   }
-
-}
-#endif /* def SSPLIT_VERBOSE */
+#undef SSPLIT_VERBOSE
+/* #define SSPLIT_VERBOSE 1 */
 
 
 /*********************************************************************
  *
  * Function    :  ssplit
  *
- * Description :  Split a string using deliminters in `c'.  Results go
- *                into `v'.
+ * Description :  Split a string using delimiters in `delim'.  Results
+ *                go into `vec'.
  *
  * Parameters  :
- *          1  :  s = string to split
- *          2  :  c = array of delimiters
- *          3  :  v[] = results vector (aka. array)
- *          4  :  n = number of usable slots in the vector (aka. array size)
- *          5  :  m = consecutive delimiters means multiple fields?
- *          6  :  l = ignore leading field separators?
- *
- * Returns     :  -1 => failure, else the number of fields put in `v'.
+ *          1  :  str = string to split.  Will be split in place
+ *                (i.e. do not free until you've finished with vec,
+ *                previous contents will be trashed by the call).
+ *          2  :  delim = array of delimiters (if NULL, uses " \t").
+ *          3  :  vec[] = results vector (aka. array) [out]
+ *          4  :  vec_len = number of usable slots in the vector (aka. array size)
+ *          5  :  dont_save_empty_fields = zero if consecutive delimiters
+ *                give a null output field(s), nonzero if they are just 
+ *                to be considered as single delimeter
+ *          6  :  ignore_leading = nonzero to ignore leading field
+ *                separators.
+ *
+ * Returns     :  -1 => Error: vec_len is too small to hold all the 
+ *                      data, or str == NULL.
+ *                >=0 => the number of fields put in `vec'.
+ *                On error, vec and str may still have been overwritten.
  *
  *********************************************************************/
-int ssplit(char *s, char *c, char *v[], int n, int m, int l)
+int ssplit(char *str, const char *delim, char *vec[], int vec_len, 
+           int dont_save_empty_fields, int ignore_leading)
 {
-   char t[256];
-   char **x = NULL;
-   int xsize = 0;
-   unsigned char *p, b;
-   int xi = 0;
-   int vi = 0;
-   int i;
-   int last_was_null;
-
-   if (!s)
+   unsigned char is_delim[256];
+   unsigned char char_type;
+   int vec_count = 0;
+
+   if (!str)
    {
       return(-1);
    }
 
-   memset(t, '\0', sizeof(t));
 
-   p = (unsigned char *) c;
+   /* Build is_delim array */
 
-   if (!p)
+   memset(is_delim, '\0', sizeof(is_delim));
+
+   if (!delim)
    {
-      p = (unsigned char *) " \t";  /* default field separators */
+      delim = " \t";  /* default field separators */
    }
 
-   while (*p)
+   while (*delim)
    {
-      t[*p++] = 1;   /* separator  */
+      is_delim[(unsigned)(unsigned char)*delim++] = 1;   /* separator  */
    }
 
-   t['\0'] = 2;   /* terminator */
-   t['\n'] = 2;   /* terminator */
+   is_delim[(unsigned)(unsigned char)'\0'] = 2;   /* terminator */
+   is_delim[(unsigned)(unsigned char)'\n'] = 2;   /* terminator */
+
 
-   p = (unsigned char *) s;
+   /* Parse string */
 
-   if (l)/* are we to skip leading separators ? */
+   if (ignore_leading)
    {
-      while ((b = t[*p]) != 2)
+      /* skip leading separators */
+      while (is_delim[(unsigned)(unsigned char)*str] == 1)
       {
-         if (b != 1)
-         {
-            break;
-         }
-         p++;
+         str++;
       }
    }
 
-   xsize = 256;
-
-   x = (char **) zalloc((xsize) * sizeof(char *));
-
-   x[xi++] = (char *) p;   /* first pointer is the beginning of string */
+   /* first pointer is the beginning of string */
+   /* Check if we want to save this field */
+   if ( (!dont_save_empty_fields)
+     || (is_delim[(unsigned)(unsigned char)*str] == 0) )
+      {
+      /*
+       * We want empty fields, or the first character in this 
+       * field is not a delimiter or the end of string.
+       * So save it.
+       */
+      if (vec_count >= vec_len)
+      {
+         return(-1); /* overflow */
+      }
+      vec[vec_count++] = (char *) str;   
+   }
 
-   /* first pass:  save pointers to the field separators */
-   while ((b = t[*p]) != 2)
+   while ((char_type = is_delim[(unsigned)(unsigned char)*str]) != 2)
    {
-      if (b == 1)    /* if the char is a separator ... */
+      if (char_type == 1)    
       {
-         *p++ = '\0';      /* null terminate the substring */
+         /* the char is a separator */
 
-         if (xi == xsize)
-         {
-            /* get another chunk */
-            int new_xsize = xsize + 256;
-            char **new_x = (char **)zalloc((new_xsize) * sizeof(char *));
+         /* null terminate the substring */
+         *str++ = '\0';      
 
-            for (i=0; i < xsize; i++)
+         /* Check if we want to save this field */
+         if ( (!dont_save_empty_fields)
+           || (is_delim[(unsigned)(unsigned char)*str] == 0) )
             {
-               new_x[i] = x[i];
+            /*
+             * We want empty fields, or the first character in this 
+             * field is not a delimiter or the end of string.
+             * So save it.
+             */
+            if (vec_count >= vec_len)
+            {
+               return(-1); /* overflow */
             }
-
-            free(x);
-            xsize = new_xsize;
-            x     = new_x;
+            vec[vec_count++] = (char *) str;   
          }
-         x[xi++] = (char *) p;   /* save pointer to beginning of next string */
       }
       else
       {
-         p++;
+         str++;
       }
    }
-   *p = '\0';     /* null terminate the substring */
-
+   *str = '\0';     /* null terminate the substring */
 
 #ifdef SSPLIT_VERBOSE
-   if (DEBUG(HDR))
    {
-      print(x, xi); /* debugging */
-   }
-#endif /* def SSPLIT_VERBOSE */
-
-
-   /* second pass: copy the relevant pointers to the output vector */
-   last_was_null = 0;
-   for (i=0 ; i < xi; i++)
-   {
-      if (m)
-      {
-         /* there are NO null fields */
-         if (*x[i] == 0)
-         {
-            continue;
-         }
-      }
-      if (vi < n)
+      int i;
+      printf("dump %d strings\n", vec_count);
+      for (i = 0; i < vec_count; i++)
       {
-         v[vi++] = x[i];
+         printf("%d '%s'\n", i, vec[i]);
       }
-      else
-      {
-         free(x);
-         return(-1); /* overflow */
-      }
-   }
-   free(x);
-
-#ifdef SSPLIT_VERBOSE
-   if (DEBUG(HDR))
-   {
-      print(v, vi); /* debugging  */
    }
 #endif /* def SSPLIT_VERBOSE */
 
-   return(vi);
-
+   return(vec_count);
 }
 
 
index 39bd993..397dda2 100644 (file)
--- a/ssplit.h
+++ b/ssplit.h
@@ -1,14 +1,14 @@
-#ifndef _SSPLIT_H
-#define _SSPLIT_H
-#define SSPLIT_H_VERSION "$Id: ssplit.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
+#ifndef SSPLIT_H_INCLUDED
+#define SSPLIT_H_INCLUDED
+#define SSPLIT_H_VERSION "$Id: ssplit.h,v 1.4 2002/03/24 13:25:43 swa Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/ssplit.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/ssplit.h,v $
  *
  * Purpose     :  A function to split a string at specified deliminters.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: ssplit.h,v $
+ *    Revision 1.4  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.3  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.2  2001/05/29 08:54:25  jongfoster
+ *    Rewrote the innards of ssplit() to be easier to understand,
+ *    faster, and to use less memory.  Didn't change the interface
+ *    except to give the parameters meaningful names.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:04  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -42,7 +57,8 @@
 extern "C" {
 #endif
 
-extern int ssplit(char *s, char *c, char *v[], int n, int m, int l);
+extern int ssplit(char *str, const char *delim, char *vec[], int vec_len, 
+                  int dont_save_empty_fields, int ignore_leading);
 
 /* Revision control strings from this header and associated .c file */
 extern const char ssplit_rcs[];
@@ -52,7 +68,7 @@ extern const char ssplit_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _SSPLIT_H */
+#endif /* ndef SSPLIT_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/standard.action b/standard.action
new file mode 100644 (file)
index 0000000..7d5fd99
--- /dev/null
@@ -0,0 +1,138 @@
+######################################################################
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/standard.action,v $
+# 
+#  $Id: standard.action,v 1.1 2002/04/24 02:20:49 oes Exp $
+#
+#  Purpose     :  Provide prefedined sets of actions, see
+#                 http://www.privoxy.org/faq/questions.html#CONFIGFILES
+#
+#  Copyright   :  Written by and Copyright
+#                 Privoxy team. http://www.privoxy.org/
+#
+######################################################################
+
+######################################################################
+#
+# CAUTION: MODYFING THIS FILE IS *NOT* RECOMMENDED for the average
+#          user.
+#
+#          If you want to customize Privoxy to suit your needs, 
+#          you can alter the default section in default.action and/or
+#          add your personal exceptions and additions in user.action
+#
+######################################################################
+
+################
+#
+# Cautions settings -- safe for all sites
+#
+{ \
+-add-header \
+-block \
+-deanimate-gifs \
+-downgrade-http-version \
+-fast-redirects \
++filter{html-annoyances} \
++filter{js-annoyances} \
+-filter{content-cookies} \
+-filter{popups} \
++filter{webbugs} \
+-filter{refresh-tags} \
+-filter{fun} \
++filter{nimda} \
++filter{banners-by-size} \
+-filter{shockwave-flash} \
+-filter{crude-prental} \
++hide-forwarded-for-headers \
++hide-from-header{block} \
+-hide-referrer \
+-hide-user-agent \
+-handle-as-image \
++set-image-blocker{pattern} \
+-limit-connect \
++prevent-compression \
+-session-cookies-only \
+-crunch-outgoing-cookies \
+-crunch-incoming-cookies \
+-kill-popups \
+-send-vanilla-wafer \
+-send-wafer \
+}
+standard.Cautious
+
+################
+#
+# Medium settings -- safe for most sites
+#
+{ \
+-add-header \
+-block \
++deanimate-gifs{last} \
+-downgrade-http-version \
+-fast-redirects \
++filter{html-annoyances} \
++filter{js-annoyances} \
++filter{content-cookies} \
+-filter{popups} \
++filter{webbugs} \
++filter{refresh-tags} \
+-filter{fun} \
++filter{nimda} \
++filter{banners-by-size} \
+-filter{shockwave-flash} \
+-filter{crude-prental} \
++hide-forwarded-for-headers \
++hide-from-header{block} \
++hide-referrer{forge} \
+-hide-user-agent \
+-handle-as-image \
++set-image-blocker{pattern} \
+-limit-connect \
++prevent-compression \
++session-cookies-only \
+-crunch-outgoing-cookies \
+-crunch-incoming-cookies \
+-kill-popups \
+-send-vanilla-wafer \
+-send-wafer \
+}
+standard.Medium
+
+################
+#
+# Advanced settings -- fun but risky
+#
+{ \
++add-header{X-User-Tracking: sucks} \
+-block \
++deanimate-gifs{last} \
+-downgrade-http-version \
++fast-redirects \
++filter{html-annoyances} \
++filter{js-annoyances} \
++filter{content-cookies} \
++filter{popups} \
++filter{webbugs} \
++filter{refresh-tags} \
++filter{fun} \
++filter{nimda} \
++filter{banners-by-size} \
+-filter{shockwave-flash} \
+-filter{crude-prental} \
++hide-forwarded-for-headers \
++hide-from-header{block} \
++hide-referrer{forge} \
+-hide-user-agent \
+-handle-as-image \
++set-image-blocker{pattern} \
+-limit-connect \
++prevent-compression \
++session-cookies-only \
+-crunch-outgoing-cookies \
+-crunch-incoming-cookies \
+-kill-popups \
+-send-vanilla-wafer \
+-send-wafer \
+}
+standard.Advanced
diff --git a/templates/blocked b/templates/blocked
new file mode 100644 (file)
index 0000000..e323b9e
--- /dev/null
@@ -0,0 +1,270 @@
+##########################################################
+#
+# "Blocked" Error Output template for Privoxy.
+#
+#  NOTE: UNLIKE THE OTHER TEMPLATES, THIS ONE USES
+#  JavaScript write() TO GENERATE THE PAGE IN JS_AWARE
+#  BROWSERS. SYMBOL SUBSTITUTIONS THAT RESULT IN MULTILINE
+#  STRINGS WILL BREAK THE JavaScript SYNTAX.
+#  USE WITH CAUTION.
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written in plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+#  protocol:
+#    The request's protocol: http:// or https://
+#  hostport:
+#    The host and port part of the request that lead to this problem
+#  path:
+#    The path part of the request that lead to this problem
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    This is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#  force-support:
+#    Privoxy has been compiled with support for forced loading
+#    of blocked content. In that case, the symbol "force-prefix" is
+#    avaiable, which translates to the FORCE_PREFIX  
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+  <title>Request blocked (Privoxy@@my-hostname@)</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+  <script type="text/javascript" language="javascript">
+  <!--
+    /*
+     * Is this window or frame too small
+     * for the full-blown "blocked" page?
+     */
+    function isSmallFrame()
+    {
+       minWidth  = 650;
+       minHeight = 330;
+
+       /* 
+        * Navigator, Mozilla, Opera
+        */
+       if (window.innerWidth 
+           && (window.innerWidth >= minWidth) 
+           && (window.innerHeight >= minHeight))
+       {
+          return false;
+       }
+       /* 
+        * MSIE
+        */
+       else if (document.body && document.body.clientWidth 
+                && (document.body.clientWidth >= minWidth)
+                && (document.body.clientHeight >= minHeight))
+       {
+          return false;
+       }
+
+       /*
+        * Small window or unsupported browser
+        */
+       return true;
+   }
+  //-->
+  </script>
+ </head>
+ <body>
+  <script type="text/javascript" language="javascript">
+  <!--
+#   Note: The same small version is used at the bottom
+#         of this file in the <noscript> context. If you
+#         make changes here, keep the other version in sync!
+
+  if (isSmallFrame())
+  {
+     document.write('\
+   <p class="small" align="center"> \
+    <a href="@default-cgi@" target="_blank">Privoxy</a> blocked <b>@protocol@@hostport@@path@</b>. \
+    <br><a href="@default-cgi@show-url-info?url=@hostport@@path@" target="_blank">See why</a> \
+    <!-- @if-force-support-start --> \
+    or <a href="http://@hostport@@force-prefix@@path@">go there anyway</a>. \
+    <!-- if-force-support-end@ --> \
+   </p> \
+   ');
+
+  }
+  else
+  {
+     document.write('\
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">\
+    <tr> \
+      <td class="status"> \
+        BLOCKED \
+      </td> \
+      <td class="title" width=100%> \
+         <h1> \
+          This is <a href="@homepage@">Privoxy</a> @version@ on @my-hostname@ (@my-ip-address@), port @my-port@, \
+          @if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@ \
+        </h1> \
+      </td> \
+    </tr> \
+ \
+<!-- @if-unstable-start --> \
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in \
+    <tr> \
+      <td class="warning" colspan="2"> \
+        <h2>Warning:</h2> \
+        <p> \
+          <b>Please note that this <font color=red>@code-status@</font> release \
+          of the proxy software is not intended for production systems! \
+          <br>Use at your own risk. See the <a href="http://www.gnu.org/copyleft/gpl.html">license</a> for details.</b> \
+        </p> \
+      </td> \
+    </tr> \
+<!-- if-unstable-end@ --> \
+ \
+    <tr> \
+      <td class="box" colspan="2"> \
+        <h2>Request for blocked URL</h2> \
+        <p>Your request for <b>@protocol@@hostport@@path@</b> was blocked. \
+          <br><a href="@default-cgi@show-url-info?url=@hostport@@path@">See why</a> \
+    <!-- @if-force-support-start --> \
+          or <a href="http://@hostport@@force-prefix@@path@">go there anyway</a>. \
+<!-- if-force-support-end@ --> \
+        </p> \
+      </td> \
+    </tr> \
+ \
+    <tr> \
+      <td class="box" colspan="2"> \
+        <h2>More Privoxy:</h2> \
+        <ul>@menu@</ul> \
+      </td> \
+    </tr> \
+ \
+    <tr> \
+      <td class="info" colspan="2"> \
+        <big><b>Support and Service via Sourceforge:</b></big> \
+        <p> \
+          We value your feedback. To provide you with the best support, \
+          we ask that you: \
+        </p> \
+        <ul> \
+          <li> \
+            use the <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=211118">support forum</a> or (better) the \
+            <a href="http://sourceforge.net/mail/?group_id=11118">mailing lists</a> to get help. \
+          </li> \
+          <li> \
+            submit banners and all problems with the actions file only through the \
+            <a href="javascript:void(window.open(\'http://www.privoxy.org/actions\',\'Feedback\',\'width=600,scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no\').focus());">actions \
+            file feedback system</a>. \
+          </li> \
+          <li> \
+            submit bugs only through our <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=111118">bug tracker</a>. \
+            Make sure that the bug has not yet been submitted. \
+          </li> \
+          <li> \
+            submit feature requests only through our <a href="http://sourceforge.net/tracker/?atid=361118&amp;group_id=11118&amp;func=browse">feature \
+            request tracker</a>. \
+          </li> \
+        </ul> \
+      </td> \
+    </tr> \
+ \
+<!-- @if-have-help-info-start --> \
+    <tr> \
+      <td class="info" colspan="2"> \
+        <h2>Local Privoxy support:</h2> \
+ \
+<!-- @if-have-proxy-info-start --> \
+        <p>You can consult the <a href="@proxy-info-url@">online documentation</a> for more information about this Privoxy installation.</p> \
+<!-- if-have-proxy-info-end@ --> \
+ \
+<!-- @if-have-adminaddr-info-start --> \
+        <p>Address e-mail questions about this service to \
+          <a href="mailto:@admin-address@"><code>@admin-address@</code></a>, \
+          who will be glad to help you. \
+        </p> \
+<!-- if-have-adminaddr-info-end@ --> \
+      </td> \
+    </tr> \
+<!-- if-have-help-info-end@ --> \
+ \
+  </table> \
+     ');
+  }
+  //-->
+  </script>
+
+#   Note: The same small version is used above via JavaScript
+#         If you make changes here, keep the other version in sync!
+
+  <noscript>
+   <p class="small" align="center">
+    <a href="@default-cgi@" target="_blank">Privoxy</a> blocked <b>@protocol@@hostport@@path@</b>.
+    <br><a href="@default-cgi@show-url-info?url=@hostport@@path@" target="_blank">See why</a>
+    <!-- @if-force-support-start -->
+    or <a href="http://@hostport@@force-prefix@@path@">go there anyway</a>.
+    <!-- if-force-support-end@ -->
+   </p>
+  </noscript>
+
+ </body>
+</html>
diff --git a/templates/cgi-error-404 b/templates/cgi-error-404
new file mode 100644 (file)
index 0000000..ee70d49
--- /dev/null
@@ -0,0 +1,154 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>404 - Privoxy Configuration Page not found</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="status">
+        404
+      </td>     
+      <td class="title" style="width: 100%">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning" colspan="2">
+        <h2>Privoxy Configuration page not found</h2>
+            <p>You typed in what looks like a URL used to configure
+               Privoxy, but it cannot be recognised.  Maybe it's
+               for a different Privoxy version, or you typed it
+               in wrong?  Or maybe the Privoxy administrator
+               has decided to disable the feature.</p>
+            <p>If you got here by clicking a link in the
+               configuration interface, please file a bug report!</p>
+            <p>You can use the menu below to select from the available
+               configuration options</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box" colspan="2">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+        
+    <tr>
+      <td colspan="2">
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+
+  </table>
+
+</body>
+</html>
diff --git a/templates/cgi-error-bad-param b/templates/cgi-error-bad-param
new file mode 100644 (file)
index 0000000..a9803db
--- /dev/null
@@ -0,0 +1,161 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy: Bad parameter</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning">
+        <h2>Bad parameter to Privoxy configuration page</h2>
+        <p>You've found a page used to configure Privoxy, but the
+           parameters (the part of the web page address after the
+           "?" mark) are wrong or missing.</p>
+        <p>Possible causes:</p>
+        <ul>
+          <li>If you just typed a URL pattern into a form, then you got
+             something wrong.  Press the "back" button on your browser
+             once and correct what you typed.</li>
+          <li>If you tried to type in the URL, then you've found a
+             page where you can't do that.  You can only view this
+             page by following links from elsewhere in the configuration
+             interface.</li>
+          <li>If you got here using your browser's "back" button, then
+             that is deliberately disabled for this page.</li>
+          <li>If you got here by clicking a link in the
+             configuration interface, please file a bug report!</li>
+        </ul>
+        <p>You can use the menu below to select from the available
+           configuration options</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>Privoxy Menu:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+    
+    <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+
+  </table>
+
+</body>
+</html>
diff --git a/templates/cgi-error-disabled b/templates/cgi-error-disabled
new file mode 100644 (file)
index 0000000..fd7f01f
--- /dev/null
@@ -0,0 +1,148 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Configuration Page Disabled</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning">
+        <h2>Privoxy Configuration page diasabled</h2>
+          <p>The Privoxy administrator has decided to disable this 
+             feature.  If you want to use it, you must ask them to
+             enable it.</p>
+          <p>If you are the Privoxy administrator, you can enable
+             this feature by changing the appropriate line in your
+             configuration file.</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+    
+    <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+
+  </table>
+
+</body>
+</html>
diff --git a/templates/cgi-error-file b/templates/cgi-error-file
new file mode 100644 (file)
index 0000000..dab262a
--- /dev/null
@@ -0,0 +1,138 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy: Actions file not found</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning">
+        <h2>Actions file not found</h2>
+        <p>The actions file you are trying to edit (<code>@f@.action</code>)
+           does not exist, or cannot be read.</p>
+      </td>
+    </tr>
+
+     <tr>
+      <td class="box">
+        <h2>Privoxy Menu:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+  </table>
+
+</body>
+</html>
diff --git a/templates/cgi-error-file-read-only b/templates/cgi-error-file-read-only
new file mode 100644 (file)
index 0000000..6222448
--- /dev/null
@@ -0,0 +1,145 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy: Cannot write to actions file</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning">
+        <h2>Cannot write to actions file</h2>
+        <p>The actions file you are trying to edit (<code>@f@.action</code>)
+           could not be written to.</p>
+        <p>You many not have permission to write to the file - check the file
+           permissions.  On Windows, right-click the file, choose Properties,
+           and make sure it is not read-only.</p>
+        <p>Another reason you may see this message is if you have run out of
+           disk space.  If that is the case, then the actions file has been
+           truncated - if you get further errors, you may need to fix it
+           using a text editor.</p>
+      </td>
+    </tr>
+
+     <tr>
+      <td class="box">
+        <h2>Privoxy Menu:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+  </table>
+
+</body>
+</html>
diff --git a/templates/cgi-error-modified b/templates/cgi-error-modified
new file mode 100644 (file)
index 0000000..c42bc69
--- /dev/null
@@ -0,0 +1,162 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy: URL out of date</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning">
+        <h2>URL out of date - file has changed since it was generated</h2>
+        <p>The URL you're viewing is out of date.  To prevent possible
+           damage to your configuration file, this action has been ignored.
+        </p>
+        <p>Possible causes:</p>
+        <ul>
+          <li>If you got here using your browser's "back" button, then
+             that is deliberately disabled for this page.  Please 
+             navigate around the configuration editor using the
+             links provided.</li>
+          <li>Perhaps you've got more than one browser window open, and
+             you're trying to change the same file in both?  You can
+             only have one editor window open at a time.  Your other edit
+             window should continue to function.</li>
+          <li>You may have modified the file some other way - perhaps by
+             editing it with a text editor.  Simply go back in to the 
+             configuration interface using the links below.</li>
+        </ul>
+        <p>You can go back into the edit interface using the menu below,
+           or by clicking <a href="edit-actions-list?f=@f@">here</a>.
+        </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+        
+    <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+    
+  </table>
+
+</body>
+</html>
diff --git a/templates/cgi-error-parse b/templates/cgi-error-parse
new file mode 100644 (file)
index 0000000..723eb67
--- /dev/null
@@ -0,0 +1,175 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy: Parse error</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning">
+        <h2>Parse error</h2>
+         <p>The file you're trying to edit is not valid.  You need to fix
+           it using a text editor before you can edit it using the
+           web-based editor.</p>
+        <p>This error should only occur if you edited the file using a text
+           editor.  If you managed to take a valid file and break it this
+           badly using the web-based editor, please file a bug report!</p>
+        <p>When you've fixed the problem, you can go back into the edit
+           interface using the menu below, or by clicking <a 
+           href="edit-actions-list?f=@f@">here</a>.
+        </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>Problem description:</h2>
+        <p>@parse-error@</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>The line which caused the problem:</h2>
+        <pre>@line-raw@</pre>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>The line which caused the problem, with comments removed</h2>
+        <p><code>@line-data@</code></p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>Note</h2>
+        <p>Only the first error is reported - the file may contain other
+           errors, as well as the one reported above.</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+    
+  </table>
+
+</body>
+</html>
diff --git a/templates/cgi-style.css b/templates/cgi-style.css
new file mode 100644 (file)
index 0000000..b3556fd
--- /dev/null
@@ -0,0 +1,137 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa/current/templates/edit-actions-list,v $
+#
+# Purpose     :  Style sheet for the web-based config interface.
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-list,v $
+#
+##############################################################################
+
+
+/*
+ * CSS for Privoxy CGI and script output
+ *
+ * $Id: cgi-style.css,v 1.7 2002/05/12 15:45:33 jongfoster Exp $
+ */
+
+/*
+ * General rules: Font, Color, Headings, Margins, Links
+ */
+body,td,th { font-family: arial, helvetica, helv, sans-serif; }
+body { background-color: #ffffff; color: #000000; }
+
+h1 { font-size: 140%; margin: 0px; }
+h2 { font-size: 120%; margin: 0px; }
+h3 { font-size: 110%; margin: 0px; }
+
+p,pre  { margin-left: 15px; }
+li { margin: 2px 15px; }
+dl { margin: 2px 15px; }
+
+a:link    { color: #0000dd; text-decoration: none; }
+a:visited { color: #330099; text-decoration: none; }
+a:active  { color: #3333ff; text-decoration: none; }
+
+/*
+ * Boxen as Table elements:
+ */
+td.title   { border: solid black 1px; background-color: #dddddd; }
+td.box     { border: solid black 1px; background-color: #eeeeee; }
+td.info    { border: solid black 1px; background-color: #ccccff; }
+td.warning { border: solid black 1px; background-color: #ffdddd; }
+
+/*
+ * Special Table Boxen: for nesting, naked container and for
+ * the Status field in CGI Output:
+ */
+td.wrapbox { border: solid black 1px; padding: 5px; }
+td.container { padding: 0px; }
+td.status  { border: solid black 1px; background-color: #ff0000; color: #ffffff; font-size: 300%; font-weight: bolder; }
+
+/*
+ * Same Boxen as <div>s:
+ */
+div.title    { border: solid black 1px; background-color: #dddddd; margin: 20px; padding: 20px; }
+div.box      { border: solid black 1px; background-color: #eeeeee; margin: 20px; padding: 20px; }
+div.info     { border: solid black 1px; background-color: #ccccff; margin: 20px; padding: 20px; }
+div.warning  { border: solid black 1px; background-color: #ffdddd; margin: 20px; padding: 20px; }
+div.wrapbox  { border: solid black 1px;                            margin: 20px; padding:  5px; }
+
+
+/*
+ * Bold definitions in <dl>s, grey BG for table headings, transparent (no-bordered) table
+ */
+dt { font-weight: bold; }
+th { background-color: #dddddd; }
+table.transparent { border-style: none}
+
+/*
+ * Special purpose paragraphs: Small for page footers,
+ * Important for quoting wrong or dangerous examples,
+ * Whiteframed for the toggle?mini=y CGI
+ */
+p.small { font-size: 10px; margin: 0px; }
+p.important { border: solid black 1px; background-color: #ffdddd; font-weight: bold; padding: 2px; }
+p.whiteframed { margin: 5px; padding: 5px; border: solid black 1px; text-align: center; background-color: #eeeeee; }
+
+/*
+ * Links as buttons:
+ */
+
+td.buttons {
+  padding: 2px;
+}
+
+a.cmd, td.indentbuttons a, td.buttons a {
+  white-space: nowrap;
+  width: auto;
+  padding: 2px;
+  background-color: #dddddd;
+  color:            #000000;
+  text-decoration: none;
+  border-top:    1px solid #ffffff;
+  border-left:   1px solid #ffffff;
+  border-bottom: 1px solid #000000;
+  border-right:  1px solid #000000;
+}
+a.cmd:hover, td.indentbuttons a:hover, td.buttons a:hover {
+  background-color: #eeeeee;
+}
+a.cmd:active, td.indentbuttons a:active, td.buttons a:active {
+  border-top:    1px solid #000000;
+  border-left:   1px solid #000000;
+  border-bottom: 1px solid #ffffff;
+  border-right:  1px solid #ffffff;
+}
+
+
+/*
+ * Special red emphasis:
+ */
+em.warning { color: #ff0000 }
diff --git a/templates/connect-failed b/templates/connect-failed
new file mode 100644 (file)
index 0000000..8e6de60
--- /dev/null
@@ -0,0 +1,159 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+#  host-ip:
+#    The IP address of the host that could not be reached
+#  hostport:
+#    The host and port part of the request that lead to this problem
+#  path:
+#    The path part of the request that lead to this problem
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>503 - Connect failed (Privoxy@@my-hostname@)</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="status">
+        503
+      </td>     
+      <td class="title" style="width: 100%">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning" colspan=2>
+        <h2>Connect failed</h2>
+          <p>Your request for <a href="@protocol@@hostport@@path@"><b>@protocol@@hostport@@path@</b></a> could
+            not be fulfilled, because the connection to <b>@host@</b> (@host-ip@) could not be established.
+          </p>
+          <p>This is often a temporary failiure, so you might just
+            <a href="@protocol@@hostport@@path@">try again</a>.
+         </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box" colspan="2">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+    <tr>
+      <td colspan="2">
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+    
+  </table>
+
+</body>
+</html>
diff --git a/templates/default b/templates/default
new file mode 100644 (file)
index 0000000..f11c3f6
--- /dev/null
@@ -0,0 +1,136 @@
+##########################################################
+#
+# Default-CGI Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy@@my-hostname@</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Privoxy Menu:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+    
+    <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+
+  </table>
+
+</body>
+</html>
diff --git a/templates/edit-actions-add-url-form b/templates/edit-actions-add-url-form
new file mode 100644 (file)
index 0000000..a15bec1
--- /dev/null
@@ -0,0 +1,202 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa/current/templates/edit-actions-add-url-form,v $
+#
+# Purpose     :  Template used to add a URL pattern to the actions file.
+#
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-add-url-form,v $
+#    Revision 1.13  2002/04/10 13:32:53  oes
+#    Made templates modular
+#
+#    Revision 1.12  2002/04/08 17:08:14  oes
+#    Cosmetic: make status in title lowercase
+#
+#    Revision 1.11  2002/04/05 16:01:33  oes
+#    Correct HTML, external Stylesheets, eye candy, some fixes
+#
+#    Revision 1.10  2002/03/26 22:29:56  swa
+#    we have a new homepage!
+#
+#    Revision 1.9  2002/03/24 15:23:33  jongfoster
+#    Name changes
+#
+#    Revision 1.8  2002/03/24 11:01:06  swa
+#    name change
+#
+#    Revision 1.7  2002/03/23 16:18:15  swa
+#    renamed every reference to the old name with foobar.
+#    fixed "application foobar application" tag, fixed
+#    "the foobar" with "foobar". left junkbuster in cvs
+#    comments and remarks to history untouched. should
+#    make final rename easier.
+#
+#    Revision 1.6  2002/03/16 15:22:19  jongfoster
+#    Moving 'alpha' warning to the end of the page
+#
+#    Revision 1.5  2002/03/03 10:29:12  swa
+#    point users to the right feedback forms,
+#    not necessarily the developer list.
+#
+#    Revision 1.4  2002/01/23 00:26:45  jongfoster
+#    Reducing length of URLs
+#    Where encoded and unencoded versions of a string existed, removing
+#    the unencoded one.
+#
+#    Revision 1.3  2002/01/17 21:33:00  jongfoster
+#    Replacing all references to the URL of the config interface
+#    with @default-cgi@
+#
+#    Revision 1.2  2002/01/17 21:21:03  jongfoster
+#    DOS->Unix line endings
+#
+#    Revision 1.1  2001/11/13 00:58:18  jongfoster
+#    New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# section
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+  <title>Privoxy@@my-hostname@: Add URL Pattern</title>
+
+  <script type="text/javascript">
+<!--
+  function validate(text)
+  {
+  if (text=="")
+  {
+    alert("You need to type a pattern in order to continue!");
+    return false;
+  }
+
+  return true;
+}
+//-->
+  </script>
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Add URL Pattern</h2>
+        <form method="GET" action="edit-actions-add-url"
+              onSubmit="return validate(u.value);">
+          <p>
+            <input type="hidden" name="f" value="@f@">
+            <input type="hidden" name="v" value="@v@">
+            <input type="hidden" name="s" value="@s@">
+            <input type="text" name="u" value="" size="78"><br>
+            <input type="submit" value="Submit"> &nbsp;
+            <input type="reset" value="Reset"> &nbsp;
+            <a class="cmd" href="edit-actions-list?f=@f@#l@s@">Cancel</a>
+          </p>
+        </form>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+    <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+
+  </table>
+
+</body>
+</html>
+
diff --git a/templates/edit-actions-for-url b/templates/edit-actions-for-url
new file mode 100644 (file)
index 0000000..4033345
--- /dev/null
@@ -0,0 +1,879 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa/current/templates/edit-actions-for-url,v $
+#
+# Purpose     :  Template used to edit the actions associated with a
+#                particular section in an actions file.
+# 
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-for-url,v $
+#    Revision 1.28  2002/05/14 21:36:38  oes
+#     - Renamed prevent-(setting/reading)-cookies to
+#       crunch-(incoming/outgoing)-cookies
+#     - Renamed helplink export to actions-help-prefix
+#     - Restored alphabetical order of actions
+#
+#    Revision 1.27  2002/04/26 22:55:26  jongfoster
+#    Removing the alternating colors because they've been wrong
+#    since the actions renames, they're high maintenance, they
+#    don't look particularly good, and now there are gaps between
+#    the table cells we don't need them.
+#
+#    Revision 1.26  2002/04/26 21:55:17  jongfoster
+#    Cosmetic change: Making the +filter UI look the same as
+#    the other actions.
+#
+#    Revision 1.25  2002/04/26 21:37:50  jongfoster
+#    Fixing all(?) the substitutions that were broken in the
+#    recent actions rename.
+#
+#    Revision 1.24  2002/04/26 18:24:28  jongfoster
+#    Fixing typos in help hyperlinks
+#
+#    Revision 1.23  2002/04/26 12:57:02  oes
+#    Actions renamed, alphabetically sorted, comments fixed, and names linked to help
+#
+#    Revision 1.22  2002/04/10 13:32:53  oes
+#    Made templates modular
+#
+#    Revision 1.21  2002/04/08 17:05:18  oes
+#    Inline a style exception
+#
+#    Revision 1.20  2002/04/05 16:01:30  oes
+#    Correct HTML, external Stylesheets, eye candy, some fixes
+#
+#    Revision 1.19  2002/03/26 22:29:56  swa
+#    we have a new homepage!
+#
+#    Revision 1.18  2002/03/24 16:32:08  jongfoster
+#    Removing logo option
+#
+#    Revision 1.17  2002/03/24 15:23:33  jongfoster
+#    Name changes
+#
+#    Revision 1.16  2002/03/24 11:01:06  swa
+#    name change
+#
+#    Revision 1.15  2002/03/23 16:18:15  swa
+#    renamed every reference to the old name with foobar.
+#    fixed "application foobar application" tag, fixed
+#    "the foobar" with "foobar". left junkbuster in cvs
+#    comments and remarks to history untouched. should
+#    make final rename easier.
+#
+#    Revision 1.14  2002/03/16 15:22:19  jongfoster
+#    Moving 'alpha' warning to the end of the page
+#
+#    Revision 1.13  2002/03/16 14:28:38  jongfoster
+#    First version of modular filters support
+#
+#    Revision 1.12  2002/03/12 01:42:50  oes
+#    Introduced modular filters
+#
+#    Revision 1.11  2002/03/08 18:19:14  jongfoster
+#    Adding +image-blocker{pattern} option to edit interface
+#
+#    Revision 1.10  2002/03/03 10:29:12  swa
+#    point users to the right feedback forms,
+#    not necessarily the developer list.
+#
+#    Revision 1.9  2002/01/23 00:26:45  jongfoster
+#    Reducing length of URLs
+#    Where encoded and unencoded versions of a string existed, removing
+#    the unencoded one.
+#
+#    Revision 1.8  2002/01/17 21:33:00  jongfoster
+#    Replacing all references to the URL of the config interface
+#    with @default-cgi@
+#
+#    Revision 1.7  2002/01/17 21:21:03  jongfoster
+#    DOS->Unix line endings
+#
+#    Revision 1.6  2001/11/22 21:58:41  jongfoster
+#    Adding action +no-cookies-keep
+#
+#    Revision 1.5  2001/11/13 21:12:17  jongfoster
+#    Added support for the following actions:
+#    +downgrade, +limit-connect, +no-compression
+#
+#    Revision 1.4  2001/11/13 00:58:18  jongfoster
+#    New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Browser support for the JavaScript on this page:
+#   MS Internet Explorer 5.5 - Tested,   Yes
+#   Netscape 6.0             - Tested,   Yes
+#   Netscape 4.75            - Tested,   NO
+#   Opera 5.12               - Tested,   NO
+#   MS Internet Explorer 4+  - Untested, Yes
+#   MS IE 3.x, NS3.x         - Untested, NO
+#   Mozilla >=0.6            - Untested, Yes
+#
+# All browsers should work, you just might not get the pretty DHTML effects.
+#
+# The effects that only work under the browsers marked "Yes" above are:
+#  - Text edit boxes that won't have any effect are disabled.
+#  - Table rows containing additional settings are hidden if the feature in
+#    question is disabled.
+#
+# There are major kludges to get around these problems with NS4, but they
+# screw up the HTML too much for other browsers.  If anyone wants to try,
+# here's some descriptions of the kludges:
+#    http://www.webreference.com/js/tips/991114.html
+#    http://www.webreference.com/dhtml/column12/outDisplay.html
+#
+# If you're favorite browser isn't listed, please test and add it.
+#
+#
+#############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# action-name-y
+# action-name-n
+# action-name-x
+#
+# deanimate-gifs-param-first
+# deanimate-gifs-param-last
+# hide-from-param-block
+# hide-from-param-custom
+# hide-from-param
+# hide-referer-param-forge
+# hide-referer-param-block
+# hide-referer-param-custom
+# hide-referer-param
+# hide-user-agent-param
+# image-blocker-param-pattern
+# image-blocker-param-blank
+# image-blocker-param-custom
+#
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+  <title>Privoxy@@my-hostname@: Edit actions</title>
+
+<style type="text/css">
+td.action    { font-weight: bold;
+               font-style: italic;
+               white-space: nowrap       }
+td.subaction { font-style: italic        }
+th           { font-weight: bold;        }
+# This is the key to the color names below:
+# bg=background, en="Enable", dis="Disable", noc="No Change", hdr=header
+# 1=odd rows, 2=even rows, h=Table header
+tr.hdr       { background-color: #999999 }
+tr.bg1       { background-color: #eeeeee }
+td.en1       { background-color: #ddffdd }
+td.dis1      { background-color: #ffdddd }
+td.noc1      { background-color: #ddddff }
+th.enh       { background-color: #99ff99 }
+th.dish      { background-color: #ff9999 }
+th.noch      { background-color: #9999ff }
+table.wide   { padding: 5px; }
+td.green     { border: solid black 1px; background-color: #ddffdd; }
+</style>
+
+<!--
+border-color: white;
+               border-style: solid;
+               border-left-width: 10px;
+               border-right-width: 10px;
+               border-top-width: 0px;
+               border-bottom-width: 0px  }
+-->
+
+<script type="text/javascript">
+<!--
+
+function hide_from_header_param_disable(tf)
+{
+    if (document.getElementById) {
+       // NS6 or IE5
+        document.getElementById("hide_from_header_param").disabled = tf;
+    } else if (document.all) {
+        // IE4
+        document.myform.hide_from_header_param.disabled = tf;
+    }
+}
+
+function hide_referer_param_disable(tf)
+{
+    if (document.getElementById) {
+        document.getElementById("hide_referer_param").disabled = tf;
+    } else if (document.all) {
+        document.myform.hide_referer_param.disabled = tf;
+    }
+}
+
+function set_image_blocker_param_disable(tf)
+{
+    if (document.getElementById) {
+        document.getElementById("set_image_blocker_param").disabled = tf;
+    } else if (document.all) {
+        document.myform.set_image_blocker_param.disabled = tf;
+    }
+}
+
+function show_add_header_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("add_header_opts");
+    } else if (document.all) {
+        target = document.add_header_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+function show_deanimate_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("deanimate_opts");
+    } else if (document.all) {
+        target = document.deanimate_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+function show_hide_from_header_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("hide_from_header_opts");
+    } else if (document.all) {
+        target = document.hide_from_header_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+function show_hide_referer_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("hide_referer_opts");
+    } else if (document.all) {
+        target = document.hide_referer_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+function show_user_agent_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("user_agent_opts");
+    } else if (document.all) {
+        target = document.user_agent_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+function show_set_image_blocker_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("set_image_blocker_opts");
+    } else if (document.all) {
+        target = document.set_image_blocker_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+function show_limit_connect_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("limit_connect_opts");
+    } else if (document.all) {
+        target = document.limit_connect_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+function show_send_wafer_opts(tf)
+{
+    if (document.getElementById) {
+        target = document.getElementById("send_wafer_opts");
+    } else if (document.all) {
+        target = document.send_wafer_opts;
+    } else {
+        return;
+    }
+    target.style.display = (tf ? "" : "none");
+}
+
+//-->
+</script>
+</head>
+
+<body>
+
+<form method="GET" action="edit-actions-submit" id="myform" name="myform">
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Edit Actions
+          <input type="hidden" name="f" value="@f@">
+          <input type="hidden" name="v" value="@v@">
+          <input type="hidden" name="s" value="@s@">
+        </h2>
+      </td>
+    </tr>
+
+<tr><td class="wrapbox">
+
+  <table border="0" cellspacing="2" width="100%" class="wide">
+    <tr class="hdr" align="left">
+      <th class="enh" align="center">Enable</th>
+      <th class="dish" align="center">Disable</th>
+      <th class="noch" align="center">No Change</th>
+      <th>Action</th>
+      <th>Description</th>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="add_header" id="add_header_y" value="Y" @add-header-y@
+        onclick="show_add_header_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="add_header" value="N" @add-header-n@
+        onclick="show_add_header_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="add_header" value="X" @add-header-x@
+        onclick="show_add_header_opts(false)"></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@ADD-HEADER">add-header</a></td>
+      <td>Adds HTTP headers.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="add_header_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td>Editing the settings for this option, or turning
+        it on if it was off, is not yet supported using this web-based
+        editor.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="block" value="Y" @block-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="block" value="N" @block-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="block" value="X" @block-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@BLOCK">block</a></td>
+      <td>Block the request</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="crunch_incoming_cookies" value="Y" @crunch-incoming-cookies-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="crunch_incoming_cookies" value="N" @crunch-incoming-cookies-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="crunch_incoming_cookies" value="X" @crunch-incoming-cookies-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</a></td>
+      <td>Prevent the website from setting cookies on your system.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="crunch_outgoing_cookies" value="Y" @crunch-outgoing-cookies-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="crunch_outgoing_cookies" value="N" @crunch-outgoing-cookies-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="crunch_outgoing_cookies" value="X" @crunch-outgoing-cookies-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</a></td>
+      <td>Prevent the website from reading cookies from your system.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="deanimate_gifs" id="deanimate_gifs_y" value="Y" @deanimate-gifs-y@
+        onclick="show_deanimate_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="deanimate_gifs" value="N" @deanimate-gifs-n@
+        onclick="show_deanimate_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="deanimate_gifs" value="X" @deanimate-gifs-x@
+        onclick="show_deanimate_opts(false)"></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@DEANIMATE-GIFS">deanimate-gifs</a></td>
+      <td>Replace animated GIFs with their (first/last) frame.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="deanimate_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td>Use the <input type="radio" name="deanimate_gifs_mode"
+        value="first" id="deanimate_first" @deanimate-gifs-param-first@><label
+        for="deanimate_first">first frame</label>&nbsp;&nbsp; <input
+        type="radio" name="deanimate_gifs_mode" value="last" 
+        id="deanimate_last" @deanimate-gifs-param-last@><label
+        for="deanimate_last">last frame</label></td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="downgrade_http_version" value="Y" @downgrade-http-version-y@></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="downgrade_http_version" value="N" @downgrade-http-version-n@></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="downgrade_http_version" value="X" @downgrade-http-version-x@></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@DOWNGRADE-HTTP-VERSION">downgrade-http-version</td>
+      <td>Change HTTP/1.1 requests to HTTP/1.0.  Only change if you know
+        what you're doing!</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="fast_redirects" value="Y" @fast-redirects-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="fast_redirects" value="N" @fast-redirects-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="fast_redirects" value="X" @fast-redirects-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@FAST-REDIRECTS">fast-redirects</a></td>
+      <td>Bypass some click-tracking URLs.</td>
+    </tr>
+
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="filter_all" id="filter_all_n" value="N" @filter-all-n@ ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="filter_all" id="filter_all_x" value="X" @filter-all-x@ ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@FILTER">filter</a> *</td>
+      <td>Filter the website through regular expression
+        filters.  You can use the radio buttons on this line to disable
+        all filters applied by previous rules, and/or you can enable or
+        disable the filters individually below.</td>
+    </tr>
+@filter-params@
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="handle_as_image" value="Y" @handle-as-image-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="handle_as_image" value="N" @handle-as-image-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="handle_as_image" value="X" @handle-as-image-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@HANDLE-AS-IMAGE">handle-as-image</a></td>
+      <td>Request is for an image (only useful in conjunction with the <i><b><a href="@user-manual@@actions-help-prefix@BLOCK">block</a></b></i>
+        and <i><b><a href="@user-manual@@actions-help-prefix@SET-IMAGE-BLOCKER">set-image-blocker</a></b></i> actions).</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="hide_forwarded_for_headers" value="Y" @hide-forwarded-for-headers-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="hide_forwarded_for_headers" value="N" @hide-forwarded-for-headers-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="hide_forwarded_for_headers" value="X" @hide-forwarded-for-headers-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@HIDE-FORWARDED-FOR-HEADERS">hide-forwarded-for-headers</a></td>
+      <td>Block any existing X-Forwarded-for header, and do not add a new one.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="hide_from_header" id="hide_from_header_y" value="Y" @hide-from-header-y@
+        onclick="show_hide_from_header_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="hide_from_header" value="N" @hide-from-header-n@
+        onclick="show_hide_from_header_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="hide_from_header" value="X" @hide-from-header-x@
+        onclick="show_hide_from_header_opts(false)"></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@HIDE-FROM-HEADER">hide-from-header</a></td>
+      <td>Stop old web browsers from sending the user's e-mail address with
+        every request.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="hide_from_header_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td><input type="radio" name="hide_from_header_mode" value="block"
+        onclick="hide_from_header_param_disable(true);"
+        @hide-from-header-param-block@ id="hide_from_header_mode_block"><label
+        for="hide_from_header_mode_block">Remove completely</label><br>
+        <input type="radio" name="hide_from_header_mode" value="CUSTOM" 
+        onclick="hide_from_header_param_disable(false);"
+        @hide-from-header-param-custom@ id="hide_from_header_mode_set"><label
+        for="hide_from_header_mode_set">Fake e-mail address:</label><br>
+        <input type="text" name="hide_from_header_param" id="hide_from_header_param"
+        size="40" value="@hide-from-header-param@"></td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="hide_referer" id="hide_referer_y" value="Y" @hide-referer-y@
+        onclick="show_hide_referer_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="hide_referer" id="hide_referer_n" value="N" @hide-referer-n@
+        onclick="show_hide_referer_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="hide_referer" id="hide_referer_x" value="X" @hide-referer-x@
+        onclick="show_hide_referer_opts(false)"
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@HIDE-REFERRER">hide-referrer</a></td>
+      <td>Helps prevent tracking by not sending the URL of the previous web
+        page.&nbsp;</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="hide_referer_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td><input type="radio" name="hide_referer_mode" value="block"
+        onclick="hide_referer_param_disable(true)"
+        @hide-referer-param-block@ id="hide_referer_mode_block"><label
+        for="hide_referer_mode_block">Remove completely</label> (breaks images
+        on some free web hosts).<br>
+        <input type="radio" name="hide_referer_mode" value="forge"
+        onclick="hide_referer_param_disable(true)"
+        @hide-referer-param-forge@ id="hide_referer_mode_forge"><label
+        for="hide_referer_mode_forge">Fake as the root directory of the
+        site</label> (fools checks for in-site links.)<br>
+        <input type="radio" name="hide_referer_mode" value="CUSTOM"
+        onclick="hide_referer_param_disable(false)"
+        @hide-referer-param-custom@ id="hide_referer_mode_set"><label
+        for="hide_referer_mode_set">Fake as this web address:</label><br>
+        <input type="text" name="hide_referer_param" 
+        id="hide_referer_param" size="40"
+        value="@hide-referer-param@"></td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="hide_user_agent" id="hide_user_agent_y" value="Y" @hide-user-agent-y@
+        onclick="show_user_agent_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="hide_user_agent" value="N" @hide-user-agent-n@
+        onclick="show_user_agent_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="hide_user_agent" value="X" @hide-user-agent-x@
+        onclick="show_user_agent_opts(false)"></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@HIDE-USER-AGENT">hide-user-agent</a></td>
+      <td>Pretend to be using a different web browser.&nbsp; (Breaks many web
+        sites).</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="user_agent_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td>User Agent string to send:<br>
+        <input type="text" name="hide_user_agent_mode" size="40"
+        value="@hide-user-agent-param@"></td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="kill_popups" value="Y" @kill-popups-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="kill_popups" value="N" @kill-popups-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="kill_popups" value="X" @kill-popups-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@KILL-POPUPS">kill-popups</td>
+      <td>Filter the website through a built-in filter to disable many JavaScript
+        pop-up windows.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="limit_connect" id="limit_connect_y" value="Y" @limit-connect-y@
+        onclick="show_limit_connect_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="limit_connect" value="N" @limit-connect-n@
+        onclick="show_limit_connect_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="limit_connect" value="X" @limit-connect-x@
+        onclick="show_limit_connect_opts(false)"></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@LIMIT-CONNECT">limit-connect</a></td>
+      <td>Specify which ports are allowed for SSL (HTTP CONNECT) access.
+        Note that this allows arbitrary tunnelling, so opening all
+        ports would be a security hole.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="limit_connect_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td>Legal SSL ports (comma separated, ranges allowed):<br>
+        <input type="text" name="limit_connect_mode" size="40"
+        value="@limit-connect-param@"></td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="prevent_compression" value="Y" @prevent-compression-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="prevent_compression" value="N" @prevent-compression-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="prevent_compression" value="X" @prevent-compression-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@PREVENT-COMPRESSION">prevent-compression</a></td>
+      <td>Disables compression.  Compressed web pages are faster to
+        download, but cannot be filtered with <a href="@user-manual@@actions-help-prefix@FILTER"><b>filter</b></a>
+        or <a href="@user-manual@@actions-help-prefix@KILL-POPUPS"><b>kill-popups</b></a>.
+        This setting only affects the few web sites which support
+        compression.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="send_vanilla_wafer" value="Y" @send-vanilla-wafer-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="send_vanilla_wafer" value="N" @send-vanilla-wafer-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="send_vanilla_wafer" value="X" @send-vanilla-wafer-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@SEND-VANILLA-WAFER">send-vanilla-wafer</a></td>
+      <td>Adds a special wafer (standard cookie) to all your requests.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="send_wafer" id="send_wafer_y" value="Y" @send-wafer-y@
+        onclick="show_send_wafer_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="send_wafer" id="send_wafer_n" value="N" @send-wafer-n@
+        onclick="show_send_wafer_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="send_wafer" id="send_wafer_x" value="X" @send-wafer-x@
+        onclick="show_send_wafer_opts(false)"></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@SEND-WAFER">send-wafer</a></td>
+      <td>Adds user-specified cookies.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="send_wafer_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td>Editing the settings for this option, or turning
+        it on if it was off, is not yet supported using this web-based
+        editor.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="session_cookies_only" value="Y" @session-cookies-only-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="session_cookies_only" value="N" @session-cookies-only-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="session_cookies_only" value="X" @session-cookies-only-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@SESSION-COOKIES-ONLY">session-cookies-only</a></td>
+      <td>Any cookies set by the website are changed to temporary
+        ("per-session") ones, which only last until you close your web
+        browser.  This will allow you to use sites that require cookies, but
+        sites will not be able to track you across sessions.  For this to
+        be useful, you should disable 
+        <a href="@user-manual@@actions-help-prefix@CRUNCH-OUTGOING-COOKIES"><b>crunch-outgoing-cookies</b></a> and
+        <a href="@user-manual@@actions-help-prefix@CRUNCH-INCOMING-COOKIES"><b>crunch-incoming-cookies</b></a>.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="set_image_blocker" id="set_image_blocker_y" value="Y" @set-image-blocker-y@
+        onclick="show_set_image_blocker_opts(true)"></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="set_image_blocker" value="N" @set-image-blocker-n@
+        onclick="show_set_image_blocker_opts(false)"></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="set_image_blocker" value="X" @set-image-blocker-x@
+        onclick="show_set_image_blocker_opts(false)"></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@SET-IMAGE-BLOCKER">set-image-blocker</a></td>
+      <td>Specifies how to block images.</td>
+    </tr>
+    <tr class="bg1" align="left" valign="top" id="set_image_blocker_opts">
+      <td class="en1">&nbsp;</td>
+      <td class="dis1">&nbsp;</td>
+      <td class="noc1">&nbsp;</td>
+      <td>&nbsp;</td>
+      <td><input type="radio" name="set_image_blocker_mode"
+        onclick="set_image_blocker_param_disable(true)"
+        value="pattern" id="set_image_blocker_mode_pattern"
+        @set-image-blocker-param-pattern@><label
+        for="set_image_blocker_mode_pattern">Send a pattern (<img
+        src="send-banner?type=p" width="12" height="12"
+        alt="pattern">)</label><br>
+        <input type="radio" name="set_image_blocker_mode" value="blank"
+        onclick="set_image_blocker_param_disable(true)"
+        id="set_image_blocker_mode_blank" @set-image-blocker-param-blank@><label 
+        for="set_image_blocker_mode_blank">Send a 1x1 transparent GIF</label><br>
+        <input type="radio" name="set_image_blocker_mode" value="CUSTOM"
+        onclick="set_image_blocker_param_disable(false)"
+        id="set_image_blocker_mode_set" @set-image-blocker-param-custom@><label
+        for="set_image_blocker_mode_set">Redirect
+        the browser to this image URL:</label><br>
+        <input type="text" name="set_image_blocker_param" id="set_image_blocker_param"
+        size="40" value="@set-image-blocker-param@"></td>
+    </tr>
+  </table>
+
+</td></tr>
+
+    <tr>
+      <td class="green" align="center">
+        <p><input type="submit" value="Submit" name="Submit"></p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+    <tr>
+      <td>
+        <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+      </td>
+    </tr>
+
+  </table>
+</form>
+
+
+<script type="text/javascript">
+<!--
+
+if (document.getElementById) {
+    // alert("Netscape 6 or IE5");
+    document.getElementById("hide_from_header_param").disabled = !(document.getElementById("hide_from_header_mode_set").checked);
+    document.getElementById("hide_referer_param").disabled = !(document.getElementById("hide_referer_mode_set").checked);
+    document.getElementById("set_image_blocker_param").disabled = !(document.getElementById("set_image_blocker_mode_set").checked);
+
+    show_add_header_opts    (document.getElementById("add_header_y").checked);
+    show_deanimate_opts     (document.getElementById("deanimate_gifs_y").checked);
+    show_hide_from_header_opts(document.getElementById("hide_from_header_y").checked);
+    show_hide_referer_opts  (document.getElementById("hide_referer_y").checked);
+    show_user_agent_opts    (document.getElementById("hide_user_agent_y").checked);
+    show_set_image_blocker_opts (document.getElementById("set_image_blocker_y").checked);
+    show_limit_connect_opts (document.getElementById("limit_connect_y").checked);
+    show_send_wafer_opts    (document.getElementById("wafer_y").checked);
+} else if (document.all) {
+    // alert("IE4");
+    document.myform.hide_from_header_param.disabled = !(document.myform.hide_from_header_mode_set.checked);
+    document.myform.hide_referer_param.disabled = !(document.myform.hide_referer_mode_set.checked);
+    document.myform.set_image_blocker_param.disabled = !(document.myform.set_image_blocker_mode_set.checked);
+
+    show_add_header_opts    (document.myform.add_header_y.checked);
+    show_deanimate_opts     (document.myform.deanimate_gifs_y.checked);
+    show_hide_from_header_opts (document.myform.hide_from_header_y.checked);
+    show_hide_referer_opts  (document.myform.hide_referer_y.checked);
+    show_user_agent_opts    (document.myform.hide_user_agent_y.checked);
+    show_set_image_blocker_opts (document.myform.set_image_blocker_y.checked);
+    show_limit_connect_opts (document.myform.limit_connect_y.checked);
+    show_send_wafer_opts    (document.myform.wafer_y.checked);
+} else if (document.layers) {
+    // alert("Netscape 4");
+}
+//-->
+</script>
+
+
+</body>
+
+</html>
diff --git a/templates/edit-actions-for-url-filter b/templates/edit-actions-for-url-filter
new file mode 100644 (file)
index 0000000..952ed14
--- /dev/null
@@ -0,0 +1,7 @@
+<tr class="bg1" align="left" valign="top">\r
+  <td class="en1" align="center" valign="middle"><input type="radio" name="filter_r@index@" value="Y" @this-filter-y@></td>\r
+  <td class="dis1" align="center" valign="middle"><input type="radio" name="filter_r@index@" value="N" @this-filter-n@></td>\r
+  <td class="noc1" align="center" valign="middle"><input type="radio" name="filter_r@index@" value="X" @this-filter-x@></td>\r
+  <td class="action"><a href="@user-manual@@actions-help-prefix@FILTER">filter</a> @name@<input type="hidden" name="filter_n@index@" value="@name@"></td>\r
+  <td>@description@</td>\r
+</tr>\r
diff --git a/templates/edit-actions-list b/templates/edit-actions-list
new file mode 100644 (file)
index 0000000..cde66a6
--- /dev/null
@@ -0,0 +1,363 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa/current/templates/edit-actions-list,v $
+#
+# Purpose     :  Template used to edit the actions file.
+# 
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-list,v $
+#    Revision 1.25  2002/05/21 21:02:52  oes
+#    Added more help links
+#
+#    Revision 1.24  2002/05/21 19:11:40  oes
+#     - Added client-side JavaScript versions of edit and add URL forms
+#     - Moved jump targets to before container table cell
+#     - Let earu determine the jump target when removing URLs via JS
+#     - Fixed broken help link
+#
+#    Revision 1.23  2002/05/12 15:53:10  jongfoster
+#    Restoring CVS log information accidentally removed in
+#    my previous commit.
+#
+#    Revision 1.22  2002/05/12 15:45:33  jongfoster
+#    Applying [Patch 552094] New templates for edit-actions-list
+#    This cleans up the templates by:
+#    - Removing the (confusing) alternating color scheme.
+#    - Making everything left-justified.
+#
+#    Revision 1.21  2002/05/03 22:58:15  jongfoster
+#    Fixing link target in all URLs section
+#
+#    Revision 1.20  2002/04/26 12:57:18  oes
+#     - Central "button" link style in cgi-style.css
+#     - Help links now dynamic
+#
+#    Revision 1.19  2002/04/24 02:19:16  oes
+#     - Show name of actions file being edited
+#     - Show context sensitive help
+#     - Add buttons for easy changing of defaults
+#     - Cosmetics and clarifications
+#
+#    Revision 1.18  2002/04/18 19:21:09  jongfoster
+#    Added code to detect "conventional" action files, that start
+#    with a set of actions for all URLs (the pattern "/").
+#    These are special-cased in the "edit-actions-list" CGI, so
+#    that a special UI can be written for them.
+#
+#    Revision 1.17  2002/04/10 13:32:53  oes
+#    Made templates modular
+#
+#    Revision 1.16  2002/04/08 17:08:14  oes
+#    Cosmetic: make status in title lowercase
+#
+#    Revision 1.15  2002/04/05 16:01:32  oes
+#    Correct HTML, external Stylesheets, eye candy, some fixes
+#
+#    Revision 1.14  2002/03/26 22:29:56  swa
+#    we have a new homepage!
+#
+#    Revision 1.13  2002/03/24 15:23:33  jongfoster
+#    Name changes
+#
+#    Revision 1.12  2002/03/24 11:01:06  swa
+#    name change
+#
+#    Revision 1.11  2002/03/23 16:18:15  swa
+#    renamed every reference to the old name with foobar.
+#    fixed "application foobar application" tag, fixed
+#    "the foobar" with "foobar". left junkbuster in cvs
+#    comments and remarks to history untouched. should
+#    make final rename easier.
+#
+#    Revision 1.10  2002/03/16 15:22:19  jongfoster
+#    Moving 'alpha' warning to the end of the page
+#
+#    Revision 1.9  2002/03/05 00:24:51  jongfoster
+#    Patch to always edit the current actions file.
+#
+#    Revision 1.8  2002/03/03 10:29:12  swa
+#    point users to the right feedback forms,
+#    not necessarily the developer list.
+#
+#    Revision 1.7  2002/01/23 00:26:45  jongfoster
+#    Reducing length of URLs
+#    Where encoded and unencoded versions of a string existed, removing
+#    the unencoded one.
+#
+#    Revision 1.6  2002/01/17 21:33:00  jongfoster
+#    Replacing all references to the URL of the config interface
+#    with @default-cgi@
+#
+#    Revision 1.5  2002/01/17 21:21:05  jongfoster
+#    DOS->Unix line endings
+#
+#    Revision 1.4  2001/11/13 00:58:18  jongfoster
+#    New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Browser support for the CSS on this page:
+#   MS Internet Explorer 5.5 - Yes - everything works.
+#   Netscape 6.2             - Yes - everything works.
+#   Netscape 4.75            - No  - CSS buttons look really bad, but they are
+#                                    usable.  Everything else works.
+#   Opera 5.12               - Yes - everything works.
+#   MS Internet Explorer 4+  - Untested
+#   MS IE 3.x, NS3.x         - Untested (Don't support CSS, so everything
+#                              should work, but will look ugly).
+#   Mozilla >=0.6            - Yes - everything works.
+#
+# All browsers should work, you just might not get the pretty CSS buttons.
+#
+# If your favorite browser isn't listed/tested, please test and add it.
+#
+#
+#############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+#
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+  <title>Privoxy: Edit actions file @f@.action</title>
+
+  <style type="text/css">
+
+table.framed {
+  border: solid black 1px;
+  margin: 10px 0px;
+}
+tr.actions {
+  background-color: #eeffee;
+}
+tr.url {
+  background-color: #ddddff;
+}
+tr.adv {
+  background-color: #FFFFD0;
+}
+td.header {
+  font-weight: bold;
+  font-size: 110%;
+  padding: 10px 15px 2px 15px;
+}
+td.url {
+  font-weight: bold;
+}
+td.action {
+  font-weight: bold;
+  font-style: italic;
+  padding: 2px 30px;
+}
+td.nbr, td.buttons {
+  white-space: nowrap;
+}
+td.indentbuttons {
+  padding: 2px 30px;
+}
+</style>
+
+<script type="text/javascript">
+<!--
+
+// Non-JS capable browsers will follow the link to a HTML "are you sure?" page
+// JavaScript-capable browsers will call this function, which does a
+// client-side prompt for speed.  It may kick off the delete directly.
+// It always returns false to cancel following the link.
+function rm_p(pattern,curtext)
+{
+   if (window.confirm("Are you sure you want to delete this URL pattern?\nPattern is: "+unescape(curtext)))
+   { window.location.href="edit-actions-remove-url?f=@f@&v=@v@&p="+pattern; }
+   return false;
+}
+
+function e_p(pattern,curtext)
+{
+   if(newtext=window.prompt("Edit the pattern to your needs:", unescape(curtext)))
+   { window.location.href="edit-actions-url?f=@f@&v=@v@&p="+pattern+"&u="+escape(newtext); }
+   return false;
+}
+
+function a_p(section)
+{
+   if(newtext=window.prompt("Enter the new pattern:", ""))
+   { window.location.href="edit-actions-add-url?f=@f@&v=@v@&s="+section+"&u="+escape(newtext); }
+   return false;
+}
+
+//-->
+</script>
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="info">
+       <h2>What is all this?</h2>
+        <p>
+         If you haven't already done so, it is <b>strongly recommended</b> that you at 
+         least skim <a href="@user-manual@@actions-help-prefix@ACTIONS-FILE">the
+         chapter on actions files</a> in the <a href="@user-manual@">user manual</a>
+         before making any changes. You will also find a comprehensive list of all available actions
+         there.
+        </p>
+         <!-- @if-all-urls-present-then@ -->
+        <p>
+         Please note that <b>the first section has special importance</b>. It sets the default actions for
+         all URLs. The resulting actions for a particular URL may differ from these defaults if that
+         URL matches again further down, but this section is largely responsible for your browsing
+         experience. Edit manually with great care, or choose from the predefined sets of actions.
+        </p>
+        <!-- @else-not-all-urls-present@@endif-all-urls-present@ -->
+        <!-- @if-default-action-then@ -->
+        <p>
+         This is the default action file. Updates for it are available from
+         <a href="http://www.privoxy.org/">Privoxy.org</a> on a regular basis. 
+         It is therefore <b>not recommended</b> that you add your private
+         rules here, since they will be lost if you install an update in the future.
+         Put your rules in a separate actions file, like <tt>user.action</tt> instead.
+        </p>
+        <!-- @else-not-default-action@@endif-default-action@ -->
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <div class="buttons">
+          <h2>Editing Actions File @f@.action</h2>
+          <!-- @if-all-urls-present-then@@else-not-all-urls-present@ -->
+          <p><a class="cmd" href="edit-actions-section-add?f=@f@&amp;v=@v@&amp;s=0">Insert new section at top</a></p>
+          <!-- @endif-all-urls-present@ -->
+        </div>
+      </td>
+    </tr>
+
+    <!-- @if-all-urls-present-then@ -->
+    <tr>
+      <td class="container"><a name="l@all-urls-s@"></a>
+        <table border="0" width="100%" cellspacing="2" cellpadding="3" class="framed">
+          <tr class="actions"><td class="header"><a href="@user-manual@@actions-help-prefix@ACTIONS">Actions</a>:</td></tr>
+          <tr class="actions">
+            <td class="indentbuttons">
+              <a href="eafu?f=@f@&amp;v=@v@&amp;s=@all-urls-s@">Edit</a>
+              @all-urls-buttons@
+            </td>
+          </tr>
+          <tr class="actions"><td class="action">@all-urls-actions@</td></tr>
+          <tr class="url"><td class="header"><a href="@user-manual@@actions-help-prefix@AF-PATTERNS">URL patterns</a>:</td></tr>
+          <tr class="url"><td class="indentbuttons">/ &nbsp; <i>(Matches all requests)</a></td></tr>
+          <tr class="adv"><td class="header">Advanced:</td></tr>
+          <tr class="adv">
+            <td class="indentbuttons">
+              <a href="easa?f=@f@&amp;v=@v@&amp;s=@all-urls-s@#l@all-urls-s-next@">Insert new section below</a>
+            </td>
+          </tr>
+        </table>
+      </td>
+    </tr>
+    <!-- @else-not-all-urls-present@@endif-all-urls-present@ -->
+
+@sections@
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+    <tr>
+      <td>
+        <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+      </td>
+    </tr>
+
+  </table>
+</body>
+
+</html>
diff --git a/templates/edit-actions-list-button b/templates/edit-actions-list-button
new file mode 100644 (file)
index 0000000..5323558
--- /dev/null
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa/current/templates/edit-actions-list-button,v $
+#
+# Purpose     :  Template which forms part of edit-actions-list
+# 
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-list-button,v $
+#    Revision 1.2  2002/05/12 15:45:33  jongfoster
+#    Applying [Patch 552094] New templates for edit-actions-list
+#    This cleans up the templates by:
+#    - Removing the (confusing) alternating color scheme.
+#    - Making everything left-justified.
+#
+#    Revision 1.1  2002/05/03 23:00:38  jongfoster
+#    Support for templates for "standard actions" buttons.
+#    See bug #549871
+#
+#############################################################################
+ &nbsp; <a href="eas?f=@f@&amp;v=@v@&amp;s=@all-urls-s@&amp;p=@button-name@#l@all-urls-s@">Set to @button-name@</a>
diff --git a/templates/edit-actions-list-section b/templates/edit-actions-list-section
new file mode 100644 (file)
index 0000000..b48bcb5
--- /dev/null
@@ -0,0 +1,114 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa/current/templates/edit-actions-list-section,v $
+#
+# Purpose     :  Template which forms part of edit-actions-list
+# 
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-list-section,v $
+#    Revision 1.14  2002/05/21 19:12:43  oes
+#     - Added client-side JavaScript versions of edit and add URL forms
+#     - Moved jump targets to before container table cell
+#
+#    Revision 1.13  2002/05/12 15:45:33  jongfoster
+#    Applying [Patch 552094] New templates for edit-actions-list
+#    This cleans up the templates by:
+#    - Removing the (confusing) alternating color scheme.
+#    - Making everything left-justified.
+#
+#    Revision 1.12  2002/04/26 12:58:11  oes
+#    Central "button" link style in cgi-style.css
+#
+#    Revision 1.11  2002/04/24 02:14:03  oes
+#    Changed shortcuts, Cosmetics
+#
+#    Revision 1.10  2002/04/17 21:27:26  jongfoster
+#    Adding #linenumber to the URLs which affect blocks, to make
+#    editing in long files easier.
+#
+#    Revision 1.9  2002/04/17 15:51:47  oes
+#    Args! Restoring CVS history
+#
+#    Revision 1.8  2002/04/17 15:04:16  oes
+#    Adapted to style change
+#
+#    Revision 1.7  2002/03/26 22:29:56  swa
+#    we have a new homepage!
+#
+#    Revision 1.6  2002/03/24 11:01:06  swa
+#    name change
+#
+#    Revision 1.5  2002/01/23 00:26:45  jongfoster
+#    Reducing length of URLs
+#    Where encoded and unencoded versions of a string existed, removing
+#    the unencoded one.
+#
+#    Revision 1.4  2002/01/17 21:33:00  jongfoster
+#    Replacing all references to the URL of the config interface
+#    with @default-cgi@
+#
+#    Revision 1.3  2001/11/13 00:58:18  jongfoster
+#    New version of actions file editor templates
+#
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# sectionid
+# urls
+#
+#############################################################################
+#
+# ** Important note: **
+#
+# It is important to keep this file small.  That's why all the
+# identifiers in the HTML are short and cryptic.  Currently, the main
+# edit-actions page is ~300k.  Before it was optimized, it was ~550k.
+#
+#############################################################################
+
+<tr><td class="container"><a name="l@s@"></a>
+<table border="0" width="100%" cellspacing="2" cellpadding="3" class="framed">
+<tr class="actions"><td class="header"><a href="@user-manual@@actions-help-prefix@ACTIONS">Actions</a>:</td></tr>
+<tr class="actions"><td class="indentbuttons"><a href="eafu?f=@f@&amp;v=@v@&amp;s=@s@">Edit</a></td></tr>
+<tr class="actions"><td class="action">@actions@</td></tr>
+<tr class="url"><td class="header"><a href="@user-manual@@actions-help-prefix@AF-PATTERNS">URL patterns</a>:</td></tr>
+<tr class="url"><td class="indentbuttons"><a href="eaa?f=@f@&amp;v=@v@&amp;s=@s@" onclick="return a_p(@s@);">Add</a></td></tr>
+@urls@
+<tr class="adv"><td class="header">Advanced:</td></tr>
+<tr class="adv"><td class="indentbuttons">
+@if-s-prev-exists-start@<a href="eass?f=@f@&amp;v=@v@&amp;s1=@s-prev@&amp;s2=@s@#l@s-prev@">Move section up</a> &nbsp; @if-s-prev-exists-end@
+@if-s-next-exists-start@<a href="eass?f=@f@&amp;v=@v@&amp;s1=@s@&amp;s2=@s-next@#l@s@">Move section down</a> &nbsp; @if-s-next-exists-end@
+<a href="easa?f=@f@&amp;v=@v@&amp;s=@s@#l@s-next@">Insert new section below</a>
+@if-empty-section-start@ &nbsp; <a href="easr?f=@f@&amp;v=@v@&amp;s=@s@#l@s@">Delete whole section</a>@if-empty-section-end@
+</td></tr>
+</table>
+</td></tr>
diff --git a/templates/edit-actions-list-url b/templates/edit-actions-list-url
new file mode 100644 (file)
index 0000000..f44eb58
--- /dev/null
@@ -0,0 +1,84 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa//current/templates/edit-actions-list-url,v $
+#
+# Purpose     :  Template which forms part of edit-actions-list
+# 
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-list-url,v $
+#    Revision 1.9  2002/05/12 15:45:33  jongfoster
+#    Applying [Patch 552094] New templates for edit-actions-list
+#    This cleans up the templates by:
+#    - Removing the (confusing) alternating color scheme.
+#    - Making everything left-justified.
+#
+#    Revision 1.8  2002/04/26 12:58:11  oes
+#    Central "button" link style in cgi-style.css
+#
+#    Revision 1.7  2002/03/26 22:29:56  swa
+#    we have a new homepage!
+#
+#    Revision 1.6  2002/03/24 11:01:06  swa
+#    name change
+#
+#    Revision 1.5  2002/01/23 00:26:45  jongfoster
+#    Reducing length of URLs
+#    Where encoded and unencoded versions of a string existed, removing
+#    the unencoded one.
+#
+#    Revision 1.4  2002/01/17 21:33:00  jongfoster
+#    Replacing all references to the URL of the config interface
+#    with @default-cgi@
+#
+#    Revision 1.3  2001/11/13 00:58:18  jongfoster
+#    New version of actions file editor templates
+#
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# sectionid
+# urls
+#
+#############################################################################
+#
+# ** Important note: **
+#
+# It is *extremely* important to keep this file small.  That's why all the
+# identifiers in the HTML are short and cryptic.  Currently, the main
+# edit-actions page is ~300k.  Before it was optimized, it was ~550k.
+#
+#############################################################################
+<tr class="url" valign="top">
+<td class="indentbuttons"><a name="l@p@"
+href="ear?f=@f@&amp;v=@v@&amp;p=@p@" onclick="return rm_p(@p@,'@url@');">Remove</a>&nbsp;&nbsp;&nbsp;<a
+href="eau?f=@f@&amp;v=@v@&amp;p=@p@" onclick="return  e_p(@p@,'@url@');">Edit</a>&nbsp; @url-html@</td>
+</tr>
diff --git a/templates/edit-actions-remove-url-form b/templates/edit-actions-remove-url-form
new file mode 100644 (file)
index 0000000..14f5fd9
--- /dev/null
@@ -0,0 +1,187 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa//current/templates/edit-actions-remove-url-form,v $
+#
+# Purpose     :  Template used to confirm removal of a particular URL
+#                pattern from an actions file.  Only used on browsers that
+#                don't support JavaScript.
+# 
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-remove-url-form,v $
+#    Revision 1.13  2002/04/10 13:32:53  oes
+#    Made templates modular
+#
+#    Revision 1.12  2002/04/08 17:08:14  oes
+#    Cosmetic: make status in title lowercase
+#
+#    Revision 1.11  2002/04/05 16:01:30  oes
+#    Correct HTML, external Stylesheets, eye candy, some fixes
+#
+#    Revision 1.10  2002/03/26 22:29:56  swa
+#    we have a new homepage!
+#
+#    Revision 1.9  2002/03/24 15:23:33  jongfoster
+#    Name changes
+#
+#    Revision 1.8  2002/03/24 11:01:06  swa
+#    name change
+#
+#    Revision 1.7  2002/03/23 16:18:15  swa
+#    renamed every reference to the old name with foobar.
+#    fixed "application foobar application" tag, fixed
+#    "the foobar" with "foobar". left junkbuster in cvs
+#    comments and remarks to history untouched. should
+#    make final rename easier.
+#
+#    Revision 1.6  2002/03/16 15:22:19  jongfoster
+#    Moving 'alpha' warning to the end of the page
+#
+#    Revision 1.5  2002/03/03 10:29:12  swa
+#    point users to the right feedback forms,
+#    not necessarily the developer list.
+#
+#    Revision 1.4  2002/01/23 00:26:45  jongfoster
+#    Reducing length of URLs
+#    Where encoded and unencoded versions of a string existed, removing
+#    the unencoded one.
+#
+#    Revision 1.3  2002/01/17 21:33:00  jongfoster
+#    Replacing all references to the URL of the config interface
+#    with @default-cgi@
+#
+#    Revision 1.2  2002/01/17 21:21:05  jongfoster
+#    DOS->Unix line endings
+#
+#    Revision 1.1  2001/11/13 00:58:18  jongfoster
+#    New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# section
+# pattern
+# oldval
+# jumptarget - append to eal URL to jump to relevant section
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+  <title>Privoxy@@my-hostname@: Remove URL Pattern</title>
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Remove URL Pattern</h2>
+        <p>Are you sure you want to delete this URL pattern?  The pattern is:</p>
+        <p class="important">@u@</p>
+        <p>
+          <a class="cmd" href="edit-actions-remove-url?f=@f@&amp;v=@v@&amp;p=@p@">OK</a>
+          &nbsp;
+          <a class="cmd" href="edit-actions-list?f=@f@@jumptarget@">Cancel</a>
+        </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+    <tr>
+      <td>
+        <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+      </td>
+    </tr>
+
+  </table>
+</body>
+
+</html>
diff --git a/templates/edit-actions-url-form b/templates/edit-actions-url-form
new file mode 100644 (file)
index 0000000..1719c19
--- /dev/null
@@ -0,0 +1,205 @@
+##############################################################################
+#
+# File        :  $Source: /cvsroot/ijbswa//current/templates/edit-actions-url-form,v $
+#
+# Purpose     :  Template used to edit a URL pattern in an actions file.
+#
+#
+# Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+#                Privoxy team. http://www.privoxy.org/
+#
+#                Original Author: Copyright (C) 2001 Jonathan Foster
+#                http://www.jon-foster.co.uk/
+#
+#                This program is free software; you can redistribute it 
+#                and/or modify it under the terms of the GNU General
+#                Public License as published by the Free Software
+#                Foundation; either version 2 of the License, or (at
+#                your option) any later version.
+#
+#                This program is distributed in the hope that it will
+#                be useful, but WITHOUT ANY WARRANTY; without even the
+#                implied warranty of MERCHANTABILITY or FITNESS FOR A
+#                PARTICULAR PURPOSE.  See the GNU General Public
+#                License for more details.
+#
+#                The GNU General Public License should be included with
+#                this file.  If not, you can view it at
+#                http://www.gnu.org/copyleft/gpl.html
+#                or write to the Free Software Foundation, Inc., 59
+#                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# Revisions   :
+#    $Log: edit-actions-url-form,v $
+#    Revision 1.13  2002/04/10 13:32:53  oes
+#    Made templates modular
+#
+#    Revision 1.12  2002/04/08 17:08:14  oes
+#    Cosmetic: make status in title lowercase
+#
+#    Revision 1.11  2002/04/05 16:01:32  oes
+#    Correct HTML, external Stylesheets, eye candy, some fixes
+#
+#    Revision 1.10  2002/03/26 22:29:56  swa
+#    we have a new homepage!
+#
+#    Revision 1.9  2002/03/24 15:23:33  jongfoster
+#    Name changes
+#
+#    Revision 1.8  2002/03/24 11:01:06  swa
+#    name change
+#
+#    Revision 1.7  2002/03/23 16:18:15  swa
+#    renamed every reference to the old name with foobar.
+#    fixed "application foobar application" tag, fixed
+#    "the foobar" with "foobar". left junkbuster in cvs
+#    comments and remarks to history untouched. should
+#    make final rename easier.
+#
+#    Revision 1.6  2002/03/16 15:22:19  jongfoster
+#    Moving 'alpha' warning to the end of the page
+#
+#    Revision 1.5  2002/03/03 10:29:13  swa
+#    point users to the right feedback forms,
+#    not necessarily the developer list.
+#
+#    Revision 1.4  2002/01/23 00:26:45  jongfoster
+#    Reducing length of URLs
+#    Where encoded and unencoded versions of a string existed, removing
+#    the unencoded one.
+#
+#    Revision 1.3  2002/01/17 21:33:00  jongfoster
+#    Replacing all references to the URL of the config interface
+#    with @default-cgi@
+#
+#    Revision 1.2  2002/01/17 21:21:05  jongfoster
+#    DOS->Unix line endings
+#
+#    Revision 1.1  2001/11/13 00:58:18  jongfoster
+#    New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# f - filename
+# v - version
+# s - section
+# p - pattern
+# u - old value of URL
+# jumptarget - append to eal URL to jump to relevant section
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+  <title>Privoxy@@my-hostname@: Edit URL Pattern</title>
+
+  <script type="text/javascript">
+<!--
+function validate(text)
+{
+  if (text=="")
+  {
+    alert("You need to type a pattern in order to continue!");
+    return false;
+  }
+
+  return true;
+}
+//-->
+  </script>
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Edit URL Pattern</h2>
+        <form method="GET" action="edit-actions-url"
+              onSubmit="return validate(u.value);">
+          <p>
+            <input type="hidden" name="f" value="@f@">
+            <input type="hidden" name="v" value="@v@">
+            <input type="hidden" name="p" value="@p@">
+            <input type="text" name="u" value="@u@" size="78"><br>
+            <input type="submit" value="Submit"> &nbsp;
+            <input type="reset" value="Reset"> &nbsp;
+            <a class="cmd" href="edit-actions-list?f=@f@@jumptarget@">Cancel</a>
+          </p>
+        </form>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+    <tr>
+      <td>
+        <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+      </td>
+    </tr>
+
+  </table>
+</body>
+
+</html>
diff --git a/templates/mod-local-help b/templates/mod-local-help
new file mode 100644 (file)
index 0000000..21d6596
--- /dev/null
@@ -0,0 +1,12 @@
+        <h2>Local Privoxy support:</h2>
+
+<!-- @if-have-proxy-info-start -->
+        <p>You can consult the <a href="@proxy-info-url@">online documentation</a> for more information about this Privoxy installation.</p>        
+<!-- if-have-proxy-info-end@ -->
+
+<!-- @if-have-adminaddr-info-start -->
+        <p>Address e-mail questions about this service to
+          <a href="mailto:@admin-address@"><code>@admin-address@</code></a>,
+          who will be glad to help you.
+        </p>
+<!-- if-have-adminaddr-info-end@ -->
diff --git a/templates/mod-support-and-service b/templates/mod-support-and-service
new file mode 100644 (file)
index 0000000..d937e16
--- /dev/null
@@ -0,0 +1,22 @@
+        <h2>Support and Service via Sourceforge:</h2>
+        <p>
+          We value your feedback. To provide you with the best support,
+          we ask that you:
+        </p>
+        <ul>
+          <li>
+            use the <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=211118">support forum</a> to get help.
+          </li>
+          <li>
+            submit banners and all problems with the actions file only through the
+            <a href="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">actions file feedback system.</a>
+          </li>
+          <li>
+            submit bugs only through our <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=111118">bug tracker</a>.
+            Make sure that the bug has not yet been submitted.
+          </li>
+          <li>
+            submit feature requests only through our <a href="http://sourceforge.net/tracker/?atid=361118&amp;group_id=11118&amp;func=browse">feature
+            request tracker</a>.
+          </li>
+        </ul>
diff --git a/templates/mod-title b/templates/mod-title
new file mode 100644 (file)
index 0000000..1829604
--- /dev/null
@@ -0,0 +1,4 @@
+        <h1>
+          This is <a href="@homepage@">Privoxy</a> @version@ on @my-hostname@ (@my-ip-address@), port @my-port@,
+          @if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@
+        </h1>
diff --git a/templates/mod-unstable-warning b/templates/mod-unstable-warning
new file mode 100644 (file)
index 0000000..bb35ccf
--- /dev/null
@@ -0,0 +1,6 @@
+        <h2>Warning:</h2>
+        <p>
+          <b>Please note that this <em class="warning">@code-status@</em> release
+          of the proxy software is not intended for production systems!
+          <br>Use at your own risk. See the <a href="http://www.gnu.org/copyleft/gpl.html">license</a> for details.</b>
+        </p>
diff --git a/templates/no-such-domain b/templates/no-such-domain
new file mode 100644 (file)
index 0000000..f220b5c
--- /dev/null
@@ -0,0 +1,160 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the proxy's administrator, as configured
+#    in the 'config' file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+#  host:
+#    The host part of the request that lead to this problem
+#  hostport:
+#    The host and port part of the request that lead to this problem
+#  path:
+#    The path part of the request that lead to this problem
+#  proxy-info-url:
+#    The URL to local online Privoxy documentation, if define in the
+#    'config' file
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>404 - No such Domain (Privoxy@@my-hostname@)</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="status">
+        404
+      </td>     
+      <td class="title" style="width: 100%">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning" colspan="2">
+        <h2>No such domain</h2>
+          <p>Your request for <a href="@protocol@@hostport@@path@"><b>@protocol@@hostport@@path@</b></a>
+            could not be fulfilled, because the domain name <b>@host@</b> could not be resolved.
+          </p>
+          <p>This is often a temporary failiure, so you might just
+            <a href="@protocol@@hostport@@path@">try again</a>.
+         </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box" colspan="2">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+    
+    <tr>
+      <td colspan="2">
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+  </table>
+
+</body>
+</html>
diff --git a/templates/show-request b/templates/show-request
new file mode 100644 (file)
index 0000000..0871a11
--- /dev/null
@@ -0,0 +1,158 @@
+##########################################################
+#
+# Show-Request-CGI Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#  client-request:
+#    The request and headers that the client sent.
+#  processed-request:
+#    What we would have rewritten this request to, if this had not
+#    been intercepted.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy@@my-hostname@</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+       <h2>Show-Request</h2>
+          <p>
+            Here you see the original headers that your client sent when requesting this page, along with
+            the headers that Privoxy would have sent to the remote server if this request hadn't been
+            intercepted. 
+          </p>
+
+        <h3>Original Client Request:</h3>
+        <pre>@client-request@</pre>
+
+        <h3>Processed Request:</h3>
+       <pre>@processed-request@</pre>
+
+      </td>
+    </tr>
+
+     <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+     <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>   
+  </table>
+
+</body>
+</html>
diff --git a/templates/show-status b/templates/show-status
new file mode 100644 (file)
index 0000000..0ec4f2e
--- /dev/null
@@ -0,0 +1,340 @@
+##########################################################
+#
+# Show-Status-CGI Output template for Privoxy.
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+#  redirect-url:
+#    The URL to a script that will redirect to the Privoxy
+#    documentation for a given item  
+#  invocation:
+#    The command line with whitch Privoxy was invoked
+#  options:
+#    The options read from the configfile, linked to their
+#    explanations, plus warnings if parsing acl or forward
+#    statements produced errors.
+#  sourceversions:
+#    A HTML-formatted list of the individual source file cvs versions
+#  defines:
+#    A HTML-formatted list of all conditional #defines used when
+#    Privoxy was compiled
+#
+#  
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    This is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#  statistics:
+#    Privoxy was compiled with statistics support
+#  have-stats:
+#    There have been previous requests and statistics have
+#    been collected. In this case, the following symbols
+#    are available:
+#    requests-received:
+#      The number of requests received so far
+#    requests-blocked:
+#      The number of request blocked so far
+#    percent-blocked:
+#      The percentage of blocked requests
+#  have-no-stats:
+#    There haven't any statistics been collected yet
+#  pcrs-support:
+#    Privoxy was compiled with pcrs support
+#  trust-support:
+#    Privoxy was compiled with trust support
+#  actions-filename:
+#    The path to the actions file.
+#  re-filter-filename:
+#    The path to the re_filter file. Only available if
+#    pcrs-support is set
+#  trust-filename:
+#    The path to the trust file.Only available if
+#    trust-support is set
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy@@my-hostname@: Proxy Status</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>The following files are in use:</h2>
+        <p>
+          <table class="transparent">
+            <tr>
+              <th colspan="2"><a href="@user-manual@@actions-help-prefix@ACTIONS-FILE">Actions Files:</a></th>
+            </tr>
+              @actions-filenames@
+           <tr>
+              <th colspan="2"><a href="@user-manual@filter-file.html">Filter File:</a></th>
+           </tr>
+           <tr>
+             <td>
+               @re-filter-filename@
+             </td>
+             <td class="buttons">
+               <!-- @if-have-filterfile-start -->
+               <a href="show-status?file=filter">View</a>
+               <!-- if-have-filterfile-end@ -->
+             </td>
+           </tr>
+<!-- @if-trust-support-start -->
+           <tr>
+              <th colspan="2"><a href="@user-manual@config.html#TRUSTFILE">Trust File:</a></th>
+           </tr>
+            <td>
+               @trust-filename@
+             </td>
+             <td class="buttons">
+               <!-- @if-have-trustfile-start -->
+               <a href="show-status?file=trust">View</a>
+               <!-- if-have-trustfile-end@ -->
+            </td>
+           </tr>
+<!-- if-trust-support-end@ -->
+          </table>
+        </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>Privoxy was <a href="@user-manual@startup.html#CMDOPTIONS">invoked</a> as follows:</h2>
+        <p>@invocation@</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>The following options were given in the <a href="@user-manual@config.html">config file</a>:</h2>
+        <p>@options@</p>
+      </td>
+    </tr>
+
+<!-- @if-statistics-start -->
+    <tr>
+      <td class="box">
+        <h2>Blocking Statistics:</h2>
+        <p>
+  <!-- @if-have-stats-start -->
+          @requests-blocked@ out of @requests-received@ requests have been blocked,
+          which equals a block rate of @percent-blocked@%.
+<!-- if-have-stats-end@ -->
+<!-- @if-have-no-stats-start -->
+          There haven't been any requests so far.
+<!-- if-have-no-stats-end@ -->
+        </p>                                   
+      </td>
+    </tr>
+<!-- if-statistics-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Conditional #defines:</h2>
+        <p>
+          <table border="1" style="margin-left: 10px">
+            <tr> 
+              <th>#define</th> <th>Enabled?</th> <th>Effects when enabled</th>
+            </tr>
+            <tr>
+              <td><code>FEATURE_ACL</code></td>
+              <td>@if-FEATURE_ACL-then@ Yes @else-not-FEATURE_ACL@ No @endif-FEATURE_ACL@</td>
+              <td>Allows the use of an ACL to control access to the proxy by IP address.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_CGI_EDIT_ACTIONS</code></td>
+              <td>@if-FEATURE_CGI_EDIT_ACTIONS-then@ Yes @else-not-FEATURE_CGI_EDIT_ACTIONS@ No @endif-FEATURE_CGI_EDIT_ACTIONS@</td>
+              <td>Allows the use of the web-based actions file 
+                 editor@if-FEATURE_CGI_EDIT_ACTIONS-then@, which is <a href="@default-cgi@edit-actions">here</a>@else-not-FEATURE_CGI_EDIT_ACTIONS@@endif-FEATURE_CGI_EDIT_ACTIONS@.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_COOKIE_JAR</code></td>
+              <td>@if-FEATURE_COOKIE_JAR-then@ Yes @else-not-FEATURE_COOKIE_JAR@ No @endif-FEATURE_COOKIE_JAR@</td>
+              <td>Allows the use of a "cookie jar" file to capture cookies.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_FAST_REDIRECTS</code></td>
+              <td>@if-FEATURE_FAST_REDIRECTS-then@ Yes @else-not-FEATURE_FAST_REDIRECTS@ No @endif-FEATURE_FAST_REDIRECTS@</td>
+              <td>Allows the +fast-redirects action, to bypass redirect and logging scripts.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_FORCE_LOAD</code></td>
+              <td>@if-FEATURE_FORCE_LOAD-then@ Yes @else-not-FEATURE_FORCE_LOAD@ No @endif-FEATURE_FORCE_LOAD@</td>
+              <td>Allows bypassing all filtering for a single page using the prefix "<code>@FORCE_PREFIX@</code>".</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_IMAGE_BLOCKING</code></td>
+              <td>@if-FEATURE_IMAGE_BLOCKING-then@ Yes @else-not-FEATURE_IMAGE_BLOCKING@ No @endif-FEATURE_IMAGE_BLOCKING@</td>
+              <td>Allows the +image ation, to send "blocked" images instead of HTML.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_IMAGE_DETECT_MSIE</code></td>
+              <td>@if-FEATURE_IMAGE_DETECT_MSIE-then@ Yes @else-not-FEATURE_IMAGE_DETECT_MSIE@ No @endif-FEATURE_IMAGE_DETECT_MSIE@</td>
+              <td>Enables automatic detection of image and HTML requests from
+               Microsoft Internet Explorer users, overriding the setting of 
+               +image in the actions file.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_KILL_POPUPS</code></td>
+              <td>@if-FEATURE_KILL_POPUPS-then@ Yes @else-not-FEATURE_KILL_POPUPS@ No @endif-FEATURE_KILL_POPUPS@</td>
+              <td>Allows the +no-popups action, to block JavaScript popups.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_NO_GIFS</code></td>
+              <td>@if-FEATURE_NO_GIFS-then@ Yes @else-not-FEATURE_NO_GIFS@ No @endif-FEATURE_NO_GIFS@</td>
+              <td>Use PNG instead of GIF for the built-in images.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_PTHREAD</code></td>
+              <td>@if-FEATURE_PTHREAD-then@ Yes @else-not-FEATURE_PTHREAD@ No @endif-FEATURE_PTHREAD@</td>
+              <td>Use POSIX threads rather than native threads</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_STATISTICS</code></td>
+              <td>@if-FEATURE_STATISTICS-then@ Yes @else-not-FEATURE_STATISTICS@ No @endif-FEATURE_STATISTICS@</td>
+              <td>Enables the statistics function.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_TOGGLE</code></td>
+              <td>@if-FEATURE_TOGGLE-then@ Yes @else-not-FEATURE_TOGGLE@ No @endif-FEATURE_TOGGLE@</td>
+              <td>Allow Privoxy to be "disabled" so it is just a normal non-blocking non-anonymizing proxy.</td>
+            </tr>
+            <tr>
+              <td><code>FEATURE_TRUST</code></td>
+              <td>@if-FEATURE_TRUST-then@ Yes @else-not-FEATURE_TRUST@ No @endif-FEATURE_TRUST@</td>
+              <td>Allows the use of trust files.</td>
+            </tr>
+            <tr>
+              <td><code>STATIC_PCRE</code></td>
+              <td>@if-STATIC_PCRE-then@ Yes @else-not-STATIC_PCRE@ No @endif-STATIC_PCRE@</td>
+              <td>Use the supplied statically-linked PCRE library.  This is set automatically
+               by <code>./configure</code> if you do not have the libpcre installed.</td>
+            </tr>
+            <tr>
+              <td><code>STATIC_PCRS</code></td>
+              <td>@if-STATIC_PCRS-then@ Yes @else-not-STATIC_PCRS@ No @endif-STATIC_PCRS@</td>
+              <td>Use the supplied statically-linked PCRS library.  This is set automatically
+               by <code>./configure</code> if you do not have the libpcrs installed.</td>
+            </tr>
+          </table>
+        </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+     <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>   
+  </table>
+
+</body>
+</html>
diff --git a/templates/show-status-file b/templates/show-status-file
new file mode 100644 (file)
index 0000000..a4abf62
--- /dev/null
@@ -0,0 +1,150 @@
+##########################################################
+#
+# Show-Status-CGI Output template for Privoxy.
+# (Variant for the show-file mode)
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+#  file-description:
+#    A descriptive name for the file being shown
+#  contents:
+#    The contents of the file being shown
+#  filepath
+#    The complete filename of the file being shown
+#
+#  
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    This is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy@@my-hostname@: Contents of @file-description@</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Contents of @file-description@ @filepath@</h2>
+        <pre>@contents@</pre>
+      </td>
+    </tr>
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+     <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>       
+  </table>
+
+</body>
+</html>
diff --git a/templates/show-url-info b/templates/show-url-info
new file mode 100644 (file)
index 0000000..fa2e124
--- /dev/null
@@ -0,0 +1,188 @@
+##########################################################
+#
+# Show-Url-Info-CGI Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#  url-given:
+#    The CGI was called with a url parameter. In that case, the
+#    following symbols are available:
+#    url:
+#      The given URL
+#    default:
+#      The system default for actions
+#    matches:
+#      The list of all matches in the actions file that this URL
+#      produced, along with the actions that were triggered by
+#      these matches
+#    final:
+#      The actions that are associated with the URL at the end of
+#      the matching process
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy@@my-hostname@ URL Info</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+<!-- @if-url-given-start -->
+    <tr>
+      <td class="box">
+<!-- @if-https-start -->
+        <h2>NOTE:</h2>
+        <p>This is a secure (https:) URL, so the part after the "/" is ignored.
+          This is a feature of the HTTPS protocol - the exact address of the
+          page you're visiting is hidden.  Privoxy can only detect the host
+          part of the URL.</p>
+        <p>&nbsp;</p>
+<!-- if-https-end@ -->
+        <h2>Matches for <a href="@url@">@url@</a>:</h2>
+        <p>@matches@</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>Final results:</h2>
+        <p><b>@final@</b></p>
+      </td>
+    </tr>
+<!-- if-url-given-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Look up the actions for a 
+<!-- @if-url-given-start -->new<!-- if-url-given-end@ -->
+          URL:</h2>
+        <form method="GET" action="@default-cgi@show-url-info">
+          <p>
+            <input type="text" name="url" size="80" value="@url@"> 
+            <input type="submit" value="Go">
+          </p>
+        </form>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+    
+
+     <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>   
+  </table>
+
+</body>
+</html>
diff --git a/templates/show-version b/templates/show-version
new file mode 100644 (file)
index 0000000..bc7890a
--- /dev/null
@@ -0,0 +1,163 @@
+##########################################################
+#
+# Show-Status-CGI Output template for Privoxy.
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+#  redirect-url:
+#    The URL to a script that will redirect to the Privoxy
+#    documentation for a given item  
+#  invocation:
+#    The command line with whitch Privoxy was invoked
+#  options:
+#    The options read from the configfile, linked to their
+#    explanations, plus warnings if parsing acl or forward
+#    statements produced errors.
+#  sourceversions:
+#    A HTML-formatted list of the individual source file cvs versions
+#  defines:
+#    A HTML-formatted list of all conditional #defines used when
+#    Privoxy was compiled
+#
+#  
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    This is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#  sourceversions
+#    The versions.
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>Privoxy@@my-hostname@: Detailed proxy version information</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Source code versions:</h2>
+        <p><i>(Note: This information is only relevant if you checked out Privoxy from CVS
+           and compiled it yourself.  If you downloaded a binary, .exe, RPM, or a .tgz file, 
+           then when you ask for support just mention the version number <b>@version@</b> 
+           and the type of download you got.)</i>
+        </p>
+        <pre>@sourceversions@</pre>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+
+     <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>       
+  </table>
+
+</body>
+</html>
diff --git a/templates/toggle b/templates/toggle
new file mode 100644 (file)
index 0000000..1150dd7
--- /dev/null
@@ -0,0 +1,185 @@
+##########################################################
+#
+# Toggle Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#  @if-enabled-display-then@ on @else-not-enabled-display@ off @endif-enabled-display@
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+  <title>@if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@ - Privoxy@@my-hostname@</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="title">
+
+#include mod-title
+
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="box">
+        <h2>Privoxy is @if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@</h2>
+          <p>When enabled, Privoxy performs its magic - blocking
+            adverts, filtering cookies, regex-filtering, etc.</p>
+          <p>When disabled, Privoxy behaves as a normal HTTP proxy,
+            and will not affect your web browsing.</p>
+          <p><a href="@default-cgi@toggle?set=@if-enabled-display-then@disable@else-not-enabled-display@enable@endif-enabled-display@">Click
+            here</a> to @if-enabled-display-then@disable@else-not-enabled-display@enable@endif-enabled-display@ Privoxy.</p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>Bookmarklets</h2>
+          <p>Here are some bookmarklets to allow you to easily access a
+            "mini" version of this page.  They are known to work with MS 
+            Internet Explorer, Netscape and Mozilla, but should work equally
+            well in other browsers which support JavaScript.  They are designed
+            to run directly from your bookmarks - <b>not</b> by clicking the
+            links below (although that will work for testing).
+          </p>
+          <p>To save them, right-click the link and choose
+            "Add to Favorites" (IE) or "Add Bookmark" (Netscape).  You
+            will get a warning that the bookmark "may not be safe" - just
+            click OK.  Then you can run the Bookmarklet directly from your
+            favourites/bookmarks.  For even faster access, you can put
+            them on the "Links" bar (IE) or the "Personal Toolbar"
+            (Netscape), and run them with a single click.
+          </p>
+
+          <ul>
+            <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y&amp;set=enabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Enable</a></li>
+            <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y&amp;set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Disable</a></li>
+            <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y&amp;set=toggle','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Toggle Privoxy</a>
+                  (Toggles between enabled and disabled)</li>
+            <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - View Status</a></li>
+          </ul>
+
+          <p>
+            <b>Credit:</b> The site which gave us the general idea for these
+            bookmarklets is <a href="http://www.bookmarklets.com/">www.bookmarklets.com</a>.
+            They have <a href="http://www.bookmarklets.com/about/">more information</a> about them.
+          </p>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+    
+
+     <tr>
+      <td>
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>   
+  </table>
+
+</body>
+</html>
+
diff --git a/templates/toggle-mini b/templates/toggle-mini
new file mode 100644 (file)
index 0000000..bf06fba
--- /dev/null
@@ -0,0 +1,90 @@
+##########################################################
+#
+# Toggle Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    this is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#  @if-enabled-display-then@ on @else-not-enabled-display@ off @endif-enabled-display@
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+  <title>@if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@ - Privoxy@@my-hostname@</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+  <p class="whiteframed">
+    <a href="@default-cgi@" target="_blank">Privoxy</a> is 
+    <b>@if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@</b>.
+    <br><a href="@default-cgi@toggle?mini=y&amp;set=@if-enabled-display-then@disable@else-not-enabled-display@enable@endif-enabled-display@"
+    >@if-enabled-display-then@[Disable]@else-not-enabled-display@[Enable]@endif-enabled-display@</a> |
+    <a href="javascript:window.close();">[Close]</a>
+  </p>
+</body>
+</html>
diff --git a/templates/untrusted b/templates/untrusted
new file mode 100644 (file)
index 0000000..d9c4529
--- /dev/null
@@ -0,0 +1,194 @@
+##########################################################
+#
+# "Untrusted" Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+# 
+# - Lines that start with a '#' character like this one
+#   are ignored
+#
+# - Each item in the below list of exported symbols will
+#   be replaced by dynamically generated text, if they
+#   are enclosed in '@'-characters. E.g. The string @version@
+#   will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+#   of the HTML template disappear if the condition <name>
+#   is not given. Simply enclose the block between the two
+#   strings @if-<name>start and if-<name>-end@. The strings
+#   should be placed in HTML comments (<!-- -->), so the
+#   html structure won't be messed when the magic happens.
+#   
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+#  my-ip-addr:
+#    The IP-address that the client used to reach this proxy
+#  my-hostname:
+#    The hostname associated with my-ip-addr
+#  admin-address:
+#    The email address of the pxoxy's administrator, as configured
+#    in the config file
+#  default-cgi:
+#    The URL for the "main menu" builtin CGI of this proxy
+#  menu:
+#    List of <li> elements linking to the other available CGIs
+#  version:
+#    The version number of the proxy software
+#  code-status:
+#    The development status of the proxy software: "alpha", "beta",
+#    or "stable".
+#  homepage:
+#    The URL of the SourceForge ijbswa project, who maintains this
+#    software.
+#
+#  hostport:
+#    The host and port part of the request that lead to this problem
+#  path:
+#    The path part of the request that lead to this problem
+#  referrer:
+#    The referrer of the request that lead to this problem
+#  trusted-referrers:
+#    An HTML-formatted list of referrers that are marked as trusted in
+#    the trustfile
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+#  unstable:
+#    This is an alpha or beta release of the proxy software
+#  have-adminaddr-info:
+#    An e-mail address for the local Privoxy adminstrator has
+#    been specified and is available through the "admin-address"
+#    symbol
+#  have-proxy-info:
+#    A URL for online documentation about this proxy has been
+#    specified and is available through the "proxy-info-url"
+#    symbol
+#  have-help-info:
+#    If either have-proxy-info is true or have-adminaddr-info is
+#    true, have-help-info is true.  Used to conditionally include
+#    a grey box for any and all help info.
+#  force-support:
+#    Privoxy has been compiled with support for forced loading
+#    of blocked content. In that case, the symbol "force-prefix" is
+#    avaiable, which translates to the FORCE_PREFIX  
+#  have-trust-info:
+#    There were URLs with info on the trust policy defined in the config
+#    file. In this case the list of URLs is available through the
+#    "trust-info" symbol.
+#
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html>
+
+<head>
+  <title>Untrusted request (Privoxy@@my-hostname@)</title>
+  <meta http-equiv="Content-Style-Type" content="text/css">
+  <meta http-equiv="Content-Script-Type" content="text/javascript">
+  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <meta name="robots" content="noindex,nofollow">
+  <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+  <table cellpadding="20" cellspacing="10" border="0" width="100%">
+    <tr>
+      <td class="status">
+        UNTRUSTED
+      </td>
+      <td class="title" style="width: 100%">
+#include mod-title
+      </td>
+    </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+    <tr>
+      <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+      </td>
+    </tr>
+<!-- if-unstable-end@ -->
+
+    <tr>
+      <td class="warning" colspan="2">
+        <h2>Request for untrusted URL</h2>
+        <p>Your request for <b>@protocol@@hostport@@path@</b> was blocked,
+          because neither the request URL itself, nor its referrer
+          (<a href="@referrer@">@referrer@</a>) were trusted.
+        </p>
+<!-- @if-force-support-start -->
+        <p>(You can <a href="@protocol@@hostport@@force-prefix@@path@">go there anyway</a>.)</p>
+<!-- if-force-support-end@ -->
+      </td>
+    </tr>
+
+    <tr>
+      <td class="box" colspan="2">
+        <h2>The following referrers are trusted:</h2>
+        <ul>
+          @trusted-referrers@
+        </ul>
+      </td>
+    </tr>
+
+<!-- @if-have-trust-info-start -->
+    <tr>
+      <td class="box" colspan="2">
+        <h2>More information on the trust policy:</h2>
+        <p>You can learn more about what this means and what you may be able to do about it by
+          reading the following documents:
+        </p>
+        <ol>
+            @trust-info@
+        </ol>
+      </td>
+    </tr>
+<!-- if-have-trust-info-end@ -->
+
+    <tr>
+      <td class="box" colspan="2">
+        <h2>More Privoxy:</h2>
+        <ul>@menu@</ul>
+      </td>
+    </tr>
+
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+      </td>
+    </tr>
+
+<!-- @if-have-help-info-start -->
+    <tr>
+      <td class="info" colspan="2">
+
+#include mod-local-help
+
+      </td>
+    </tr>
+<!-- if-have-help-info-end@ -->
+        
+    <tr>
+      <td colspan="2">
+        <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+      </td>
+    </tr>
+
+  </table>
+
+</body>
+</html>
diff --git a/testdrive.status b/testdrive.status
new file mode 100644 (file)
index 0000000..3ab18af
--- /dev/null
@@ -0,0 +1,30 @@
+CHUNK:                 ASSIGNED TO:                            RUN1:   RUN2:
+-----------------------------------------------------------------------------
+testdrive-intl-aa      
+testdrive-intl-ab
+testdrive-intl-ac      Clifford Caoile <piyokun@email.com>
+testdrive-intl-ad
+testdrive-intl-ae      bokeh <bokeh@lycos.co.uk>               1.2
+testdrive-intl-af
+testdrive-intl-ag
+testdrive-intl-ah
+testdrive-intl-ai      swa                                     1.2
+testdrive-intl-aj      swa                                     1.2
+testdrive-intl-ak      swa                                     1.2
+testdrive-unstable
+testdrive-us-aa                maynard.o@discourse.mentabolism.org     1.2
+testdrive-us-ab                Eugene Wood <gene_wood@yahoo.com>
+testdrive-us-ac
+testdrive-us-ad                Hal                                     1.2
+testdrive-us-ae                Hal                                     1.2
+testdrive-us-af                Hal                                     1.2
+testdrive-us-ag                Markus Weidler <markus.weidler@gmx.net> 1.2
+testdrive-us-ah                Adam Jacob Muller <adam@AdamJacobMuller.com>
+testdrive-us-ai
+testdrive-us-aj
+testdrive-us-ak
+testdrive-us-al
+testdrive-us-am
+testdrive-us-an
+testdrive-us-ao
+testdrive-us-ap
diff --git a/trust b/trust
index d1a9fe2..8a40dcc 100644 (file)
--- a/trust
+++ b/trust
@@ -1,8 +1,47 @@
-#  Illustrative Trustfile for the Internet Junkbuster
+######################################################################
+# 
+#  File        :  $Source: /cvsroot/ijbswa/current/basic.action,v $
+# 
+#  $Id: basic.action,v 1.3 2002/03/26 22:29:54 swa Exp $
 #
-# Copyright 1997-8 Junkbusters Corp.  For distribution, modification and use
-# under the GNU General Public License. These files come with NO WARRANTY.
-# See http://www.junkbusters.com/ht/en/gpl.html or README file for details.
+#  Purpose     :  Trustfiles are an experimental feature used for
+#                 building "whitelists" (versus the usual "blacklists"
+#                 in a blockfile).
+# 
+#  Copyright   :  Written by and Copyright
+#                 Privoxy team. http://www.privoxy.org/
+#
+#                 Based on the Internet Junkbuster originally written
+#                 by and Copyright (C) 1997 Anonymous Coders and
+#                 Junkbusters Corporation.  http://www.junkbusters.com
+#
+# We value your feedback. However, to provide you with the best support,
+# please note:
+#  
+#  * Use the support forum to get help:
+#    http://sourceforge.net/tracker/?group_id=11118&atid=211118
+#  * Submit bugs only thru our bug forum:
+#    http://sourceforge.net/tracker/?group_id=11118&atid=111118 
+#    Make sure that the bug has not already been submitted. Please try
+#    to verify that it is a Junkbuster bug, and not a browser or site
+#    bug first. If you are using your own custom configuration, please
+#    try the stock configs to see if the problem is a configuration
+#    related bug. And if not using the latest development snapshot,
+#    please try the latest one. Or even better, CVS sources.
+#  * Submit feature requests only thru our feature request forum:
+#    http://sourceforge.net/tracker/?atid=361118&group_id=11118&func=browse
+#      
+# For any other issues, feel free to use the mailing lists:
+# http://sourceforge.net/mail/?group_id=11118
+#    
+# Anyone interested in actively participating in development and related
+# discussions can join the appropriate mailing list here:
+# http://sourceforge.net/mail/?group_id=11118. Archives are available
+# here too.
+# 
+######################################################################
+#
+#  Illustrative Trustfile for Privoxy
 
 # For this file to have any effect, the line beginning "trustfile" must
 # be commented in, with the name of this file following the word "trustfile"
diff --git a/urlmatch.c b/urlmatch.c
new file mode 100644 (file)
index 0000000..1b2aee8
--- /dev/null
@@ -0,0 +1,809 @@
+const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.9 2002/04/04 00:36:36 gliptak Exp $";
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/urlmatch.c,v $
+ *
+ * Purpose     :  Declares functions to match URLs against URL
+ *                patterns.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: urlmatch.c,v $
+ *    Revision 1.9  2002/04/04 00:36:36  gliptak
+ *    always use pcre for matching
+ *
+ *    Revision 1.8  2002/04/03 23:32:47  jongfoster
+ *    Fixing memory leak on error
+ *
+ *    Revision 1.7  2002/03/26 22:29:55  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.6  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.5  2002/03/13 00:27:05  jongfoster
+ *    Killing warnings
+ *
+ *    Revision 1.4  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.3  2002/03/03 14:51:11  oes
+ *    Fixed CLF logging: Added ocmd member for client's request to struct http_request
+ *
+ *    Revision 1.2  2002/01/21 00:14:09  jongfoster
+ *    Correcting comment style
+ *    Fixing an uninitialized memory bug in create_url_spec()
+ *
+ *    Revision 1.1  2002/01/17 20:53:46  jongfoster
+ *    Moving all our URL and URL pattern parsing code to the same file - it
+ *    was scattered around in filters.c, loaders.c and parsers.c.
+ *
+ *    Providing a single, simple url_match(pattern,url) function - rather than
+ *    the 3-line match routine which was repeated all over the place.
+ *
+ *    Renaming free_url to free_url_spec, since it frees a struct url_spec.
+ *
+ *    Providing parse_http_url() so that URLs can be parsed without faking a
+ *    HTTP request line for parse_http_request() or repeating the parsing
+ *    code (both of which were techniques that were actually in use).
+ *
+ *    Standardizing that struct http_request is used to represent a URL, and
+ *    struct url_spec is used to represent a URL pattern.  (Before, URLs were
+ *    represented as seperate variables and a partially-filled-in url_spec).
+ *
+ *
+ *********************************************************************/
+\f
+
+#include "config.h"
+
+#ifndef _WIN32
+#include <stdio.h>
+#include <sys/types.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <assert.h>
+#include <string.h>
+
+#if !defined(_WIN32) && !defined(__OS2__)
+#include <unistd.h>
+#endif
+
+#include "project.h"
+#include "urlmatch.h"
+#include "ssplit.h"
+#include "miscutil.h"
+#include "errlog.h"
+
+const char urlmatch_h_rcs[] = URLMATCH_H_VERSION;
+
+
+/*********************************************************************
+ *
+ * Function    :  free_http_request
+ *
+ * Description :  Freez a http_request structure
+ *
+ * Parameters  :
+ *          1  :  http = points to a http_request structure to free
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void free_http_request(struct http_request *http)
+{
+   assert(http);
+
+   freez(http->cmd);
+   freez(http->ocmd);
+   freez(http->gpc);
+   freez(http->host);
+   freez(http->url);
+   freez(http->hostport);
+   freez(http->path);
+   freez(http->ver);
+   freez(http->host_ip_addr_str);
+   freez(http->dbuffer);
+   freez(http->dvec);
+   http->dcount = 0;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  parse_http_url
+ *
+ * Description :  Parse out the host and port from the URL.  Find the
+ *                hostname & path, port (if ':'), and/or password (if '@')
+ *
+ * Parameters  :
+ *          1  :  url = URL (or is it URI?) to break down
+ *          2  :  http = pointer to the http structure to hold elements.
+ *                       Will be zeroed before use.  Note that this
+ *                       function sets the http->gpc and http->ver
+ *                       members to NULL.
+ *          3  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out of memory
+ *                JB_ERR_CGI_PARAMS on malformed command/URL
+ *                                  or >100 domains deep.
+ *
+ *********************************************************************/
+jb_err parse_http_url(const char * url,
+                      struct http_request *http,
+                      struct client_state *csp)
+{
+   /*
+    * Zero out the results structure
+    */
+   memset(http, '\0', sizeof(*http));
+
+
+   /*
+    * Save our initial URL
+    */
+   http->url = strdup(url);
+   if (http->url == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+
+   /*
+    * Split URL into protocol,hostport,path.
+    */
+   {
+      char *buf;
+      char *url_noproto;
+      char *url_path;
+
+      buf = strdup(url);
+      if (buf == NULL)
+      {
+         return JB_ERR_MEMORY;
+      }
+
+      /* Find the start of the URL in our scratch space */
+      url_noproto = buf;
+      if (strncmpic(url_noproto, "http://",  7) == 0)
+      {
+         url_noproto += 7;
+         http->ssl = 0;
+      }
+      else if (strncmpic(url_noproto, "https://", 8) == 0)
+      {
+         url_noproto += 8;
+         http->ssl = 1;
+      }
+      else
+      {
+         http->ssl = 0;
+      }
+
+      url_path = strchr(url_noproto, '/');
+      if (url_path != NULL)
+      {
+         /*
+          * Got a path.
+          *
+          * NOTE: The following line ignores the path for HTTPS URLS.
+          * This means that you get consistent behaviour if you type a
+          * https URL in and it's parsed by the function.  (When the
+          * URL is actually retrieved, SSL hides the path part).
+          */
+         http->path = strdup(http->ssl ? "/" : url_path);
+         *url_path = '\0';
+         http->hostport = strdup(url_noproto);
+      }
+      else
+      {
+         /*
+          * Repair broken HTTP requests that don't contain a path,
+          * or CONNECT requests
+          */
+         http->path = strdup("/");
+         http->hostport = strdup(url_noproto);
+      }
+
+      free(buf);
+
+      if ( (http->path == NULL)
+        || (http->hostport == NULL))
+      {
+         free(buf);
+         free_http_request(http);
+         return JB_ERR_MEMORY;
+      }
+   }
+
+
+   /*
+    * Split hostport into user/password (ignored), host, port.
+    */
+   {
+      char *buf;
+      char *host;
+      char *port;
+
+      buf = strdup(http->hostport);
+      if (buf == NULL)
+      {
+         free_http_request(http);
+         return JB_ERR_MEMORY;
+      }
+
+      /* check if url contains username and/or password */
+      host = strchr(buf, '@');
+      if (host != NULL)
+      {
+         /* Contains username/password, skip it and the @ sign. */
+         host++;
+      }
+      else
+      {
+         /* No username or password. */
+         host = buf;
+      }
+
+      /* check if url contains port */
+      port = strchr(host, ':');
+      if (port != NULL)
+      {
+         /* Contains port */
+         /* Terminate hostname and point to start of port string */
+         *port++ = '\0';
+         http->port = atoi(port);
+      }
+      else
+      {
+         /* No port specified. */
+         http->port = (http->ssl ? 143 : 80);
+      }
+
+      http->host = strdup(host);
+
+      free(buf);
+
+      if (http->host == NULL)
+      {
+         free_http_request(http);
+         return JB_ERR_MEMORY;
+      }
+   }
+
+
+   /*
+    * Split domain name so we can compare it against wildcards
+    */
+   {
+      char *vec[BUFFER_SIZE];
+      size_t size;
+      char *p;
+
+      http->dbuffer = strdup(http->host);
+      if (NULL == http->dbuffer)
+      {
+         free_http_request(http);
+         return JB_ERR_MEMORY;
+      }
+
+      /* map to lower case */
+      for (p = http->dbuffer; *p ; p++)
+      {
+         *p = tolower((int)(unsigned char)*p);
+      }
+
+      /* split the domain name into components */
+      http->dcount = ssplit(http->dbuffer, ".", vec, SZ(vec), 1, 1);
+
+      if (http->dcount <= 0)
+      {
+         /*
+          * Error: More than SZ(vec) components in domain
+          *    or: no components in domain
+          */
+         free_http_request(http);
+         return JB_ERR_PARSE;
+      }
+
+      /* save a copy of the pointers in dvec */
+      size = http->dcount * sizeof(*http->dvec);
+
+      http->dvec = (char **)malloc(size);
+      if (NULL == http->dvec)
+      {
+         free_http_request(http);
+         return JB_ERR_MEMORY;
+      }
+
+      memcpy(http->dvec, vec, size);
+   }
+
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  parse_http_request
+ *
+ * Description :  Parse out the host and port from the URL.  Find the
+ *                hostname & path, port (if ':'), and/or password (if '@')
+ *
+ * Parameters  :
+ *          1  :  req = HTTP request line to break down
+ *          2  :  http = pointer to the http structure to hold elements
+ *          3  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out of memory
+ *                JB_ERR_CGI_PARAMS on malformed command/URL
+ *                                  or >100 domains deep.
+ *
+ *********************************************************************/
+jb_err parse_http_request(const char *req,
+                          struct http_request *http,
+                          struct client_state *csp)
+{
+   char *buf;
+   char *v[10];
+   int n;
+   jb_err err;
+   int is_connect = 0;
+
+   memset(http, '\0', sizeof(*http));
+
+   buf = strdup(req);
+   if (buf == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   n = ssplit(buf, " \r\n", v, SZ(v), 1, 1);
+   if (n != 3)
+   {
+      free(buf);
+      return JB_ERR_PARSE;
+   }
+
+   /* this could be a CONNECT request */
+   if (strcmpic(v[0], "connect") == 0)
+   {
+      /* Secure */
+      is_connect = 1;
+   }
+   /* or it could be any other basic HTTP request type */
+   else if ((0 == strcmpic(v[0], "get"))
+         || (0 == strcmpic(v[0], "head"))
+         || (0 == strcmpic(v[0], "post"))
+         || (0 == strcmpic(v[0], "put"))
+         || (0 == strcmpic(v[0], "delete"))
+         /* or a webDAV extension (RFC2518) */
+         || (0 == strcmpic(v[0], "propfind"))
+         || (0 == strcmpic(v[0], "proppatch"))
+         || (0 == strcmpic(v[0], "move"))
+         || (0 == strcmpic(v[0], "copy"))
+         || (0 == strcmpic(v[0], "mkcol"))
+         || (0 == strcmpic(v[0], "lock"))
+         || (0 == strcmpic(v[0], "unlock"))
+         )
+   {
+      /* Normal */
+      is_connect = 0;
+   }
+   else
+   {
+      /* Unknown HTTP method */
+      free(buf);
+      return JB_ERR_PARSE;
+   }
+
+   err = parse_http_url(v[1], http, csp);
+   if (err)
+   {
+      free(buf);
+      return err;
+   }
+
+   /*
+    * Copy the details into the structure
+    */
+   http->ssl = is_connect;
+   http->cmd = strdup(req);
+   http->gpc = strdup(v[0]);
+   http->ver = strdup(v[2]);
+
+   if ( (http->cmd == NULL)
+     || (http->gpc == NULL)
+     || (http->ver == NULL) )
+   {
+      free(buf);
+      free_http_request(http);
+      return JB_ERR_MEMORY;
+   }
+
+   return JB_ERR_OK;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  simple_domaincmp
+ *
+ * Description :  Domain-wise Compare fqdn's.  The comparison is
+ *                both left- and right-anchored.  The individual
+ *                domain names are compared with simplematch().
+ *                This is only used by domain_match.
+ *
+ * Parameters  :
+ *          1  :  pv = array of patterns to compare
+ *          2  :  fv = array of domain components to compare
+ *          3  :  len = length of the arrays (both arrays are the
+ *                      same length - if they weren't, it couldn't
+ *                      possibly be a match).
+ *
+ * Returns     :  0 => domains are equivalent, else no match.
+ *
+ *********************************************************************/
+static int simple_domaincmp(char **pv, char **fv, int len)
+{
+   int n;
+
+   for (n = 0; n < len; n++)
+   {
+      if (simplematch(pv[n], fv[n]))
+      {
+         return 1;
+      }
+   }
+
+   return 0;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  domain_match
+ *
+ * Description :  Domain-wise Compare fqdn's. Governed by the bimap in
+ *                pattern->unachored, the comparison is un-, left-,
+ *                right-anchored, or both.
+ *                The individual domain names are compared with
+ *                simplematch().
+ *
+ * Parameters  :
+ *          1  :  pattern = a domain that may contain a '*' as a wildcard.
+ *          2  :  fqdn = domain name against which the patterns are compared.
+ *
+ * Returns     :  0 => domains are equivalent, else no match.
+ *
+ *********************************************************************/
+static int domain_match(const struct url_spec *pattern, const struct http_request *fqdn)
+{
+   char **pv, **fv;  /* vectors  */
+   int    plen, flen;
+   int unanchored = pattern->unanchored & (ANCHOR_RIGHT | ANCHOR_LEFT);
+
+   plen = pattern->dcount;
+   flen = fqdn->dcount;
+
+   if (flen < plen)
+   {
+      /* fqdn is too short to match this pattern */
+      return 1;
+   }
+
+   pv   = pattern->dvec;
+   fv   = fqdn->dvec;
+
+   if (unanchored == ANCHOR_LEFT)
+   {
+      /*
+       * Right anchored.
+       *
+       * Convert this into a fully anchored pattern with
+       * the fqdn and pattern the same length
+       */
+      fv += (flen - plen); /* flen - plen >= 0 due to check above */
+      return simple_domaincmp(pv, fv, plen);
+   }
+   else if (unanchored == 0)
+   {
+      /* Fully anchored, check length */
+      if (flen != plen)
+      {
+         return 1;
+      }
+      return simple_domaincmp(pv, fv, plen);
+   }
+   else if (unanchored == ANCHOR_RIGHT)
+   {
+      /* Left anchored, ignore all extra in fqdn */
+      return simple_domaincmp(pv, fv, plen);
+   }
+   else
+   {
+      /* Unanchored */
+      int n;
+      int maxn = flen - plen;
+      for (n = 0; n <= maxn; n++)
+      {
+         if (!simple_domaincmp(pv, fv, plen))
+         {
+            return 0;
+         }
+         /*
+          * Doesn't match from start of fqdn
+          * Try skipping first part of fqdn
+          */
+         fv++;
+      }
+      return 1;
+   }
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  create_url_spec
+ *
+ * Description :  Creates a "url_spec" structure from a string.
+ *                When finished, free with unload_url().
+ *
+ * Parameters  :
+ *          1  :  url = Target url_spec to be filled in.  Will be
+ *                      zeroed before use.
+ *          2  :  buf = Source pattern, null terminated.  NOTE: The
+ *                      contents of this buffer are destroyed by this
+ *                      function.  If this function succeeds, the
+ *                      buffer is copied to url->spec.  If this
+ *                      function fails, the contents of the buffer
+ *                      are lost forever.
+ *
+ * Returns     :  JB_ERR_OK - Success
+ *                JB_ERR_MEMORY - Out of memory
+ *                JB_ERR_PARSE - Cannot parse regex (Detailed message
+ *                               written to system log)
+ *
+ *********************************************************************/
+jb_err create_url_spec(struct url_spec * url, const char * buf)
+{
+   char *p;
+
+   assert(url);
+   assert(buf);
+
+   /* Zero memory */
+   memset(url, '\0', sizeof(*url));
+
+   /* save a copy of the orignal specification */
+   if ((url->spec = strdup(buf)) == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   if ((p = strchr(buf, '/')) != NULL)
+   {
+      if (NULL == (url->path = strdup(p)))
+      {
+         freez(url->spec);
+         return JB_ERR_MEMORY;
+      }
+      url->pathlen = strlen(url->path);
+      *p = '\0';
+   }
+   else
+   {
+      url->path    = NULL;
+      url->pathlen = 0;
+   }
+   if (url->path)
+   {
+      int errcode;
+      char rebuf[BUFFER_SIZE];
+
+      if (NULL == (url->preg = zalloc(sizeof(*url->preg))))
+      {
+         freez(url->spec);
+         freez(url->path);
+         return JB_ERR_MEMORY;
+      }
+
+      sprintf(rebuf, "^(%s)", url->path);
+
+      errcode = regcomp(url->preg, rebuf,
+            (REG_EXTENDED|REG_NOSUB|REG_ICASE));
+      if (errcode)
+      {
+         size_t errlen = regerror(errcode,
+            url->preg, rebuf, sizeof(rebuf));
+
+         if (errlen > (sizeof(rebuf) - (size_t)1))
+         {
+            errlen = sizeof(rebuf) - (size_t)1;
+         }
+         rebuf[errlen] = '\0';
+
+         log_error(LOG_LEVEL_ERROR, "error compiling %s: %s",
+            url->spec, rebuf);
+
+         freez(url->spec);
+         freez(url->path);
+         regfree(url->preg);
+         freez(url->preg);
+
+         return JB_ERR_PARSE;
+      }
+   }
+   if ((p = strchr(buf, ':')) == NULL)
+   {
+      url->port = 0;
+   }
+   else
+   {
+      *p++ = '\0';
+      url->port = atoi(p);
+   }
+
+   if (buf[0] != '\0')
+   {
+      char *v[150];
+      size_t size;
+
+      /* Parse domain part */
+      if (buf[strlen(buf) - 1] == '.')
+      {
+         url->unanchored |= ANCHOR_RIGHT;
+      }
+      if (buf[0] == '.')
+      {
+         url->unanchored |= ANCHOR_LEFT;
+      }
+
+      /* split domain into components */
+
+      url->dbuffer = strdup(buf);
+      if (NULL == url->dbuffer)
+      {
+         freez(url->spec);
+         freez(url->path);
+         regfree(url->preg);
+         freez(url->preg);
+         return JB_ERR_MEMORY;
+      }
+
+      /* map to lower case */
+      for (p = url->dbuffer; *p ; p++)
+      {
+         *p = tolower((int)(unsigned char)*p);
+      }
+
+      /* split the domain name into components */
+      url->dcount = ssplit(url->dbuffer, ".", v, SZ(v), 1, 1);
+
+      if (url->dcount < 0)
+      {
+         freez(url->spec);
+         freez(url->path);
+         regfree(url->preg);
+         freez(url->preg);
+         freez(url->dbuffer);
+         url->dcount = 0;
+         return JB_ERR_MEMORY;
+      }
+      else if (url->dcount != 0)
+      {
+
+         /* save a copy of the pointers in dvec */
+         size = url->dcount * sizeof(*url->dvec);
+
+         url->dvec = (char **)malloc(size);
+         if (NULL == url->dvec)
+         {
+            freez(url->spec);
+            freez(url->path);
+            regfree(url->preg);
+            freez(url->preg);
+            freez(url->dbuffer);
+            url->dcount = 0;
+            return JB_ERR_MEMORY;
+         }
+
+         memcpy(url->dvec, v, size);
+      }
+   }
+
+   return JB_ERR_OK;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_url_spec
+ *
+ * Description :  Called from the "unloaders".  Freez the url
+ *                structure elements.
+ *
+ * Parameters  :
+ *          1  :  url = pointer to a url_spec structure.
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+void free_url_spec(struct url_spec *url)
+{
+   if (url == NULL) return;
+
+   freez(url->spec);
+   freez(url->dbuffer);
+   freez(url->dvec);
+   freez(url->path);
+   if (url->preg)
+   {
+      regfree(url->preg);
+      freez(url->preg);
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  url_match
+ *
+ * Description :  Compare a URL against a URL pattern.
+ *
+ * Parameters  :
+ *          1  :  pattern = a URL pattern
+ *          2  :  url = URL to match
+ *
+ * Returns     :  0 iff the URL matches the pattern, else nonzero.
+ *
+ *********************************************************************/
+int url_match(const struct url_spec *pattern,
+              const struct http_request *url)
+{
+   return ((pattern->port == 0) || (pattern->port == url->port))
+       && ((pattern->dbuffer == NULL) || (domain_match(pattern, url) == 0))
+       && ((pattern->path == NULL) ||
+            (regexec(pattern->preg, url->path, 0, NULL, 0) == 0)
+      );
+}
+
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/urlmatch.h b/urlmatch.h
new file mode 100644 (file)
index 0000000..09fa639
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef URLMATCH_H_INCLUDED
+#define URLMATCH_H_INCLUDED
+#define URLMATCH_H_VERSION "$Id: urlmatch.h,v 1.2 2002/03/24 13:25:43 swa Exp $"
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/urlmatch.h,v $
+ *
+ * Purpose     :  Declares functions to match URLs against URL
+ *                patterns.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: urlmatch.h,v $
+ *    Revision 1.2  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.1  2002/01/17 20:53:46  jongfoster
+ *    Moving all our URL and URL pattern parsing code to the same file - it
+ *    was scattered around in filters.c, loaders.c and parsers.c.
+ *
+ *    Providing a single, simple url_match(pattern,url) function - rather than
+ *    the 3-line match routine which was repeated all over the place.
+ *
+ *    Renaming free_url to free_url_spec, since it frees a struct url_spec.
+ *
+ *    Providing parse_http_url() so that URLs can be parsed without faking a
+ *    HTTP request line for parse_http_request() or repeating the parsing
+ *    code (both of which were techniques that were actually in use).
+ *
+ *    Standardizing that struct http_request is used to represent a URL, and
+ *    struct url_spec is used to represent a URL pattern.  (Before, URLs were
+ *    represented as seperate variables and a partially-filled-in url_spec).
+ *
+ *
+ *********************************************************************/
+\f
+
+#include "project.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void free_http_request(struct http_request *http);
+extern jb_err parse_http_request(const char *req,
+                                 struct http_request *http,
+                                 struct client_state *csp);
+extern jb_err parse_http_url(const char * url,
+                             struct http_request *http,
+                             struct client_state *csp);
+
+extern int url_match(const struct url_spec *pattern,
+                     const struct http_request *url);
+
+extern jb_err create_url_spec(struct url_spec * url, const char * buf);
+extern void free_url_spec(struct url_spec *url);
+
+
+/* Revision control strings from this header and associated .c file */
+extern const char urlmatch_rcs[];
+extern const char urlmatch_h_rcs[];
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ndef URLMATCH_H_INCLUDED */
+
+/*
+  Local Variables:
+  tab-width: 3
+  end:
+*/
diff --git a/user.action b/user.action
new file mode 100644 (file)
index 0000000..f35a446
--- /dev/null
@@ -0,0 +1,32 @@
+######################################################################
+# 
+#  File        :  $Source:  $
+# 
+#  $Id:  $
+#
+#  Purpose     :  User-maintained actions file, see
+#                 http://www.privoxy.org/faq/questions.html#CONFIGFILES
+#
+######################################################################
+
+# This is the place to add your personal exceptions and additions to
+# the general policy. (Here they will be safe from updates to the
+# "main" actions file, default.action.
+
+# Say you've seen an ad on your favourite page on example.com that
+# you want to get rid of. You have right-clicked the image, selected
+# "copy image location" and pasted the URL below, into a { +block }
+# section. Note that { +handle-as-image } need not be specified,
+# since all URLs ending in .gif will be tagged as images by the
+# general rules in default.action anyway:
+# 
+{ +block }
+www.example.com/nasty-ads/sponsor.gif
+
+# Say the site where you do your homebanking needs to open
+# popup windows, but you have chosen to kill popups by
+# default. This will allow it for your-example-bank.com:
+#
+{ -filter{popups} -kill-popups }
+.your-example-bank.com
+
diff --git a/vc_config_pthreads.h b/vc_config_pthreads.h
new file mode 100644 (file)
index 0000000..c4a1137
--- /dev/null
@@ -0,0 +1,479 @@
+#ifndef CONFIG_H_INCLUDED
+#define CONFIG_H_INCLUDED
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/vc_config_pthreads.h,v $
+ *
+ * Purpose     :  This file should be the first thing included in every
+ *                .c file.  (Before even system headers).  It contains 
+ *                #define statements for various features.  It was
+ *                introduced because the compile command line started
+ *                getting ludicrously long with feature defines.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: vc_config_pthreads.h,v $
+ *    Revision 1.2  2002/04/26 18:26:09  jongfoster
+ *    Bumping version numbers
+ *
+ *    Revision 1.1  2002/04/06 20:38:01  jongfoster
+ *    Renaming VC++ versions of config.h
+ *
+ *    Revision 1.20  2002/04/03 22:28:03  gliptak
+ *    Removed references to gnu_regex
+ *
+ *    Revision 1.19  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.18  2002/03/24 17:08:12  jongfoster
+ *    Version number bump
+ *
+ *    Revision 1.17  2002/03/24 13:33:26  swa
+ *    name change related issues
+ *
+ *    Revision 1.16  2002/03/16 14:27:22  jongfoster
+ *    Ignoring a very common warning.
+ *
+ *    Revision 1.15  2002/03/13 00:28:32  jongfoster
+ *    Hiding all the warnings generated by #include<windows.h>
+ *
+ *    Revision 1.14  2001/11/30 21:35:54  jongfoster
+ *    Bumping version number to 2.9.10
+ *
+ *    Revision 1.13  2001/10/23 21:24:09  jongfoster
+ *    Support for FEATURE_CGI_EDIT_ACTIONS
+ *
+ *    Revision 1.12  2001/10/07 15:33:14  oes
+ *    Removed FEATURE_DENY_GZIP
+ *    Bumped up version number
+ *
+ *    Revision 1.11  2001/09/16 16:59:34  jongfoster
+ *    Bugfix - couldn't build resources with previous version.
+ *
+ *    Revision 1.10  2001/09/16 16:19:02  jongfoster
+ *    New version based on latest configure.in and acconfig.h
+ *
+ *    Revision 1.9  2001/07/30 22:16:07  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.8  2001/07/25 19:16:27  oes
+ *    Bumping version number to 2.9.8
+ *
+ *    Revision 1.7  2001/07/21 18:00:07  jongfoster
+ *    Bumping version number to 2.9.7
+ *
+ *    Revision 1.6  2001/07/15 20:08:40  jongfoster
+ *    New build files for VC++ which provide the option of POSIX
+ *    or Win32 threads.
+ *
+ *    Revision 1.5  2001/07/15 18:00:46  jongfoster
+ *    Renaming STATIC to STATIC_PCRE.
+ *    Replacing this file with one built by "configure" from
+ *    "config.h.in", for consistency.
+ *
+ *    Revision 1.6  2001/07/15 17:54:29  jongfoster
+ *    Renaming #define STATIC to STATIC_PCRE
+ *    Adding new #define FEATURE_PTHREAD that will be used to enable
+ *    POSIX threads support.
+ *
+ *    Revision 1.5  2001/07/13 13:48:37  oes
+ *     - (Fix:) Copied CODE_STATUS #define from config.h.in
+ *     - split REGEX #define into REGEX_GNU and REGEX_PCRE
+ *       and removed PCRE.
+ *       (REGEX = REGEX_GNU || REGEX_PCRE per project.h)
+ *     - Moved STATIC (for pcre) here from Makefile.in
+ *     - Introduced STATIC_PCRS #define to allow for dynaimc linking with
+ *       libpcrs
+ *     - Removed PCRS #define, since pcrs is now needed for CGI anyway
+ *
+ *    Revision 1.4  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.3  2001/05/26 01:26:34  jongfoster
+ *    New #define, WIN_GUI_EDIT, enables the (embryonic) Win32 GUI editor.
+ *    This #define cannot be set from ./configure - there's no point, it
+ *    doesn't work yet.  See feature request # 425722
+ *
+ *    Revision 1.2  2001/05/22 17:43:35  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Many minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:45  oes
+ *    Initial import of version 2.9.3 source tree
+ *
+ *
+ *********************************************************************/
+\f
+
+/*
+ * Version number - Major (X._._)
+ */
+#define VERSION_MAJOR 2
+
+/*
+ * Version number - Minor (_.X._)
+ */
+#define VERSION_MINOR 9
+
+/*
+ * Version number - Point (_._.X)
+ */
+#define VERSION_POINT 15
+
+/*
+ * Version number, as a string
+ */
+#define VERSION "2.9.15"
+
+/*
+ * Status of the code: alpha, beta or stable
+ */
+#define CODE_STATUS "beta"
+
+/*
+ * Regular expression matching for URLs.  (Highly recommended).
+ * If neither of these are defined then you can ony use prefix matching.
+ * Don't bother to change this here! Use configure instead.
+ */
+#define REGEX_PCRE 1
+
+/* 
+ * Should pcre be statically built in instead of linkling with libpcre?
+ * (This is determined by configure depending on the availiability of
+ * libpcre and user preferences). The name is ugly, but pcre needs it.
+ * Don't bother to change this here! Use configure instead.
+ */
+#define STATIC_PCRE 1
+
+/* 
+ * Should pcrs be statically built in instead of linkling with libpcrs?
+ * (This is determined by configure depending on the availiability of
+ * libpcrs and user preferences).
+ * Don't bother to change this here! Use configure instead.
+ */
+#define STATIC_PCRS 1
+
+/*
+ * Allows the use of an ACL to control access to the proxy by IP address.
+ */
+#define FEATURE_ACL 1
+
+/*
+ * Enables the web-based configuration (actionsfile) editor.  If you
+ * have a shared proxy, you might want to turn this off.
+ */
+#define FEATURE_CGI_EDIT_ACTIONS 1
+
+/*
+ * Allows the use of jar files to capture cookies.
+ */
+#define FEATURE_COOKIE_JAR 1
+
+/*
+ * Locally redirect remote script-redirect URLs
+ */
+#define FEATURE_FAST_REDIRECTS 1
+
+/*
+ * Bypass filtering for 1 page only
+ */
+#define FEATURE_FORCE_LOAD 1
+
+/*
+ * Allow blocking using images as well as HTML.
+ * If you do not define this then everything is blocked as HTML.
+ *
+ * Note that this is required if you want to use FEATURE_IMAGE_DETECT_MSIE.
+ */
+#define FEATURE_IMAGE_BLOCKING 1
+
+/*
+ * Detect image requests automatically for MSIE.  Will fall back to
+ * other image-detection methods (i.e. "+image" permission) for other
+ * browsers.
+ *
+ * You must also define FEATURE_IMAGE_BLOCKING to use this feature.
+ *
+ * It detects the following header pair as an image request:
+ *
+ * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
+ * Accept: * / *
+ *
+ * And the following as a HTML request:
+ *
+ * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
+ * Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, * / *
+ *
+ * And no, I haven't got that backwards - IE is being wierd.
+ *
+ * Known limitations: 
+ * 1) If you press shift-reload on a blocked HTML page, you get
+ *    the image "blocked" page, not the HTML "blocked" page.
+ * 2) Once an image "blocked" page has been sent, viewing it 
+ *    in it's own browser window *should* bring up the HTML
+ *    "blocked" page, but it doesn't.  You need to clear the 
+ *    browser cache to get the HTML version again.
+ *
+ * These limitations are due to IE making inconsistent choices
+ * about which "Accept:" header to send.
+ */
+#define FEATURE_IMAGE_DETECT_MSIE 1
+
+/*
+ * Kills JavaScript popups - window.open, onunload, etc.
+ */
+#define FEATURE_KILL_POPUPS 1
+
+/*
+ * Use POSIX threads instead of native threads.
+ */
+#define FEATURE_PTHREAD 1
+
+/*
+ * Enables statistics function.
+ */
+#define FEATURE_STATISTICS 1
+
+/*
+ * Allow JunkBuster to be "disabled" so it is just a normal non-blocking
+ * non-anonymizing proxy.  This is useful if you're trying to access a
+ * blocked or broken site - just change the setting in the config file,
+ * or use the handy "Disable" menu option in the Windows GUI.
+ */
+#define FEATURE_TOGGLE 1
+
+/*
+ * Allows the use of trust files.
+ */
+#define FEATURE_TRUST 1
+
+
+/****************************************************************************
+ * The following values are correct for MS VC++97.
+ * You should normally not change them.
+ ***************************************************************************/
+
+
+/*
+ * Defined on Solaris only.  Makes the system libraries thread safe.
+ */
+/* #define _REENTRANT 1 */
+
+/*
+ * Defined on Solaris only.  Without this, many important functions are not
+ * defined in the system headers.
+ */
+/* #define __EXTENSIONS__ 1 */
+
+/*
+ * Defined always.
+ * FIXME: Don't know what it does or why we need it.
+ * (presumably something to do with MultiThreading?)
+ */
+#define __MT__ 1
+
+
+/* Define if you have the `bcopy' function. */
+/* #define HAVE_BCOPY 1 */
+
+/* Define if you have the <inttypes.h> header file. */
+/* #define HAVE_INTTYPES_H 1 */
+
+/* Define if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <stdint.h> header file. */
+/* #define HAVE_STDINT_H 1 */
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the <strings.h> header file. */
+/* #define HAVE_STRINGS_H 1 */
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <unistd.h> header file. */
+/* #define HAVE_UNISTD_H 1 */
+
+/* The size of a `char *', as computed by sizeof. */
+#define SIZEOF_CHAR_P 4
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of a `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of a `long long', as computed by sizeof. */
+/* #define SIZEOF_LONG_LONG ---not supported--- */
+
+/* The size of a `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #define const */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #define size_t unsigned */
+
+/*
+ * Defined always.
+ * FIXME: Don't know what it does or why we need it.
+ * (presumably something to do with ANSI Standard C?)
+ */
+/* Don't define for MS VC++ or you don't get strdup() declared.
+#ifndef __STDC__
+#define __STDC__ 1
+#endif
+*/
+
+/*
+ * Need to set up this define only for the Pthreads library for
+ * Win32, available from http://sources.redhat.com/pthreads-win32/
+ */
+#if defined(FEATURE_PTHREAD) && defined(_WIN32)
+#define __CLEANUP_C
+#endif /* defined(FEATURE_PTHREAD) && defined(_WIN32) */
+
+/*
+ * BEOS does not currently support POSIX threads.
+ * This *should* be detected by ./configure, but let's be sure.
+ */
+#if defined(FEATURE_PTHREAD) && defined(__BEOS__)
+#error BEOS does not support pthread - please run ./configure again with "--disable-pthread"
+
+#endif /* defined(FEATURE_PTHREAD) && defined(__BEOS__) */
+
+
+#if (!defined(_MSC_VER)) && (!defined(RC_INVOKED))
+#error This file is only intended for MS VC++ on Win32.  For other compilers, please run configure.
+#endif /* (!defined(_MSC_VER)) && (!defined(RC_INVOKED)) */
+
+#pragma warning ( disable: 4100 4115 4201 4214 4244 4514 )
+
+/*
+ * C4100 : unreferenced formal parameter
+ * Very common, not a bug
+ * 
+ * C4115 : named type definition in parentheses
+ * #include <windows.h> causes a warning about one of these.
+ *
+ * C4201 : nonstandard extension used : nameless struct/union
+ * Endemic in <windows.h>
+ *
+ * C4214 nonstandard extension used : bit field types other than int
+ * Endemic in <windows.h>
+ *
+ * C4244 conversion from 'int' to 'char', possible loss of data
+ * Should really fix this one.  Throughout the JB code.
+ *
+ * C4514 unreferenced inline/local function has been removed
+ * Caused by #include <windows.h>
+ */
+
+#endif /* CONFIG_H_INCLUDED */
+
diff --git a/vc_config_winthreads.h b/vc_config_winthreads.h
new file mode 100644 (file)
index 0000000..396fb67
--- /dev/null
@@ -0,0 +1,478 @@
+#ifndef CONFIG_H_INCLUDED
+#define CONFIG_H_INCLUDED
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/vc_config_winthreads.h,v $
+ *
+ * Purpose     :  This file should be the first thing included in every
+ *                .c file.  (Before even system headers).  It contains 
+ *                #define statements for various features.  It was
+ *                introduced because the compile command line started
+ *                getting ludicrously long with feature defines.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                Privoxy team. http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: vc_config_winthreads.h,v $
+ *    Revision 1.2  2002/04/26 18:26:09  jongfoster
+ *    Bumping version numbers
+ *
+ *    Revision 1.1  2002/04/06 20:38:01  jongfoster
+ *    Renaming VC++ versions of config.h
+ *
+ *    Revision 1.14  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.13  2002/03/24 17:08:12  jongfoster
+ *    Version number bump
+ *
+ *    Revision 1.12  2002/03/24 13:25:43  swa
+ *    name change related issues
+ *
+ *    Revision 1.11  2002/03/16 14:27:22  jongfoster
+ *    Ignoring a very common warning.
+ *
+ *    Revision 1.10  2002/03/13 00:28:32  jongfoster
+ *    Hiding all the warnings generated by #include<windows.h>
+ *
+ *    Revision 1.9  2001/11/30 21:35:54  jongfoster
+ *    Bumping version number to 2.9.10
+ *
+ *    Revision 1.8  2001/10/23 21:24:09  jongfoster
+ *    Support for FEATURE_CGI_EDIT_ACTIONS
+ *
+ *    Revision 1.7  2001/10/07 15:33:14  oes
+ *    Removed FEATURE_DENY_GZIP
+ *    Bumped up version number
+ *
+ *    Revision 1.6  2001/09/16 16:59:34  jongfoster
+ *    Bugfix - couldn't build resources with previous version.
+ *
+ *    Revision 1.5  2001/09/16 16:19:02  jongfoster
+ *    New version based on latest configure.in and acconfig.h
+ *
+ *    Revision 1.9  2001/07/30 22:16:07  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.8  2001/07/25 19:16:27  oes
+ *    Bumping version number to 2.9.8
+ *
+ *    Revision 1.7  2001/07/21 18:00:07  jongfoster
+ *    Bumping version number to 2.9.7
+ *
+ *    Revision 1.6  2001/07/15 20:08:40  jongfoster
+ *    New build files for VC++ which provide the option of POSIX
+ *    or Win32 threads.
+ *
+ *    Revision 1.5  2001/07/15 18:00:46  jongfoster
+ *    Renaming STATIC to STATIC_PCRE.
+ *    Replacing this file with one built by "configure" from
+ *    "config.h.in", for consistency.
+ *
+ *    Revision 1.6  2001/07/15 17:54:29  jongfoster
+ *    Renaming #define STATIC to STATIC_PCRE
+ *    Adding new #define FEATURE_PTHREAD that will be used to enable
+ *    POSIX threads support.
+ *
+ *    Revision 1.5  2001/07/13 13:48:37  oes
+ *     - (Fix:) Copied CODE_STATUS #define from config.h.in
+ *     - split REGEX #define into REGEX_GNU and REGEX_PCRE
+ *       and removed PCRE.
+ *       (REGEX = REGEX_GNU || REGEX_PCRE per project.h)
+ *     - Moved STATIC (for pcre) here from Makefile.in
+ *     - Introduced STATIC_PCRS #define to allow for dynaimc linking with
+ *       libpcrs
+ *     - Removed PCRS #define, since pcrs is now needed for CGI anyway
+ *
+ *    Revision 1.4  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.3  2001/05/26 01:26:34  jongfoster
+ *    New #define, WIN_GUI_EDIT, enables the (embryonic) Win32 GUI editor.
+ *    This #define cannot be set from ./configure - there's no point, it
+ *    doesn't work yet.  See feature request # 425722
+ *
+ *    Revision 1.2  2001/05/22 17:43:35  oes
+ *
+ *    - Enabled filtering banners by size rather than URL
+ *      by adding patterns that replace all standard banner
+ *      sizes with the "Junkbuster" gif to the re_filterfile
+ *
+ *    - Enabled filtering WebBugs by providing a pattern
+ *      which kills all 1x1 images
+ *
+ *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
+ *      which is selected by the (nonstandard and therefore
+ *      capital) letter 'U' in the option string.
+ *      It causes the quantifiers to be ungreedy by default.
+ *      Appending a ? turns back to greedy (!).
+ *
+ *    - Added a new interceptor ijb-send-banner, which
+ *      sends back the "Junkbuster" gif. Without imagelist or
+ *      MSIE detection support, or if tinygif = 1, or the
+ *      URL isn't recognized as an imageurl, a lame HTML
+ *      explanation is sent instead.
+ *
+ *    - Added new feature, which permits blocking remote
+ *      script redirects and firing back a local redirect
+ *      to the browser.
+ *      The feature is conditionally compiled, i.e. it
+ *      can be disabled with --disable-fast-redirects,
+ *      plus it must be activated by a "fast-redirects"
+ *      line in the config file, has its own log level
+ *      and of course wants to be displayed by show-proxy-args
+ *      Note: Boy, all the #ifdefs in 1001 locations and
+ *      all the fumbling with configure.in and acconfig.h
+ *      were *way* more work than the feature itself :-(
+ *
+ *    - Because a generic redirect template was needed for
+ *      this, tinygif = 3 now uses the same.
+ *
+ *    - Moved GIFs, and other static HTTP response templates
+ *      to project.h
+ *
+ *    - Many minor fixes
+ *
+ *    - Removed some >400 CRs again (Jon, you really worked
+ *      a lot! ;-)
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:58:45  oes
+ *    Initial import of version 2.9.3 source tree
+ *
+ *
+ *********************************************************************/
+\f
+
+/*
+ * Version number - Major (X._._)
+ */
+#define VERSION_MAJOR 2
+
+/*
+ * Version number - Minor (_.X._)
+ */
+#define VERSION_MINOR 9
+
+/*
+ * Version number - Point (_._.X)
+ */
+#define VERSION_POINT 15
+
+/*
+ * Version number, as a string
+ */
+#define VERSION "2.9.15"
+
+/*
+ * Status of the code: alpha, beta or stable
+ */
+#define CODE_STATUS "beta"
+
+/*
+ * Regular expression matching for URLs.  (Highly recommended).
+ * If neither of these are defined then you can ony use prefix matching.
+ * Don't bother to change this here! Use configure instead.
+ */
+/* #define REGEX_GNU 1 */
+#define REGEX_PCRE 1
+
+/* 
+ * Should pcre be statically built in instead of linkling with libpcre?
+ * (This is determined by configure depending on the availiability of
+ * libpcre and user preferences). The name is ugly, but pcre needs it.
+ * Don't bother to change this here! Use configure instead.
+ */
+#define STATIC_PCRE 1
+
+/* 
+ * Should pcrs be statically built in instead of linkling with libpcrs?
+ * (This is determined by configure depending on the availiability of
+ * libpcrs and user preferences).
+ * Don't bother to change this here! Use configure instead.
+ */
+#define STATIC_PCRS 1
+
+/*
+ * Allows the use of an ACL to control access to the proxy by IP address.
+ */
+#define FEATURE_ACL 1
+
+/*
+ * Enables the web-based configuration (actionsfile) editor.  If you
+ * have a shared proxy, you might want to turn this off.
+ */
+#define FEATURE_CGI_EDIT_ACTIONS 1
+
+/*
+ * Allows the use of jar files to capture cookies.
+ */
+#define FEATURE_COOKIE_JAR 1
+
+/*
+ * Locally redirect remote script-redirect URLs
+ */
+#define FEATURE_FAST_REDIRECTS 1
+
+/*
+ * Bypass filtering for 1 page only
+ */
+#define FEATURE_FORCE_LOAD 1
+
+/*
+ * Allow blocking using images as well as HTML.
+ * If you do not define this then everything is blocked as HTML.
+ *
+ * Note that this is required if you want to use FEATURE_IMAGE_DETECT_MSIE.
+ */
+#define FEATURE_IMAGE_BLOCKING 1
+
+/*
+ * Detect image requests automatically for MSIE.  Will fall back to
+ * other image-detection methods (i.e. "+image" permission) for other
+ * browsers.
+ *
+ * You must also define FEATURE_IMAGE_BLOCKING to use this feature.
+ *
+ * It detects the following header pair as an image request:
+ *
+ * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
+ * Accept: * / *
+ *
+ * And the following as a HTML request:
+ *
+ * User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
+ * Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, * / *
+ *
+ * And no, I haven't got that backwards - IE is being wierd.
+ *
+ * Known limitations: 
+ * 1) If you press shift-reload on a blocked HTML page, you get
+ *    the image "blocked" page, not the HTML "blocked" page.
+ * 2) Once an image "blocked" page has been sent, viewing it 
+ *    in it's own browser window *should* bring up the HTML
+ *    "blocked" page, but it doesn't.  You need to clear the 
+ *    browser cache to get the HTML version again.
+ *
+ * These limitations are due to IE making inconsistent choices
+ * about which "Accept:" header to send.
+ */
+#define FEATURE_IMAGE_DETECT_MSIE 1
+
+/*
+ * Kills JavaScript popups - window.open, onunload, etc.
+ */
+#define FEATURE_KILL_POPUPS 1
+
+/*
+ * Use POSIX threads instead of native threads.
+ */
+/* #define FEATURE_PTHREAD 1 */
+
+/*
+ * Enables statistics function.
+ */
+#define FEATURE_STATISTICS 1
+
+/*
+ * Allow JunkBuster to be "disabled" so it is just a normal non-blocking
+ * non-anonymizing proxy.  This is useful if you're trying to access a
+ * blocked or broken site - just change the setting in the config file,
+ * or use the handy "Disable" menu option in the Windows GUI.
+ */
+#define FEATURE_TOGGLE 1
+
+/*
+ * Allows the use of trust files.
+ */
+#define FEATURE_TRUST 1
+
+
+/****************************************************************************
+ * The following values are correct for MS VC++97.
+ * You should normally not change them.
+ ***************************************************************************/
+
+
+/*
+ * Defined on Solaris only.  Makes the system libraries thread safe.
+ */
+/* #define _REENTRANT 1 */
+
+/*
+ * Defined on Solaris only.  Without this, many important functions are not
+ * defined in the system headers.
+ */
+/* #define __EXTENSIONS__ 1 */
+
+/*
+ * Defined always.
+ * FIXME: Don't know what it does or why we need it.
+ * (presumably something to do with MultiThreading?)
+ */
+#define __MT__ 1
+
+
+/* Define if you have the `bcopy' function. */
+/* #define HAVE_BCOPY 1 */
+
+/* Define if you have the <inttypes.h> header file. */
+/* #define HAVE_INTTYPES_H 1 */
+
+/* Define if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <stdint.h> header file. */
+/* #define HAVE_STDINT_H 1 */
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the <strings.h> header file. */
+/* #define HAVE_STRINGS_H 1 */
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <unistd.h> header file. */
+/* #define HAVE_UNISTD_H 1 */
+
+/* The size of a `char *', as computed by sizeof. */
+#define SIZEOF_CHAR_P 4
+
+/* The size of a `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of a `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of a `long long', as computed by sizeof. */
+/* #define SIZEOF_LONG_LONG ---not supported--- */
+
+/* The size of a `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #define const */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #define size_t unsigned */
+
+/*
+ * Defined always.
+ * FIXME: Don't know what it does or why we need it.
+ * (presumably something to do with ANSI Standard C?)
+ */
+/* Don't define for MS VC++ or you don't get strdup() declared.
+#ifndef __STDC__
+#define __STDC__ 1
+#endif
+*/
+
+/*
+ * Need to set up this define only for the Pthreads library for
+ * Win32, available from http://sources.redhat.com/pthreads-win32/
+ */
+#if defined(FEATURE_PTHREAD) && defined(_WIN32)
+#define __CLEANUP_C
+#endif /* defined(FEATURE_PTHREAD) && defined(_WIN32) */
+
+/*
+ * BEOS does not currently support POSIX threads.
+ * This *should* be detected by ./configure, but let's be sure.
+ */
+#if defined(FEATURE_PTHREAD) && defined(__BEOS__)
+#error BEOS does not support pthread - please run ./configure again with "--disable-pthread"
+
+#endif /* defined(FEATURE_PTHREAD) && defined(__BEOS__) */
+
+
+#if (!defined(_MSC_VER)) && (!defined(RC_INVOKED))
+#error This file is only intended for MS VC++ on Win32.  For other compilers, please run configure.
+#endif /* (!defined(_MSC_VER)) && (!defined(RC_INVOKED)) */
+
+#pragma warning ( disable: 4100 4115 4201 4214 4244 4514 )
+
+/*
+ * C4100 : unreferenced formal parameter
+ * Very common, not a bug
+ * 
+ * C4115 : named type definition in parentheses
+ * #include <windows.h> causes a warning about one of these.
+ *
+ * C4201 : nonstandard extension used : nameless struct/union
+ * Endemic in <windows.h>
+ *
+ * C4214 nonstandard extension used : bit field types other than int
+ * Endemic in <windows.h>
+ *
+ * C4244 conversion from 'int' to 'char', possible loss of data
+ * Should really fix this one.  Throughout the JB code.
+ *
+ * C4514 unreferenced inline/local function has been removed
+ * Caused by #include <windows.h>
+ */
+
+
+#endif /* CONFIG_H_INCLUDED */
+
diff --git a/vc_console.dsp b/vc_console.dsp
new file mode 100644 (file)
index 0000000..23d2f2a
--- /dev/null
@@ -0,0 +1,413 @@
+# Microsoft Developer Studio Project File - Name="vc_console" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 5.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
+\r
+CFG=vc_console - Win32 Debug with Win32 threads\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "vc_console.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "vc_console.mak"\\r
+ CFG="vc_console - Win32 Debug with Win32 threads"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "vc_console - Win32 Release" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE "vc_console - Win32 Debug" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE "vc_console - Win32 Debug with Win32 threads" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE "vc_console - Win32 Release with Win32 threads" (based on\\r
+ "Win32 (x86) Console Application")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "vc_console - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "console_release"\r
+# PROP Intermediate_Dir "console_release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "pcre" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WIN_CONSOLE" /D "STATIC" /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:console /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "vc_console - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "console_debug"\r
+# PROP Intermediate_Dir "console_debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "pcre" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WIN_CONSOLE" /D "STATIC" /FR /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "vc_console - Win32 Debug with Win32 threads"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "console_"\r
+# PROP BASE Intermediate_Dir "console_"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "console_debug_winthr"\r
+# PROP Intermediate_Dir "console_debug_winthr"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "pcre" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WIN_CONSOLE" /D "STATIC" /FR /YX /FD /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "pcre" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WIN_CONSOLE" /D "STATIC" /FR /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "vc_console - Win32 Release with Win32 threads"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "console0"\r
+# PROP BASE Intermediate_Dir "console0"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "console_release_winthr"\r
+# PROP Intermediate_Dir "console_release_winthr"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "pcre" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WIN_CONSOLE" /D "STATIC" /YX /FD /c\r
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "pcre" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WIN_CONSOLE" /D "STATIC" /YX /FD /c\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:console /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib /nologo /subsystem:console /machine:I386\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "vc_console - Win32 Release"\r
+# Name "vc_console - Win32 Debug"\r
+# Name "vc_console - Win32 Debug with Win32 threads"\r
+# Name "vc_console - Win32 Release with Win32 threads"\r
+# Begin Group "JunkBuster"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\actionlist.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\actions.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\actions.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgi.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgi.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgiedit.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgiedit.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgisimple.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgisimple.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\config.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\deanimate.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\deanimate.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\errlog.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\errlog.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\filters.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\filters.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\jcc.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\jcc.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\killpopup.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\killpopup.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\loadcfg.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\loadcfg.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\loaders.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\loaders.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\parsers.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\parsers.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\project.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\urlmatch.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\urlmatch.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Win32"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\cygwin.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\win32.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\win32.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "PCRE"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\chartables.c\r
+\r
+!IF  "$(CFG)" == "vc_console - Win32 Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_console - Win32 Debug"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_console - Win32 Debug with Win32 threads"\r
+\r
+# PROP BASE Exclude_From_Build 1\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_console - Win32 Release with Win32 threads"\r
+\r
+# PROP BASE Exclude_From_Build 1\r
+# PROP Exclude_From_Build 1\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\config.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\get.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\internal.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\maketables.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\pcre.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\pcre.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\pcreposix.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\pcreposix.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcre\study.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "PCRS"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\pcrs.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\pcrs.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Sockets"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\gateway.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\gateway.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\jbsockets.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\jbsockets.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Utilities"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\encode.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\encode.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\list.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\list.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\miscutil.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\miscutil.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\ssplit.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\ssplit.h\r
+# End Source File\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/vc_junkbuster.dsw b/vc_junkbuster.dsw
deleted file mode 100644 (file)
index a275c02..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 5.00\r
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
-\r
-###############################################################################\r
-\r
-Project: "vc_junkbuster"=".\vc_junkbuster.dsp" - Package Owner=<4>\r
-\r
-Package=<5>\r
-{{{\r
-}}}\r
-\r
-Package=<4>\r
-{{{\r
-}}}\r
-\r
-###############################################################################\r
-\r
-Global:\r
-\r
-Package=<5>\r
-{{{\r
-}}}\r
-\r
-Package=<3>\r
-{{{\r
-}}}\r
-\r
-###############################################################################\r
-\r
similarity index 57%
rename from vc_junkbuster.dsp
rename to vc_privoxy.dsp
index f9acd6b..3a61a18 100644 (file)
@@ -1,24 +1,29 @@
-# Microsoft Developer Studio Project File - Name="vc_junkbuster" - Package Owner=<4>\r
+# Microsoft Developer Studio Project File - Name="vc_privoxy" - Package Owner=<4>\r
 # Microsoft Developer Studio Generated Build File, Format Version 5.00\r
 # ** DO NOT EDIT **\r
 \r
 # TARGTYPE "Win32 (x86) Application" 0x0101\r
 \r
-CFG=vc_junkbuster - Win32 Release\r
+CFG=vc_privoxy - Win32 Debug with Win32 threads\r
 !MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
 !MESSAGE use the Export Makefile command and run\r
 !MESSAGE \r
-!MESSAGE NMAKE /f "vc_junkbuster.mak".\r
+!MESSAGE NMAKE /f "vc_privoxy.mak".\r
 !MESSAGE \r
 !MESSAGE You can specify a configuration when running NMAKE\r
 !MESSAGE by defining the macro CFG on the command line. For example:\r
 !MESSAGE \r
-!MESSAGE NMAKE /f "vc_junkbuster.mak" CFG="vc_junkbuster - Win32 Release"\r
+!MESSAGE NMAKE /f "vc_privoxy.mak"\\r
+ CFG="vc_privoxy - Win32 Debug with Win32 threads"\r
 !MESSAGE \r
 !MESSAGE Possible choices for configuration are:\r
 !MESSAGE \r
-!MESSAGE "vc_junkbuster - Win32 Release" (based on "Win32 (x86) Application")\r
-!MESSAGE "vc_junkbuster - Win32 Debug" (based on "Win32 (x86) Application")\r
+!MESSAGE "vc_privoxy - Win32 Release" (based on "Win32 (x86) Application")\r
+!MESSAGE "vc_privoxy - Win32 Debug" (based on "Win32 (x86) Application")\r
+!MESSAGE "vc_privoxy - Win32 Release with Win32 threads" (based on\\r
+ "Win32 (x86) Application")\r
+!MESSAGE "vc_privoxy - Win32 Debug with Win32 threads" (based on\\r
+ "Win32 (x86) Application")\r
 !MESSAGE \r
 \r
 # Begin Project\r
@@ -28,7 +33,7 @@ CPP=cl.exe
 MTL=midl.exe\r
 RSC=rc.exe\r
 \r
-!IF  "$(CFG)" == "vc_junkbuster - Win32 Release"\r
+!IF  "$(CFG)" == "vc_privoxy - Win32 Release"\r
 \r
 # PROP BASE Use_MFC 0\r
 # PROP BASE Use_Debug_Libraries 0\r
@@ -52,9 +57,9 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo\r
 LINK32=link.exe\r
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386\r
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib /nologo /subsystem:windows /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:windows /machine:I386\r
 \r
-!ELSEIF  "$(CFG)" == "vc_junkbuster - Win32 Debug"\r
+!ELSEIF  "$(CFG)" == "vc_privoxy - Win32 Debug"\r
 \r
 # PROP BASE Use_MFC 0\r
 # PROP BASE Use_Debug_Libraries 1\r
@@ -68,7 +73,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0\r
 # PROP Target_Dir ""\r
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c\r
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /O2 /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /YX /FD /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c\r
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32\r
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32\r
 # ADD BASE RSC /l 0x809 /d "_DEBUG"\r
@@ -78,24 +83,108 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo\r
 LINK32=link.exe\r
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\r
+\r
+!ELSEIF  "$(CFG)" == "vc_privoxy - Win32 Release with Win32 threads"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "vc_junkb"\r
+# PROP BASE Intermediate_Dir "vc_junkb"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "vc_release_winthr"\r
+# PROP Intermediate_Dir "vc_release_winthr"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "pcre" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c\r
+# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "pcre" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:windows /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib /nologo /subsystem:windows /machine:I386\r
+\r
+!ELSEIF  "$(CFG)" == "vc_privoxy - Win32 Debug with Win32 threads"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "vc_junk0"\r
+# PROP BASE Intermediate_Dir "vc_junk0"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "vc_debug_winthr"\r
+# PROP Intermediate_Dir "vc_debug_winthr"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /O2 /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /YX /FD /c\r
+# ADD CPP /nologo /MTd /W4 /Gm /GX /Zi /Od /I "pcre" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "STATIC" /FR /YX /FD /c\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib pthreadVC.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\r
 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept\r
 \r
 !ENDIF \r
 \r
 # Begin Target\r
 \r
-# Name "vc_junkbuster - Win32 Release"\r
-# Name "vc_junkbuster - Win32 Debug"\r
+# Name "vc_privoxy - Win32 Release"\r
+# Name "vc_privoxy - Win32 Debug"\r
+# Name "vc_privoxy - Win32 Release with Win32 threads"\r
+# Name "vc_privoxy - Win32 Debug with Win32 threads"\r
 # Begin Group "JunkBuster"\r
 \r
 # PROP Default_Filter ""\r
 # Begin Source File\r
 \r
-SOURCE=.\amiga.c\r
+SOURCE=.\actionlist.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\actions.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\actions.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgi.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgi.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgiedit.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgiedit.h\r
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\amiga.h\r
+SOURCE=.\cgisimple.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\cgisimple.h\r
 # End Source File\r
 # Begin Source File\r
 \r
@@ -103,6 +192,14 @@ SOURCE=.\config.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\deanimate.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\deanimate.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\errlog.c\r
 # End Source File\r
 # Begin Source File\r
@@ -163,11 +260,11 @@ SOURCE=.\project.h
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\showargs.c\r
+SOURCE=.\urlmatch.c\r
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\showargs.h\r
+SOURCE=.\urlmatch.h\r
 # End Source File\r
 # End Group\r
 # Begin Group "Win32"\r
@@ -191,14 +288,6 @@ SOURCE=.\w32res.h
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\w32rulesdlg.c\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\w32rulesdlg.h\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\w32taskbar.c\r
 # End Source File\r
 # Begin Source File\r
@@ -219,10 +308,6 @@ SOURCE=.\win32.h
 # PROP Default_Filter "rc,ico,bmp"\r
 # Begin Source File\r
 \r
-SOURCE=.\icons\denyrule.ico\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\icons\ico00001.ico\r
 # End Source File\r
 # Begin Source File\r
@@ -255,15 +340,11 @@ SOURCE=.\icons\ico00008.ico
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\icons\icon1.ico\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\icons\idle.ico\r
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\icons\junkbust.ico\r
+SOURCE=.\icons\privoxy.ico\r
 # End Source File\r
 # Begin Source File\r
 \r
@@ -277,10 +358,22 @@ SOURCE=.\w32.rc
 \r
 SOURCE=.\pcre\chartables.c\r
 \r
-!IF  "$(CFG)" == "vc_junkbuster - Win32 Release"\r
+!IF  "$(CFG)" == "vc_privoxy - Win32 Release"\r
+\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_privoxy - Win32 Debug"\r
 \r
-!ELSEIF  "$(CFG)" == "vc_junkbuster - Win32 Debug"\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_privoxy - Win32 Release with Win32 threads"\r
+\r
+# PROP BASE Exclude_From_Build 1\r
+# PROP Exclude_From_Build 1\r
+\r
+!ELSEIF  "$(CFG)" == "vc_privoxy - Win32 Debug with Win32 threads"\r
 \r
+# PROP BASE Exclude_From_Build 1\r
 # PROP Exclude_From_Build 1\r
 \r
 !ENDIF \r
@@ -368,6 +461,14 @@ SOURCE=.\encode.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\list.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\list.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\miscutil.c\r
 # End Source File\r
 # Begin Source File\r
diff --git a/vc_privoxy.dsw b/vc_privoxy.dsw
new file mode 100644 (file)
index 0000000..3bee927
--- /dev/null
@@ -0,0 +1,59 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "vc_console"=".\vc_console.dsp" - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name vc_dftables\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "vc_dftables"=".\pcre\vc_dftables.dsp" - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "vc_privoxy"=".\vc_privoxy.dsp" - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name vc_dftables\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/w32.aps b/w32.aps
deleted file mode 100644 (file)
index 85caaa5..0000000
Binary files a/w32.aps and /dev/null differ
diff --git a/w32.rc b/w32.rc
index 99cdac2..20f6a93 100644 (file)
--- a/w32.rc
+++ b/w32.rc
-/*********************************************************************\r
- *\r
- * File        :  $Source:  $\r
- *\r
- * Purpose     :  Windows GUI resource script.\r
- *\r
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge\r
- *                IJBSWA team.  http://ijbswa.sourceforge.net\r
- *\r
- *                Based on the Internet Junkbuster originally written\r
- *                by and Copyright (C) 1997 Anonymous Coders and \r
- *                Junkbusters Corporation.  http://www.junkbusters.com\r
- *\r
- *                This program is free software; you can redistribute it \r
- *                and/or modify it under the terms of the GNU General\r
- *                Public License as published by the Free Software\r
- *                Foundation; either version 2 of the License, or (at\r
- *                your option) any later version.\r
- *\r
- *                This program is distributed in the hope that it will\r
- *                be useful, but WITHOUT ANY WARRANTY; without even the\r
- *                implied warranty of MERCHANTABILITY or FITNESS FOR A\r
- *                PARTICULAR PURPOSE.  See the GNU General Public\r
- *                License for more details.\r
- *\r
- *                The GNU General Public License should be included with\r
- *                this file.  If not, you can view it at\r
- *                http://www.gnu.org/copyleft/gpl.html\r
- *                or write to the Free Software Foundation, Inc., 59\r
- *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
- *\r
- * Revisions   :\r
- *    $Log:$\r
- *\r
- *********************************************************************/\r
-\r
-#include <windows.h>\r
-#include "config.h"\r
-#include "w32res.h"\r
-\r
-#ifdef __MINGW32__\r
-#include "cygwin.h"\r
-#endif\r
-\r
-/****************************************************************************\r
- *  Language-neutral resources\r
- ****************************************************************************/\r
-\r
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)\r
-#ifdef _WIN32\r
-/* LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL */\r
-#pragma code_page(1252)\r
-#endif /* _WIN32 */\r
-\r
-/*\r
- * Icons\r
- *\r
- * Icon with lowest ID value placed first to ensure application icon\r
- * remains consistent on all systems.\r
- */\r
-IDI_JUNKBUSTER          ICON    DISCARDABLE     "icons/junkbust.ico"\r
-IDI_JUNKBUSTER1         ICON    DISCARDABLE     "icons/ico00001.ico"\r
-IDI_JUNKBUSTER2         ICON    DISCARDABLE     "icons/ico00002.ico"\r
-IDI_JUNKBUSTER3         ICON    DISCARDABLE     "icons/ico00003.ico"\r
-IDI_JUNKBUSTER4         ICON    DISCARDABLE     "icons/ico00004.ico"\r
-IDI_JUNKBUSTER5         ICON    DISCARDABLE     "icons/ico00005.ico"\r
-IDI_JUNKBUSTER6         ICON    DISCARDABLE     "icons/ico00006.ico"\r
-IDI_JUNKBUSTER7         ICON    DISCARDABLE     "icons/ico00007.ico"\r
-IDI_JUNKBUSTER8         ICON    DISCARDABLE     "icons/ico00008.ico"\r
-IDI_IDLE                ICON    DISCARDABLE     "icons/idle.ico"\r
-\r
-#endif /* Neutral resources */\r
-\r
-\r
-/****************************************************************************\r
- *  English (U.S.) resources\r
- ****************************************************************************/\r
-\r
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
-#ifdef _WIN32\r
-/* LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US */\r
-#pragma code_page(1252)\r
-#endif //_WIN32\r
-\r
-/*\r
- * Menus\r
- */\r
-\r
-IDR_TRAYMENU MENU DISCARDABLE\r
-BEGIN\r
-    POPUP "Popup"\r
-    BEGIN\r
-        MENUITEM "E&xit JunkBuster",   ID_FILE_EXIT\r
-        MENUITEM                       SEPARATOR\r
-        POPUP "&Options"\r
-        BEGIN\r
-            MENUITEM "&Junkbuster...",              ID_TOOLS_EDITJUNKBUSTER\r
-            MENUITEM                                SEPARATOR\r
-            MENUITEM "&Blockers...",                ID_TOOLS_EDITBLOCKERS\r
-            MENUITEM "&Cookies...",                 ID_TOOLS_EDITCOOKIES\r
-            MENUITEM "&Forward...",                 ID_TOOLS_EDITFORWARD\r
-#ifdef ACL_FILES\r
-            MENUITEM "&Access Control Lists...",    ID_TOOLS_EDITACLS\r
-#endif /* def ACL_FILES */\r
-#ifdef USE_IMAGE_LIST\r
-            MENUITEM "&Images...",                  ID_TOOLS_EDITIMAGE\r
-#endif /* def USE_IMAGE_LIST */\r
-#ifdef KILLPOPUPS\r
-            MENUITEM "&Popups...",                  ID_TOOLS_EDITPOPUPS\r
-#endif /* def KILLPOPUPS */\r
-#ifdef PCRS\r
-            MENUITEM "Perl &Regexps...",            ID_TOOLS_EDITPERLRE\r
-#endif /* def PCRS */\r
-#ifdef TRUST_FILES\r
-            MENUITEM "&Trust...",                   ID_TOOLS_EDITTRUST\r
-#endif /* def TRUST_FILES */\r
-        END\r
-        MENUITEM                              SEPARATOR\r
-#ifdef TOGGLE\r
-        MENUITEM "&Enable",                   ID_TOGGLE_IJB, CHECKED\r
-#endif\r
-        MENUITEM "&Reload config",            ID_RELOAD_CONFIG\r
-        MENUITEM "Show &JunkBuster Window",   ID_SHOWWINDOW\r
-    END\r
-END\r
-\r
-IDR_LOGVIEW MENU DISCARDABLE\r
-BEGIN\r
-    POPUP "&File"\r
-    BEGIN\r
-        MENUITEM "E&xit",                       ID_FILE_EXIT\r
-    END\r
-    POPUP "&Edit"\r
-    BEGIN\r
-        MENUITEM "Copy",                        ID_EDIT_COPY\r
-    END\r
-    POPUP "&View"\r
-    BEGIN\r
-        MENUITEM "&Clear Log",                  ID_VIEW_CLEARLOG\r
-        MENUITEM                                SEPARATOR\r
-        MENUITEM "&Log Messages",               ID_VIEW_LOGMESSAGES, CHECKED\r
-        MENUITEM "Message &Highlighting",       ID_VIEW_MESSAGEHIGHLIGHTING, CHECKED\r
-        MENUITEM "Limit &Buffer Size",          ID_VIEW_LIMITBUFFERSIZE, CHECKED\r
-        MENUITEM "&Activity Animation",         ID_VIEW_ACTIVITYANIMATION, CHECKED\r
-    END\r
-    POPUP "&Options"\r
-    BEGIN\r
-#ifdef TOGGLE\r
-        MENUITEM "&Enable",                     ID_TOGGLE_IJB, CHECKED\r
-        MENUITEM "&Reload config",              ID_RELOAD_CONFIG\r
-        MENUITEM                                SEPARATOR\r
-#endif\r
-        MENUITEM "&Junkbuster...",              ID_TOOLS_EDITJUNKBUSTER\r
-        MENUITEM                                SEPARATOR\r
-        MENUITEM "&Blockers...",                ID_TOOLS_EDITBLOCKERS\r
-        MENUITEM "&Cookies...",                 ID_TOOLS_EDITCOOKIES\r
-        MENUITEM "&Forward...",                 ID_TOOLS_EDITFORWARD\r
-#ifdef ACL_FILES\r
-            MENUITEM "&Access Control Lists...",ID_TOOLS_EDITACLS\r
-#endif /* def ACL_FILES */\r
-#ifdef USE_IMAGE_LIST\r
-            MENUITEM "&Images...",              ID_TOOLS_EDITIMAGE\r
-#endif /* def USE_IMAGE_LIST */\r
-#ifdef KILLPOPUPS\r
-            MENUITEM "&Popups...",              ID_TOOLS_EDITPOPUPS\r
-#endif /* def KILLPOPUPS */\r
-#ifdef PCRS\r
-            MENUITEM "Perl &Regexps...",        ID_TOOLS_EDITPERLRE\r
-#endif /* def PCRS */\r
-#ifdef TRUST_FILES\r
-            MENUITEM "&Trust...",               ID_TOOLS_EDITTRUST\r
-#endif /* def TRUST_FILES */\r
-    END\r
-    POPUP "&Help"\r
-    BEGIN\r
-        MENUITEM "Junkbuster &FAQ",             ID_HELP_FAQ\r
-        MENUITEM "Junkbuster &Manual",          ID_HELP_MANUAL\r
-        MENUITEM "GNU &General Public Licence", ID_HELP_GPL\r
-        MENUITEM                                SEPARATOR\r
-        MENUITEM "Junkbuster Status...",        ID_HELP_STATUS\r
-        MENUITEM                                SEPARATOR\r
-        MENUITEM "About Junkbuster...",         ID_HELP_ABOUTJUNKBUSTER\r
-    END\r
-END\r
-\r
-IDR_POPUP_SELECTION MENU DISCARDABLE\r
-BEGIN\r
-    POPUP "Popup"\r
-    BEGIN\r
-        MENUITEM "&Copy",                       ID_EDIT_COPY\r
-    END\r
-END\r
-\r
-\r
-/*\r
- * Accelerators\r
- */\r
-\r
-IDR_ACCELERATOR ACCELERATORS DISCARDABLE\r
-BEGIN\r
-    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL, NOINVERT\r
-END\r
-\r
-/*\r
- * Icons\r
- *\r
- * Icon with lowest ID value placed first to ensure application icon\r
- * remains consistent on all systems.\r
- */\r
-IDI_DENYRULE            ICON    DISCARDABLE     "icons/denyrule.ico"\r
-IDI_ALLOWRULE           ICON    DISCARDABLE     "icons/icon1.ico"\r
-\r
-/*\r
- * Dialog\r
- */\r
-\r
-IDD_RULES DIALOG DISCARDABLE  0, 0, 239, 225\r
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
-CAPTION "Blockers"\r
-FONT 8, "MS Sans Serif"\r
-BEGIN\r
-    GROUPBOX        "New Rule",IDC_STATIC,5,5,230,55\r
-    LTEXT           "For:",IDC_STATIC,10,15,13,8\r
-    EDITTEXT        IDC_NEW,10,25,220,12,ES_AUTOHSCROLL\r
-    COMBOBOX        IDC_ACTION,10,40,75,37,CBS_DROPDOWNLIST | CBS_SORT |\r
-                    WS_VSCROLL | WS_TABSTOP\r
-    PUSHBUTTON      "C&reate!",IDC_CREATE,90,40,50,14\r
-    GROUPBOX        "Rules",IDC_STATIC,5,65,230,135\r
-    CONTROL         "List1",IDC_RULES,"SysListView32",LVS_REPORT |\r
-                    LVS_SHOWSELALWAYS | LVS_EDITLABELS | WS_BORDER |\r
-                    WS_TABSTOP,10,75,220,100\r
-    PUSHBUTTON      "Move &Up",IDC_MOVEUP,10,180,50,14,WS_DISABLED\r
-    PUSHBUTTON      "Move &Down",IDC_MOVEDOWN,65,180,50,14,WS_DISABLED\r
-    PUSHBUTTON      "&Delete",IDC_DELETE,120,180,50,14,WS_DISABLED\r
-    PUSHBUTTON      "&Save",IDC_SAVE,130,205,50,14\r
-    PUSHBUTTON      "&Cancel",IDCANCEL,185,205,50,14\r
-END\r
-\r
-\r
-/*\r
- * DESIGNINFO\r
- */\r
-\r
-#ifdef APSTUDIO_INVOKED\r
-GUIDELINES DESIGNINFO DISCARDABLE\r
-BEGIN\r
-    IDD_RULES, DIALOG\r
-    BEGIN\r
-        LEFTMARGIN, 7\r
-        RIGHTMARGIN, 232\r
-        TOPMARGIN, 7\r
-        BOTTOMMARGIN, 218\r
-    END\r
-END\r
-#endif    // APSTUDIO_INVOKED\r
-\r
-\r
-/*\r
- * String Table\r
- */\r
-\r
-STRINGTABLE DISCARDABLE\r
-BEGIN\r
-    IDS_NEW_BLOCKER         "Create rule for ""%s""..."\r
-END\r
-\r
-#endif /* English (U.S.) resources */\r
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/w32.rc,v $
+ *
+ * Purpose     :  Windows GUI resource script.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
+ *
+ *                Based on the Internet Junkbuster originally written
+ *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                Junkbusters Corporation.  http://www.junkbusters.com
+ *
+ *                This program is free software; you can redistribute it 
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Revisions   :
+ *    $Log: w32.rc,v $
+ *    Revision 1.16  2002/03/26 22:57:44  jongfoster
+ *    Web server name should begin www.
+ *
+ *    Revision 1.15  2002/03/24 14:29:25  jongfoster
+ *    Renaming icon file
+ *
+ *    Revision 1.14  2002/03/24 12:07:36  jongfoster
+ *    Consistern name for filters file
+ *
+ *    Revision 1.13  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.12  2001/07/30 22:16:07  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.11  2001/07/21 17:53:41  jongfoster
+ *    Adding version information block.
+ *
+ *    Revision 1.10  2001/07/19 19:14:19  haroon
+ *    -  Removed all #ifdef PCRS. The .rc file extension had eluded Andreas.
+ *
+ *    Revision 1.9  2001/06/07 23:08:54  jongfoster
+ *    Forward and ACL edit options removed.
+ *    Config edit option renamed from "&Junkbuster" to "&Configuration".
+ *
+ *    Revision 1.8  2001/05/31 21:37:11  jongfoster
+ *    GUI changes to rename "permissions file" to "actions file".
+ *
+ *    Revision 1.7  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.6  2001/05/26 14:15:18  jongfoster
+ *    Cosmetic fix: // -> block comment
+ *
+ *    Revision 1.5  2001/05/26 13:24:31  jongfoster
+ *    New #define, WIN_GUI_EDIT, enables the (embryonic) Win32 GUI editor.
+ *    This #define cannot be set from ./configure - there's no point, it
+ *    doesn't work yet.  See feature request # 425722
+ *    (I missed this file in my original checkin)
+ *
+ *    Revision 1.4  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.3  2001/05/25 22:33:40  jongfoster
+ *    CRLF->LF
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:07  oes
+ *    Initial import of version 2.9.3 source tree
+ *
+ *
+ *********************************************************************/
+
+#include "config.h"
+
+#ifndef STRICT
+#define STRICT
+#endif
+#include <windows.h>
+
+#include "w32res.h"
+
+#ifdef __MINGW32__
+#include "cygwin.h"
+#endif
+
+/****************************************************************************
+ *  Language-neutral resources
+ ****************************************************************************/
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+/* LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL */
+#pragma code_page(1252)
+#endif /* _WIN32 */
+
+/*
+ * Icons
+ *
+ * Icon with lowest ID value placed first to ensure application icon
+ * remains consistent on all systems.
+ */
+IDI_MAINICON            ICON    DISCARDABLE     "icons/privoxy.ico"
+IDI_ANIMATED1           ICON    DISCARDABLE     "icons/ico00001.ico"
+IDI_ANIMATED2           ICON    DISCARDABLE     "icons/ico00002.ico"
+IDI_ANIMATED3           ICON    DISCARDABLE     "icons/ico00003.ico"
+IDI_ANIMATED4           ICON    DISCARDABLE     "icons/ico00004.ico"
+IDI_ANIMATED5           ICON    DISCARDABLE     "icons/ico00005.ico"
+IDI_ANIMATED6           ICON    DISCARDABLE     "icons/ico00006.ico"
+IDI_ANIMATED7           ICON    DISCARDABLE     "icons/ico00007.ico"
+IDI_ANIMATED8           ICON    DISCARDABLE     "icons/ico00008.ico"
+IDI_IDLE                ICON    DISCARDABLE     "icons/idle.ico"
+
+#endif /* Neutral resources */
+
+
+/****************************************************************************
+ *  English (U.S.) resources
+ ****************************************************************************/
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+/* LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US */
+#pragma code_page(1252)
+#endif /* def _WIN32 */
+
+/*
+ * File Version
+ */
+#ifndef _MAC
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_POINT,0
+ PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_POINT,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "The Privoxy team - www.privoxy.org\0"
+            VALUE "FileDescription", "Privoxy\0"
+            VALUE "FileVersion", VERSION "\0"
+            VALUE "InternalName", "Privoxy\0"
+            VALUE "LegalCopyright", "Distributed under the GNU GPL\0"
+            VALUE "OriginalFilename", "privoxy.exe\0"
+            VALUE "ProductName", "Privoxy\0"
+            VALUE "ProductVersion", VERSION "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif /* ndef _MAC */
+
+
+/*
+ * Menus
+ */
+
+IDR_TRAYMENU MENU DISCARDABLE
+BEGIN
+    POPUP "Popup"
+    BEGIN
+        MENUITEM "E&xit Privoxy",      ID_FILE_EXIT
+        MENUITEM                       SEPARATOR
+        POPUP "&Options"
+        BEGIN
+            MENUITEM "&Configuration...",           ID_TOOLS_EDITCONFIG
+            MENUITEM                                SEPARATOR
+            MENUITEM "&Actions...",                 ID_TOOLS_EDITACTIONS
+            MENUITEM "&Filters...",                 ID_TOOLS_EDITFILTERS
+#ifdef FEATURE_TRUST
+            MENUITEM "&Trust...",                   ID_TOOLS_EDITTRUST
+#endif /* def FEATURE_TRUST */
+        END
+        MENUITEM                              SEPARATOR
+#ifdef FEATURE_TOGGLE
+        MENUITEM "&Enable",                   ID_TOGGLE_ENABLED, CHECKED
+#endif /* def FEATURE_TOGGLE */
+        MENUITEM "Show Privoxy &Window",      ID_SHOWWINDOW
+    END
+END
+
+IDR_LOGVIEW MENU DISCARDABLE
+BEGIN
+    POPUP "&File"
+    BEGIN
+        MENUITEM "E&xit",                       ID_FILE_EXIT
+    END
+    POPUP "&Edit"
+    BEGIN
+        MENUITEM "Copy",                        ID_EDIT_COPY
+    END
+    POPUP "&View"
+    BEGIN
+        MENUITEM "&Clear Log",                  ID_VIEW_CLEARLOG
+        MENUITEM                                SEPARATOR
+        MENUITEM "&Log Messages",               ID_VIEW_LOGMESSAGES, CHECKED
+        MENUITEM "Message &Highlighting",       ID_VIEW_MESSAGEHIGHLIGHTING, CHECKED
+        MENUITEM "Limit &Buffer Size",          ID_VIEW_LIMITBUFFERSIZE, CHECKED
+        MENUITEM "&Activity Animation",         ID_VIEW_ACTIVITYANIMATION, CHECKED
+    END
+    POPUP "&Options"
+    BEGIN
+#ifdef FEATURE_TOGGLE
+        MENUITEM "&Enable",                     ID_TOGGLE_ENABLED, CHECKED
+        MENUITEM                                SEPARATOR
+#endif /* def FEATURE_TOGGLE */
+        MENUITEM "&Configuration...",           ID_TOOLS_EDITCONFIG
+        MENUITEM                                SEPARATOR
+        MENUITEM "&Actions...",                 ID_TOOLS_EDITACTIONS
+            MENUITEM "&Filters...",             ID_TOOLS_EDITFILTERS
+#ifdef FEATURE_TRUST
+            MENUITEM "&Trust...",               ID_TOOLS_EDITTRUST
+#endif /* def FEATURE_TRUST */
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "Privoxy &FAQ",                ID_HELP_FAQ
+        MENUITEM "Privoxy &Manual",             ID_HELP_MANUAL
+        MENUITEM "GNU &General Public Licence", ID_HELP_GPL
+        MENUITEM                                SEPARATOR
+        MENUITEM "Privoxy Status...",           ID_HELP_STATUS
+        MENUITEM                                SEPARATOR
+        MENUITEM "About Privoxy...",            ID_HELP_ABOUT
+    END
+END
+
+IDR_POPUP_SELECTION MENU DISCARDABLE
+BEGIN
+    POPUP "Popup"
+    BEGIN
+        MENUITEM "&Copy",                       ID_EDIT_COPY
+    END
+END
+
+
+/*
+ * Accelerators
+ */
+
+IDR_ACCELERATOR ACCELERATORS DISCARDABLE
+BEGIN
+    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL, NOINVERT
+END
+
+#endif /* English (U.S.) resources */
index 975c5e0..ada06b2 100644 (file)
--- a/w32log.c
+++ b/w32log.c
@@ -1,13 +1,13 @@
-const char w32log_rcs[] = "$Id: w32log.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
+const char w32log_rcs[] = "$Id: w32log.c,v 1.24 2002/03/31 17:19:00 jongfoster Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/w32log.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/w32log.c,v $
  *
  * Purpose     :  Functions for creating and destroying the log window,
  *                ouputting strings, processing messages and so on.
  *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
  *
  *                Written by and Copyright (C) 1999 Adam Lock
  *                <locka@iol.ie>
@@ -32,6 +32,121 @@ const char w32log_rcs[] = "$Id: w32log.c,v 1.1 2001/05/13 21:57:07 administrator
  *
  * Revisions   :
  *    $Log: w32log.c,v $
+ *    Revision 1.24  2002/03/31 17:19:00  jongfoster
+ *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
+ *
+ *    Revision 1.23  2002/03/26 22:57:10  jongfoster
+ *    Web server name should begin www.
+ *
+ *    Revision 1.22  2002/03/24 12:48:23  jongfoster
+ *    Fixing doc links
+ *
+ *    Revision 1.21  2002/03/24 12:07:35  jongfoster
+ *    Consistern name for filters file
+ *
+ *    Revision 1.20  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.19  2002/01/17 21:04:17  jongfoster
+ *    Replacing hard references to the URL of the config interface
+ *    with #defines from project.h
+ *
+ *    Revision 1.18  2001/11/30 23:37:24  jongfoster
+ *    Renaming the Win32 config file to config.txt - this is almost the
+ *    same as the corresponding UNIX name "config"
+ *
+ *    Revision 1.17  2001/11/16 00:46:31  jongfoster
+ *    Fixing compiler warnings
+ *
+ *    Revision 1.16  2001/08/01 19:58:12  jongfoster
+ *    Fixing documentation filenames in help menu, and making status
+ *    option work without needing the "Junkbuster Status.URL" file.
+ *
+ *    Revision 1.15  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.14  2001/07/29 18:47:05  jongfoster
+ *    Adding missing #include "loadcfg.h"
+ *
+ *    Revision 1.13  2001/07/19 19:15:14  haroon
+ *    - Added a FIXME for EditFile but didn't fix :-)
+ *
+ *    Revision 1.12  2001/07/13 14:04:59  oes
+ *    Removed all #ifdef PCRS
+ *
+ *    Revision 1.11  2001/06/07 23:08:12  jongfoster
+ *    Forward and ACL edit options removed.
+ *
+ *    Revision 1.10  2001/05/31 21:37:11  jongfoster
+ *    GUI changes to rename "permissions file" to "actions file".
+ *
+ *    Revision 1.9  2001/05/31 17:33:13  oes
+ *
+ *    CRLF -> LF
+ *
+ *    Revision 1.8  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.7  2001/05/26 01:26:34  jongfoster
+ *    New #define, WIN_GUI_EDIT, enables the (embryonic) Win32 GUI editor.
+ *    This #define cannot be set from ./configure - there's no point, it
+ *    doesn't work yet.  See feature request # 425722
+ *
+ *    Revision 1.6  2001/05/26 00:31:30  jongfoster
+ *    Fixing compiler warning about comparing signed/unsigned.
+ *
+ *    Revision 1.5  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.4  2001/05/22 18:56:28  oes
+ *    CRLF -> LF
+ *
+ *    Revision 1.3  2001/05/20 15:07:54  jongfoster
+ *    File is now ignored if _WIN_CONSOLE is defined.
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:07  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -41,18 +156,21 @@ const char w32log_rcs[] = "$Id: w32log.c,v 1.1 2001/05/13 21:57:07 administrator
 #include <assert.h>
 #include <stdio.h>
 
+#ifndef STRICT
+#define STRICT
+#endif
 #include <windows.h>
 #include <richedit.h>
 
 #include "project.h"
 #include "w32log.h"
 #include "w32taskbar.h"
-#include "w32rulesdlg.h"
 #include "win32.h"
 #include "w32res.h"
 #include "jcc.h"
 #include "miscutil.h"
 #include "errlog.h"
+#include "loadcfg.h"
 
 const char w32res_h_rcs[] = W32RES_H_VERSION;
 
@@ -63,6 +181,8 @@ const char cygwin_h_rcs[] = CYGWIN_H_VERSION;
 
 const char w32log_h_rcs[] = W32LOG_H_VERSION;
 
+#ifndef _WIN_CONSOLE /* entire file */
+
 /*
  * Timers and the various durations
  */
@@ -126,7 +246,16 @@ char g_szFontFaceName[255] = DEFAULT_LOG_FONT_NAME;
 int g_nFontSize = DEFAULT_LOG_FONT_SIZE;
 
 
-#ifdef REGEX
+/* FIXME: this is a kludge */
+
+const char * g_actions_file = NULL;
+const char * g_re_filterfile = NULL;
+#ifdef FEATURE_TRUST
+const char * g_trustfile = NULL;
+#endif /* def FEATURE_TRUST */
+
+/* FIXME: end kludge */
+
 /* Regular expression for detected URLs */
 #define RE_URL "http:[^ \n\r]*"
 
@@ -172,8 +301,6 @@ static struct _Pattern
    /* this is the terminator statement - do not delete! */
    { NULL,                  STYLE_NONE }
 };
-#endif /* def REGEX */
-
 
 /*
  * Public variables
@@ -228,14 +355,14 @@ BOOL InitLogWindow(void)
    g_hiconIdle = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_IDLE));
    for (i = 0; i < ANIM_FRAMES; i++)
    {
-      g_hiconAnim[i] = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_JUNKBUSTER1 + i));
+      g_hiconAnim[i] = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ANIMATED1 + i));
    }
-   g_hiconApp = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_JUNKBUSTER));
+   g_hiconApp = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MAINICON));
 
    /* Create the user interface */
    g_hwndLogFrame = CreateLogWindow(g_hInstance, g_nCmdShow);
    g_hwndTray = CreateTrayWindow(g_hInstance);
-   TrayAddIcon(g_hwndTray, 1, g_hiconApp, "Junkbuster");
+   TrayAddIcon(g_hwndTray, 1, g_hiconApp, "Privoxy");
 
    /* Create pattern matching buffers (for highlighting */
    LogCreatePatternMatchingBuffers();
@@ -289,14 +416,11 @@ void TermLogWindow(void)
  *********************************************************************/
 void LogCreatePatternMatchingBuffers(void)
 {
-#ifdef REGEX
    int i;
    for (i = 0; patterns_to_highlight[i].str != NULL; i++)
    {
       regcomp(&patterns_to_highlight[i].buffer, patterns_to_highlight[i].str, REG_ICASE);
    }
-#endif
-
 }
 
 
@@ -313,14 +437,11 @@ void LogCreatePatternMatchingBuffers(void)
  *********************************************************************/
 void LogDestroyPatternMatchingBuffers(void)
 {
-#ifdef REGEX
    int i;
    for (i = 0; patterns_to_highlight[i].str != NULL; i++)
    {
       regfree(&patterns_to_highlight[i].buffer);
    }
-#endif
-
 }
 
 
@@ -338,7 +459,6 @@ void LogDestroyPatternMatchingBuffers(void)
 char *LogGetURLUnderCursor(void)
 {
    char *szResult = NULL;
-#ifdef REGEX
    regex_t re;
    POINT ptCursor;
    POINTL ptl;
@@ -381,7 +501,6 @@ char *LogGetURLUnderCursor(void)
 
       regfree(&re);
    }
-#endif
    return szResult;
 
 }
@@ -392,7 +511,7 @@ char *LogGetURLUnderCursor(void)
  * Function    :  LogPutString
  *
  * Description :  Inserts text into the logging window.  This is really
- *                a REGEXP aware wrapper function to `LogPutStringNoMatch'.
+ *                a regexp aware wrapper function to `LogPutStringNoMatch'.
  *
  * Parameters  :
  *          1  :  pszText = pointer to string going to the log window
@@ -404,9 +523,7 @@ char *LogGetURLUnderCursor(void)
  *********************************************************************/
 int LogPutString(const char *pszText)
 {
-#ifdef REGEX
    int i;
-#endif
    int result = 0;
 
    if (pszText == NULL || strlen(pszText) == 0)
@@ -424,7 +541,6 @@ int LogPutString(const char *pszText)
     */
    EnterCriticalSection(&g_criticalsection);
 
-#ifdef REGEX
    if (g_bHighlightMessages)
    {
       regmatch_t match;
@@ -448,7 +564,7 @@ int LogPutString(const char *pszText)
                memset(pszBefore, 0, (match.rm_so + 1) * sizeof(char));
                strncpy(pszBefore, pszText, match.rm_so);
             }
-            if (match.rm_eo < strlen(pszText))
+            if (match.rm_eo < (regoff_t)strlen(pszText))
             {
                pszAfter = strdup(&pszText[match.rm_eo]);
             }
@@ -479,13 +595,10 @@ int LogPutString(const char *pszText)
          }
       }
    }
-#endif
 
    result = LogPutStringNoMatch(pszText, STYLE_NONE);
 
-#ifdef REGEX
 end:
-#endif
    LeaveCriticalSection(&g_criticalsection);
 
    return result;
@@ -656,7 +769,7 @@ void LogClipBuffer(void)
  *********************************************************************/
 HWND CreateHiddenLogOwnerWindow(HINSTANCE hInstance)
 {
-   static const char *szWndName = "JunkbusterLogLogOwner";
+   static const char *szWndName = "PrivoxyLogOwner";
    WNDCLASS wc;
    HWND hwnd;
 
@@ -719,12 +832,11 @@ LRESULT CALLBACK LogOwnerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
  *********************************************************************/
 HWND CreateLogWindow(HINSTANCE hInstance, int nCmdShow)
 {
-   static const char *szWndName = "JunkbusterLogWindow";
-   static const char *szWndTitle = "Junkbuster";
+   static const char *szWndName = "PrivoxyLogWindow";
+   static const char *szWndTitle = "Privoxy";
 
    HWND hwnd = NULL;
    HWND hwndOwner = (g_bShowOnTaskBar) ? NULL : CreateHiddenLogOwnerWindow(hInstance);
-   HWND hwndChild = NULL;
    RECT rcClient;
    WNDCLASSEX wc;
 
@@ -857,9 +969,11 @@ void ShowLogWindow(BOOL bShow)
  * Function    :  EditFile
  *
  * Description :  Opens the specified setting file for editing.
+ * FIXME: What if the file has no associated application. Check for return values
+*        from ShellExecute??
  *
  * Parameters  :
- *          1  :  filename = filename from the config (aka junkbstr.txt) file.
+ *          1  :  filename = filename from the config (aka config.txt) file.
  *
  * Returns     :  N/A
  *
@@ -899,7 +1013,6 @@ void OnLogRButtonUp(int nModifier, int x, int y)
    if (hMenu != NULL)
    {
       HMENU hMenuPopup = GetSubMenu(hMenu, 0);
-      char *szURL;
 
       /* Check if there is a selection */
       CHARRANGE range;
@@ -913,38 +1026,6 @@ void OnLogRButtonUp(int nModifier, int x, int y)
          EnableMenuItem(hMenuPopup, ID_EDIT_COPY, MF_BYCOMMAND | MF_ENABLED);
       }
 
-      /* Check if cursor is over a link */
-      szURL = LogGetURLUnderCursor();
-      if (szURL)
-      {
-         MENUITEMINFO item;
-         TCHAR szMenuItemTemplate[1000];
-         char *szMenuItem;
-
-         memset(&item, 0, sizeof(item));
-         item.cbSize = sizeof(item);
-         item.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
-         item.fType = MFT_STRING;
-         item.fState = MFS_ENABLED;
-         item.wID = ID_NEW_BLOCKER;
-
-         /* Put the item into the menu */
-         memset(szMenuItemTemplate, 0, sizeof(szMenuItemTemplate));
-         LoadString(g_hInstance, IDS_NEW_BLOCKER, szMenuItemTemplate, sizeof(szMenuItemTemplate) / sizeof(szMenuItemTemplate[0]));
-
-         szMenuItem = (char *)malloc(strlen(szMenuItemTemplate) + strlen(szURL) + 1);
-         sprintf(szMenuItem, szMenuItemTemplate, szURL);
-
-         item.dwTypeData = szMenuItem;
-         item.cch = strlen(szMenuItem);
-
-         InsertMenuItem(hMenuPopup, 1, TRUE, &item);
-
-         SetDefaultRule(szURL);
-
-         free(szURL);
-      }
-
       /* Display the popup */
       TrackPopupMenu(hMenuPopup, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, x, y, 0, g_hwndLogFrame, NULL);
       DestroyMenu(hMenu);
@@ -1005,9 +1086,9 @@ void OnLogCommand(int nCommand)
          /* SaveLogSettings(); */
          break;
 
-#ifdef TOGGLE
+#ifdef FEATURE_TOGGLE
       /* by haroon - change toggle to its opposite value */
-      case ID_TOGGLE_IJB:
+      case ID_TOGGLE_ENABLED:
          g_bToggleIJB = !g_bToggleIJB;
          if (g_bToggleIJB)
          {
@@ -1018,90 +1099,44 @@ void OnLogCommand(int nCommand)
             log_error(LOG_LEVEL_INFO, "Now toggled OFF.");
          }
          break;
-#endif
-
-      case ID_RELOAD_CONFIG:
-         configret = 0;
-         load_config( 1 );
-
-         if ( configret )
-         {
-            log_error(LOG_LEVEL_ERROR, "load_config encountered a problem!  You should probably restart IJB.");
-         }
-         else
-         {
-            log_error(LOG_LEVEL_INFO, "Configuration has been reloaded.");
-         }
-         break;
+#endif /* def FEATURE_TOGGLE */
 
-      case ID_TOOLS_EDITJUNKBUSTER:
+      case ID_TOOLS_EDITCONFIG:
          EditFile(configfile);
          break;
 
-      case ID_TOOLS_EDITBLOCKERS:
-         EditFile(blockfile);
-         break;
-
-      case ID_TOOLS_EDITCOOKIES:
-         EditFile(cookiefile);
-         break;
-
-      case ID_TOOLS_EDITFORWARD:
-         EditFile(forwardfile);
-         break;
-
-#ifdef ACL_FILES
-      case ID_TOOLS_EDITACLS:
-         EditFile(aclfile);
-         break;
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-      case ID_TOOLS_EDITIMAGE:
-         EditFile(imagefile);
-         break;
-#endif /* def USE_IMAGE_LIST */
-
-#ifdef PCRS
-      case ID_TOOLS_EDITPERLRE:
-         EditFile(re_filterfile);
+      case ID_TOOLS_EDITACTIONS:
+         EditFile(g_actions_file);
          break;
-#endif
 
-#ifdef KILLPOPUPS
-      case ID_TOOLS_EDITPOPUPS:
-         EditFile(popupfile);
+      case ID_TOOLS_EDITFILTERS:
+         EditFile(g_re_filterfile);
          break;
-#endif /* def KILLPOPUPS */
 
-#ifdef TRUST_FILES
+#ifdef FEATURE_TRUST
       case ID_TOOLS_EDITTRUST:
-         EditFile(trustfile);
-         break;
-#endif /* def TRUST_FILES */
-
-      case ID_NEW_BLOCKER:
-         ShowRulesDialog(g_hwndLogFrame);
+         EditFile(g_trustfile);
          break;
+#endif /* def FEATURE_TRUST */
 
       case ID_HELP_GPL:
-         ShellExecute(g_hwndLogFrame, "open", "gpl.html", NULL, NULL, SW_SHOWNORMAL);
+         ShellExecute(g_hwndLogFrame, "open", "LICENSE.txt", NULL, NULL, SW_SHOWNORMAL);
          break;
 
       case ID_HELP_FAQ:
-         ShellExecute(g_hwndLogFrame, "open", "ijbfaq.html", NULL, NULL, SW_SHOWNORMAL);
+         ShellExecute(g_hwndLogFrame, "open", "doc\\faq\\index.html", NULL, NULL, SW_SHOWNORMAL);
          break;
 
       case ID_HELP_MANUAL:
-         ShellExecute(g_hwndLogFrame, "open", "ijbman.html", NULL, NULL, SW_SHOWNORMAL);
+         ShellExecute(g_hwndLogFrame, "open", "doc\\user-manual\\index.html", NULL, NULL, SW_SHOWNORMAL);
          break;
 
       case ID_HELP_STATUS:
-         ShellExecute(g_hwndLogFrame, "open", "Junkbuster Status.URL", NULL, NULL, SW_SHOWNORMAL);
+         ShellExecute(g_hwndLogFrame, "open", CGI_PREFIX "show-status", NULL, NULL, SW_SHOWNORMAL);
          break;
 
-      case ID_HELP_ABOUTJUNKBUSTER:
-         MessageBox(g_hwndLogFrame, win32_blurb, "Junkbuster Information", MB_OK);
+      case ID_HELP_ABOUT:
+         MessageBox(g_hwndLogFrame, win32_blurb, "About Privoxy", MB_OK);
          break;
 
       default:
@@ -1128,34 +1163,21 @@ void OnLogCommand(int nCommand)
 void OnLogInitMenu(HMENU hmenu)
 {
    /* Only enable editors if there is a file to edit */
-   EnableMenuItem(hmenu, ID_TOOLS_EDITCOOKIES, MF_BYCOMMAND | (cookiefile ? MF_ENABLED : MF_GRAYED));
-   EnableMenuItem(hmenu, ID_TOOLS_EDITBLOCKERS, MF_BYCOMMAND | (blockfile ? MF_ENABLED : MF_GRAYED));
-   EnableMenuItem(hmenu, ID_TOOLS_EDITFORWARD, MF_BYCOMMAND | (forwardfile ? MF_ENABLED : MF_GRAYED));
-#ifdef ACL_FILES
-   EnableMenuItem(hmenu, ID_TOOLS_EDITACLS, MF_BYCOMMAND | (aclfile ? MF_ENABLED : MF_GRAYED));
-#endif /* def ACL_FILES */
-#ifdef USE_IMAGE_LIST
-   EnableMenuItem(hmenu, ID_TOOLS_EDITIMAGE, MF_BYCOMMAND | (imagefile ? MF_ENABLED : MF_GRAYED));
-#endif /* def USE_IMAGE_LIST */
-#ifdef KILLPOPUPS
-   EnableMenuItem(hmenu, ID_TOOLS_EDITPOPUPS, MF_BYCOMMAND | (popupfile ? MF_ENABLED : MF_GRAYED));
-#endif /* def KILLPOPUPS */
-#ifdef PCRS
-   EnableMenuItem(hmenu, ID_TOOLS_EDITPERLRE, MF_BYCOMMAND | (re_filterfile ? MF_ENABLED : MF_GRAYED));
-#endif
-#ifdef TRUST_FILES
-   EnableMenuItem(hmenu, ID_TOOLS_EDITTRUST, MF_BYCOMMAND | (trustfile ? MF_ENABLED : MF_GRAYED));
-#endif /* def TRUST_FILES */
+   EnableMenuItem(hmenu, ID_TOOLS_EDITACTIONS, MF_BYCOMMAND | (g_actions_file ? MF_ENABLED : MF_GRAYED));
+   EnableMenuItem(hmenu, ID_TOOLS_EDITFILTERS, MF_BYCOMMAND | (g_re_filterfile ? MF_ENABLED : MF_GRAYED));
+#ifdef FEATURE_TRUST
+   EnableMenuItem(hmenu, ID_TOOLS_EDITTRUST, MF_BYCOMMAND | (g_trustfile ? MF_ENABLED : MF_GRAYED));
+#endif /* def FEATURE_TRUST */
 
    /* Check/uncheck options */
    CheckMenuItem(hmenu, ID_VIEW_LOGMESSAGES, MF_BYCOMMAND | (g_bLogMessages ? MF_CHECKED : MF_UNCHECKED));
    CheckMenuItem(hmenu, ID_VIEW_MESSAGEHIGHLIGHTING, MF_BYCOMMAND | (g_bHighlightMessages ? MF_CHECKED : MF_UNCHECKED));
    CheckMenuItem(hmenu, ID_VIEW_LIMITBUFFERSIZE, MF_BYCOMMAND | (g_bLimitBufferSize ? MF_CHECKED : MF_UNCHECKED));
    CheckMenuItem(hmenu, ID_VIEW_ACTIVITYANIMATION, MF_BYCOMMAND | (g_bShowActivityAnimation ? MF_CHECKED : MF_UNCHECKED));
-#ifdef TOGGLE
+#ifdef FEATURE_TOGGLE
    /* by haroon - menu item for Enable toggle on/off */
-   CheckMenuItem(hmenu, ID_TOGGLE_IJB, MF_BYCOMMAND | (g_bToggleIJB ? MF_CHECKED : MF_UNCHECKED));
-#endif
+   CheckMenuItem(hmenu, ID_TOGGLE_ENABLED, MF_BYCOMMAND | (g_bToggleIJB ? MF_CHECKED : MF_UNCHECKED));
+#endif /* def FEATURE_TOGGLE */
 
 }
 
@@ -1313,6 +1335,7 @@ LRESULT CALLBACK LogWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara
 
 }
 
+#endif /* ndef _WIN_CONSOLE - entire file */
 
 /*
   Local Variables:
index 85b4375..2634a95 100644 (file)
--- a/w32log.h
+++ b/w32log.h
@@ -1,15 +1,15 @@
-#ifndef _W32LOG_H
-#define _W32LOG_H
-#define W32LOG_H_VERSION "$Id: w32log.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
+#ifndef W32LOG_H_INCLUDED
+#define W32LOG_H_INCLUDED
+#define W32LOG_H_VERSION "$Id: w32log.h,v 1.9 2002/03/24 12:03:47 jongfoster Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/w32log.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/w32log.h,v $
  *
  * Purpose     :  Functions for creating and destroying the log window,
  *                ouputting strings, processing messages and so on.
  *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
  *
  *                Written by and Copyright (C) 1999 Adam Lock
  *                <locka@iol.ie>
  *
  * Revisions   :
  *    $Log: w32log.h,v $
+ *    Revision 1.9  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.8  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.7  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.6  2001/07/13 14:04:59  oes
+ *    Removed all #ifdef PCRS
+ *
+ *    Revision 1.5  2001/06/07 23:08:12  jongfoster
+ *    Forward and ACL edit options removed.
+ *
+ *    Revision 1.4  2001/05/31 21:37:11  jongfoster
+ *    GUI changes to rename "permissions file" to "actions file".
+ *
+ *    Revision 1.3  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.2  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:07  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -72,6 +127,16 @@ extern char g_szFontFaceName[255];
 extern int g_nFontSize;
 
 
+/* FIXME: this is a kludge */
+
+extern const char * g_actions_file;
+extern const char * g_re_filterfile;
+#ifdef FEATURE_TRUST
+extern const char * g_trustfile;
+#endif /* def FEATURE_TRUST */
+
+/* FIXME: end kludge */
+
 extern int LogPutString(const char *pszText);
 extern BOOL InitLogWindow(void);
 extern void TermLogWindow(void);
@@ -86,7 +151,7 @@ extern const char w32log_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _W32LOG_H */
+#endif /* ndef W32LOG_H_INCLUDED */
 
 
 /*
index 7fb57b6..62308cf 100644 (file)
--- a/w32res.h
+++ b/w32res.h
@@ -1,14 +1,14 @@
-#ifndef _W32RES_H
-#define _W32RES_H
-#define W32RES_H_VERSION "$Id: w32res.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
+#ifndef W32RES_H_INCLUDED
+#define W32RES_H_INCLUDED
+#define W32RES_H_VERSION "$Id: w32res.h,v 1.12 2002/03/24 12:07:36 jongfoster Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/w32res.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/w32res.h,v $
  *
  * Purpose     :  Identifiers for Windows GUI resources.
  *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and 
  *
  * Revisions   :
  *    $Log: w32res.h,v $
+ *    Revision 1.12  2002/03/24 12:07:36  jongfoster
+ *    Consistern name for filters file
+ *
+ *    Revision 1.11  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.10  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.9  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.8  2001/07/13 14:04:59  oes
+ *    Removed all #ifdef PCRS
+ *
+ *    Revision 1.7  2001/06/07 23:08:12  jongfoster
+ *    Forward and ACL edit options removed.
+ *
+ *    Revision 1.6  2001/05/31 21:37:11  jongfoster
+ *    GUI changes to rename "permissions file" to "actions file".
+ *
+ *    Revision 1.5  2001/05/29 09:50:24  jongfoster
+ *    Unified blocklist/imagelist/permissionslist.
+ *    File format is still under discussion, but the internal changes
+ *    are (mostly) done.
+ *
+ *    Also modified interceptor behaviour:
+ *    - We now intercept all URLs beginning with one of the following
+ *      prefixes (and *only* these prefixes):
+ *        * http://i.j.b/
+ *        * http://ijbswa.sf.net/config/
+ *        * http://ijbswa.sourceforge.net/config/
+ *    - New interceptors "home page" - go to http://i.j.b/ to see it.
+ *    - Internal changes so that intercepted and fast redirect pages
+ *      are not replaced with an image.
+ *    - Interceptors now have the option to send a binary page direct
+ *      to the client. (i.e. ijb-send-banner uses this)
+ *    - Implemented show-url-info interceptor.  (Which is why I needed
+ *      the above interceptors changes - a typical URL is
+ *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
+ *      The previous mechanism would not have intercepted that, and
+ *      if it had been intercepted then it then it would have replaced
+ *      it with an image.)
+ *
+ *    Revision 1.4  2001/05/26 01:26:34  jongfoster
+ *    New #define, WIN_GUI_EDIT, enables the (embryonic) Win32 GUI editor.
+ *    This #define cannot be set from ./configure - there's no point, it
+ *    doesn't work yet.  See feature request # 425722
+ *
+ *    Revision 1.3  2001/05/26 00:28:36  jongfoster
+ *    Automatic reloading of config file.
+ *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
+ *    Most of the global variables have been moved to a new
+ *    struct configuration_spec, accessed through csp->config->globalname
+ *    Most of the globals remaining are used by the Win32 GUI.
+ *
+ *    Revision 1.2  2001/05/20 01:21:20  jongfoster
+ *    Version 2.9.4 checkin.
+ *    - Merged popupfile and cookiefile, and added control over PCRS
+ *      filtering, in new "permissionsfile".
+ *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
+ *      file error you now get a message box (in the Win32 GUI) rather
+ *      than the program exiting with no explanation.
+ *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
+ *      skipping.
+ *    - Removed tabs from "config"
+ *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
+ *    - Bumped up version number.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:08  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 
-#define IDS_NEW_BLOCKER                   1
-
-#define ID_NEW_BLOCKER                    100
 #define IDR_TRAYMENU                      101
 #define IDI_IDLE                          102
 #define IDR_LOGVIEW                       103
 #define IDR_ACCELERATOR                   104
 #define IDR_POPUP_SELECTION               105
-#define IDD_RULES                         106
-#define IDI_DENYRULE                      107
-#define IDI_ALLOWRULE                     108
 
-#define IDI_JUNKBUSTER                    200
-#define IDI_JUNKBUSTER1                   201
-#define IDI_JUNKBUSTER2                   202
-#define IDI_JUNKBUSTER3                   203
-#define IDI_JUNKBUSTER4                   204
-#define IDI_JUNKBUSTER5                   205
-#define IDI_JUNKBUSTER6                   206
-#define IDI_JUNKBUSTER7                   207
-#define IDI_JUNKBUSTER8                   208
 
-#define IDC_NEW                           300
-#define IDC_ACTION                        301
-#define IDC_RULES                         302
-#define IDC_CREATE                        303
-#define IDC_MOVEUP                        304
-#define IDC_MOVEDOWN                      305
-#define IDC_DELETE                        306
-#define IDC_SAVE                          307
+#define IDI_MAINICON                      200
+#define IDI_ANIMATED1                     201
+#define IDI_ANIMATED2                     202
+#define IDI_ANIMATED3                     203
+#define IDI_ANIMATED4                     204
+#define IDI_ANIMATED5                     205
+#define IDI_ANIMATED6                     206
+#define IDI_ANIMATED7                     207
+#define IDI_ANIMATED8                     208
 
 #define ID_SHOWWINDOW                     4000
-#define ID_HELP_ABOUTJUNKBUSTER           4001
+#define ID_HELP_ABOUT                     4001
 #define ID_FILE_EXIT                      4002
 #define ID_VIEW_CLEARLOG                  4003
 #define ID_VIEW_LOGMESSAGES               4004
 #define ID_HELP_MANUAL                    4009
 #define ID_HELP_GPL                       4010
 #define ID_HELP_STATUS                    4011
-#ifdef TOGGLE
-#define ID_TOGGLE_IJB                     4012
-#endif
-#define ID_RELOAD_CONFIG                  4013
+#ifdef FEATURE_TOGGLE
+#define ID_TOGGLE_ENABLED                 4012
+#endif /* def FEATURE_TOGGLE */
 
 /* Break these out so they are easier to extend, but keep consecutive */
-#define ID_TOOLS_EDITJUNKBUSTER           5000
-#define ID_TOOLS_EDITBLOCKERS             5001
-#define ID_TOOLS_EDITCOOKIES              5002
-#define ID_TOOLS_EDITFORWARD              5003
-
-#ifdef ACL_FILES
-#define ID_TOOLS_EDITACLS                 5005
-#endif /* def ACL_FILES */
-
-#ifdef USE_IMAGE_LIST
-#define ID_TOOLS_EDITIMAGE                5006
-#endif /* def USE_IMAGE_LIST */
-
-#ifdef KILLPOPUPS
-#define ID_TOOLS_EDITPOPUPS               5007
-#endif /* def KILLPOPUPS */
-
-#ifdef PCRS
-#define ID_TOOLS_EDITPERLRE               5008
-#endif /* def PCRS */
+#define ID_TOOLS_EDITCONFIG               5000
+#define ID_TOOLS_EDITACTIONS              5001
+#define ID_TOOLS_EDITFILTERS              5002
 
-#ifdef TRUST_FILES
-#define ID_TOOLS_EDITTRUST                5004
-#endif /* def TRUST_FILES */
+#ifdef FEATURE_TRUST
+#define ID_TOOLS_EDITTRUST                5003
+#endif /* def FEATURE_TRUST */
 
 /*
  * The following symbols are declared in <afxres.h> in VC++.
 #define ID_EDIT_COPY  30000
 
 
-#endif /* ndef _W32RES_H */
+#endif /* ndef W32RES_H_INCLUDED */
 
 /*
   Local Variables:
diff --git a/w32rulesdlg.c b/w32rulesdlg.c
deleted file mode 100644 (file)
index 845995b..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-const char w32rulesdlg_rcs[] = "$Id: w32rulesdlg.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
-/*********************************************************************
- *
- * File        :  $Source: /home/administrator/cvs/ijb/w32rulesdlg.c,v $
- *
- * Purpose     :  A dialog to allow GUI editing of the rules.
- *                Unfinished.
- *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
- *
- *                Written by and Copyright (C) 1999 Adam Lock
- *                <locka@iol.ie>
- *
- *                This program is free software; you can redistribute it 
- *                and/or modify it under the terms of the GNU General
- *                Public License as published by the Free Software
- *                Foundation; either version 2 of the License, or (at
- *                your option) any later version.
- *
- *                This program is distributed in the hope that it will
- *                be useful, but WITHOUT ANY WARRANTY; without even the
- *                implied warranty of MERCHANTABILITY or FITNESS FOR A
- *                PARTICULAR PURPOSE.  See the GNU General Public
- *                License for more details.
- *
- *                The GNU General Public License should be included with
- *                this file.  If not, you can view it at
- *                http://www.gnu.org/copyleft/gpl.html
- *                or write to the Free Software Foundation, Inc., 59
- *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Revisions   :
- *    $Log: w32rulesdlg.c,v $
- *
- *********************************************************************/
-\f
-#include "config.h"
-
-#include <stdio.h>
-
-#include <windows.h>
-#include <commctrl.h>
-
-#include "w32res.h"
-#include "w32rulesdlg.h"
-#include "win32.h"
-
-#ifdef __MINGW32__
-#include "cygwin.h"
-#endif
-
-const char w32rulesdlg_h_rcs[] = W32RULESDLG_H_VERSION;
-
-const int nSmallIconWidth = 16;
-const int nSmallIconHeight = 16;
-
-static BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
-static HIMAGELIST g_hImageList = NULL;
-static char *g_pszDefaultRule;
-static BOOL g_bDirty = FALSE;
-
-
-
-/*********************************************************************
- *
- * Function    :  ShowRulesDialog
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndParent = (what?)
- *
- * Returns     :  (Please fill me in!)
- *
- *********************************************************************/
-int ShowRulesDialog(HWND hwndParent)
-{
-   DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_RULES), hwndParent, DialogProc);
-   return TRUE;
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  SetDefaultRule
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  pszRule = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-void SetDefaultRule(const char *pszRule)
-{
-   if (pszRule == NULL)
-   {
-      if (g_pszDefaultRule)
-      {
-         free(g_pszDefaultRule);
-         g_pszDefaultRule = NULL;
-      }
-   }
-   else
-   {
-      g_pszDefaultRule = strdup(pszRule);
-   }
-
-}
-
-
-#define IMAGE_ALLOW 0
-#define IMAGE_DENY  1
-
-/*********************************************************************
- *
- * Function    :  InsertRule
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndListView = (what?)
- *          2  :  pszRule = (what?)
- *          3  :  bAllow = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void InsertRule(HWND hwndListView, const char *pszRule, BOOL bAllow)
-{
-   LVITEM item;
-   item.mask = LVIF_TEXT | LVIF_IMAGE;
-   item.pszText = (char *)pszRule;
-   item.iItem = ListView_GetItemCount(hwndListView) + 1;
-   item.iSubItem = 0;
-   item.iImage = bAllow ? IMAGE_ALLOW : IMAGE_DENY;
-   ListView_InsertItem(hwndListView, &item);
-   /* TODO add subitem for whether the rule is always or never */
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  SetDirty
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  bDirty = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void SetDirty(BOOL bDirty)
-{
-   g_bDirty = bDirty;
-   /* TODO Change some values */
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnInitDialog
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnInitDialog(HWND hwndDlg)
-{
-   LVCOLUMN aCols[2];
-   HWND hwndListView;
-   RECT rcListView;
-   int cx;
-
-   if (g_hImageList == NULL)
-   {
-      /* Create image list and add icons */
-      HICON hIconDeny = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_DENYRULE), IMAGE_ICON, nSmallIconWidth, nSmallIconHeight, 0);
-      HICON hIconAllow = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ALLOWRULE), IMAGE_ICON, nSmallIconWidth, nSmallIconHeight, 0);
-      g_hImageList = ImageList_Create(nSmallIconWidth, nSmallIconHeight, ILC_COLOR | ILC_MASK, 0, 10);
-      ImageList_AddIcon(g_hImageList, hIconAllow);
-      ImageList_AddIcon(g_hImageList, hIconDeny);
-   }
-
-   /* Set the default rule value if there is one */
-   if (g_pszDefaultRule)
-   {
-      SetDlgItemText(hwndDlg, IDC_NEW, g_pszDefaultRule);
-      SetDefaultRule(NULL);
-   }
-
-   /* Initialise the list view */
-   hwndListView = GetDlgItem(hwndDlg, IDC_RULES);
-   ListView_SetImageList(hwndListView, g_hImageList, LVSIL_SMALL);
-   GetClientRect(hwndListView, &rcListView);
-   cx = rcListView.right - rcListView.left;
-   aCols[0].mask = LVCF_TEXT | LVCF_WIDTH;
-   aCols[0].pszText = "Rule";
-   aCols[0].cx = (70 * cx) / 100;
-   aCols[1].mask = LVCF_TEXT | LVCF_WIDTH;
-   aCols[1].pszText = "Applies when";
-   aCols[1].cx = cx - aCols[0].cx;
-   ListView_InsertColumn(hwndListView, 0, &aCols[0]);
-   ListView_InsertColumn(hwndListView, 1, &aCols[1]);
-
-   /* Read and add rules to the list */
-   /* TODO */
-   InsertRule(hwndListView, "Test rule 1", TRUE);
-   InsertRule(hwndListView, "Test rule 2", TRUE);
-   InsertRule(hwndListView, "Test rule 3", FALSE);
-   InsertRule(hwndListView, "Test rule 4", FALSE);
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  GetFirstSelectedItem
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  (Please fill me in!)
- *
- *********************************************************************/
-static int GetFirstSelectedItem(HWND hwndDlg)
-{
-   /* Check for selected items */
-   HWND hwndListView = GetDlgItem(hwndDlg, IDC_RULES);
-   int nItem = -1;
-   do
-   {
-      nItem = ListView_GetNextItem(hwndListView, nItem, LVNI_SELECTED);
-      if (nItem >= 0)
-      {
-         return nItem;
-      }
-   } while (nItem >= 0);
-   return -1;
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnRulesItemChanged
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnRulesItemChanged(HWND hwndDlg)
-{
-   int nItem = GetFirstSelectedItem(hwndDlg);
-   HWND hwndListView = GetDlgItem(hwndDlg, IDC_RULES);
-   int nItems = ListView_GetItemCount(hwndListView);
-   BOOL bHaveSelection = (nItem >= 0) ? TRUE : FALSE;
-   BOOL bMoveUp = (bHaveSelection && nItem > 0) ? TRUE : FALSE;
-   BOOL bMoveDown = (bHaveSelection && nItem < nItems - 1) ? TRUE : FALSE;
-
-   /* Enable/disable buttons */
-   EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), bHaveSelection);
-   EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEUP), bMoveUp);
-   EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEDOWN), bMoveDown);
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  MoveRules
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *          2  :  bMoveUp = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void MoveRules(HWND hwndDlg, BOOL bMoveUp)
-{
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnMoveRuleUpClick
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnMoveRuleUpClick(HWND hwndDlg)
-{
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnMoveRuleDownClick
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnMoveRuleDownClick(HWND hwndDlg)
-{
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnCreateRuleClick
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnCreateRuleClick(HWND hwndDlg)
-{
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnDeleteRuleClick
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnDeleteRuleClick(HWND hwndDlg)
-{
-   /* Get selection and remove it */
-   int nItem = GetFirstSelectedItem(hwndDlg);
-   if (nItem >= 0)
-   {
-      LVITEM item;
-      HWND hwndListView = GetDlgItem(hwndDlg, IDC_RULES);
-      item.mask = LVIF_PARAM;
-      item.iItem = nItem;
-      item.iSubItem = 0;
-      ListView_GetItem(hwndListView, &item);
-      /* TODO erase data stored with item */
-      ListView_DeleteItem(hwndListView, nItem);
-   }
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnCommand
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *          2  :  nCommand = (what?)
- *          3  :  nNotifyCode = (what?)
- *          4  :  hwndItem = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnCommand(HWND hwndDlg, int nCommand, int nNotifyCode, HWND hwndItem)
-{
-   switch (nCommand)
-   {
-      case IDCANCEL:
-      case IDC_SAVE:
-         EndDialog(hwndDlg, IDOK);
-         break;
-      case IDC_CREATE:
-         if (nNotifyCode == BN_CLICKED)
-         {
-            OnCreateRuleClick(hwndDlg);
-         }
-         break;
-      case IDC_DELETE:
-         if (nNotifyCode == BN_CLICKED)
-         {
-            OnDeleteRuleClick(hwndDlg);
-         }
-         break;
-      case IDC_MOVEUP:
-         if (nNotifyCode == BN_CLICKED)
-         {
-            OnMoveRuleUpClick(hwndDlg);
-         }
-         break;
-      case IDC_MOVEDOWN:
-         if (nNotifyCode == BN_CLICKED)
-         {
-            OnMoveRuleDownClick(hwndDlg);
-         }
-         break;
-   }
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnNotify
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *          2  :  nIdCtrl = (what?)
- *          3  :  pnmh = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnNotify(HWND hwndDlg, int nIdCtrl, LPNMHDR pnmh)
-{
-   switch (nIdCtrl)
-   {
-      case IDC_RULES:
-         switch (pnmh->code)
-         {
-            case LVN_ITEMCHANGED:
-               OnRulesItemChanged(hwndDlg);
-               break;
-         }
-         break;
-   }
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  OnDestroy
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-static void OnDestroy(HWND hwndDlg)
-{
-   /* TODO any destruction cleanup */
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  DialogProc
- *
- * Description :  (Please fill me in!)
- *
- * Parameters  :
- *          1  :  hwndDlg = (what?)
- *          2  :  uMsg = (what?)
- *          3  :  wParam = (what?)
- *          4  :  lParam = (what?)
- *
- * Returns     :  (Please fill me in!)
- *
- *********************************************************************/
-static BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
-   switch (uMsg)
-   {
-      case WM_INITDIALOG:
-         OnInitDialog(hwndDlg);
-         return TRUE;
-
-      case WM_DESTROY:
-         OnDestroy(hwndDlg);
-         return TRUE;
-
-      case WM_COMMAND:
-         OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND) lParam);
-         break;
-
-      case WM_NOTIFY:
-         OnNotify(hwndDlg, (int) wParam, (LPNMHDR) lParam);
-         break;
-   }
-   return FALSE;
-
-}
-
-
-/*
-  Local Variables:
-  tab-width: 3
-  end:
-*/
diff --git a/w32rulesdlg.h b/w32rulesdlg.h
deleted file mode 100644 (file)
index 991a8bd..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef _W32RULESDLG_H
-#define _W32RULESDLG_H
-#define W32RULESDLG_H_VERSION "$Id: w32rulesdlg.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
-/*********************************************************************
- *
- * File        :  $Source: /home/administrator/cvs/ijb/w32rulesdlg.h,v $
- *
- * Purpose     :  A dialog to allow GUI editing of the rules.
- *                Unfinished.
- *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
- *
- *                Written by and Copyright (C) 1999 Adam Lock
- *                <locka@iol.ie>
- *
- *                This program is free software; you can redistribute it 
- *                and/or modify it under the terms of the GNU General
- *                Public License as published by the Free Software
- *                Foundation; either version 2 of the License, or (at
- *                your option) any later version.
- *
- *                This program is distributed in the hope that it will
- *                be useful, but WITHOUT ANY WARRANTY; without even the
- *                implied warranty of MERCHANTABILITY or FITNESS FOR A
- *                PARTICULAR PURPOSE.  See the GNU General Public
- *                License for more details.
- *
- *                The GNU General Public License should be included with
- *                this file.  If not, you can view it at
- *                http://www.gnu.org/copyleft/gpl.html
- *                or write to the Free Software Foundation, Inc., 59
- *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * Revisions   :
- *    $Log: w32rulesdlg.h,v $
- *
- *********************************************************************/
-\f
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int ShowRulesDialog(HWND hwndParent);
-extern void SetDefaultRule(const char *pszRule);
-
-/* Revision control strings from this header and associated .c file */
-extern const char w32rulesdlg_rcs[];
-extern const char w32rulesdlg_h_rcs[];
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* ndef _W32RULESDLG_H */
-
-
-/*
-  Local Variables:
-  tab-width: 3
-  end:
-*/
index 62f269d..721ad08 100644 (file)
@@ -1,13 +1,13 @@
-const char w32taskbar_rcs[] = "$Id: w32taskbar.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
+const char w32taskbar_rcs[] = "$Id: w32taskbar.c,v 1.6 2002/03/26 22:57:10 jongfoster Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/w32taskbar.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/w32taskbar.c,v $
  *
  * Purpose     :  Functions for creating, setting and destroying the
  *                workspace tray icon
  *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
  *
  *                Written by and Copyright (C) 1999 Adam Lock
  *                <locka@iol.ie>
@@ -32,6 +32,24 @@ const char w32taskbar_rcs[] = "$Id: w32taskbar.c,v 1.1 2001/05/13 21:57:07 admin
  *
  * Revisions   :
  *    $Log: w32taskbar.c,v $
+ *    Revision 1.6  2002/03/26 22:57:10  jongfoster
+ *    Web server name should begin www.
+ *
+ *    Revision 1.5  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.4  2001/11/16 00:46:31  jongfoster
+ *    Fixing compiler warnings
+ *
+ *    Revision 1.3  2001/05/22 18:56:28  oes
+ *    CRLF -> LF
+ *
+ *    Revision 1.2  2001/05/20 15:07:54  jongfoster
+ *    File is now ignored if _WIN_CONSOLE is defined.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:08  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -40,6 +58,9 @@ const char w32taskbar_rcs[] = "$Id: w32taskbar.c,v 1.1 2001/05/13 21:57:07 admin
 
 #include <stdio.h>
 
+#ifndef STRICT
+#define STRICT
+#endif
 #include <windows.h>
 
 #include "w32taskbar.h"
@@ -48,6 +69,8 @@ const char w32taskbar_rcs[] = "$Id: w32taskbar.c,v 1.1 2001/05/13 21:57:07 admin
 
 const char w32taskbar_h_rcs[] = W32TASKBAR_H_VERSION;
 
+#ifndef _WIN_CONSOLE /* entire file */
+
 #define WM_TRAYMSG WM_USER+1
 
 static HMENU g_hmenuTray;
@@ -60,7 +83,8 @@ static LRESULT CALLBACK TrayProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar
  *
  * Function    :  CreateTrayWindow
  *
- * Description :  Creates and returns the invisible window responsible for processing tray messages.
+ * Description :  Creates and returns the invisible window responsible
+ *                for processing tray messages.
  *
  * Parameters  :
  *          1  :  hInstance = instance handle of this application
@@ -71,7 +95,7 @@ static LRESULT CALLBACK TrayProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar
 HWND CreateTrayWindow(HINSTANCE hInstance)
 {
    WNDCLASS wc;
-   static const char *szWndName = "JunkbusterTrayWindow";
+   static const char *szWndName = "PrivoxyTrayWindow";
 
    wc.style          = 0;
    wc.lpfnWndProc    = TrayProc;
@@ -226,7 +250,7 @@ LRESULT CALLBACK TrayProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
       case WM_TRAYMSG:
       {
-         UINT uID = (UINT) wParam;
+         /* UINT uID = (UINT) wParam; */
          UINT uMouseMsg = (UINT) lParam;
 
          if (uMouseMsg == WM_RBUTTONDOWN)
@@ -255,6 +279,8 @@ LRESULT CALLBACK TrayProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 }
 
 
+#endif /* ndef _WIN_CONSOLE - entire file */
+
 /*
   Local Variables:
   tab-width: 3
index 9ba21fb..1945061 100644 (file)
@@ -1,15 +1,15 @@
-#ifndef _W32TASKBAR_H
-#define _W32TASKBAR_H
-#define W32TASKBAR_H_VERSION "$Id: w32taskbar.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
+#ifndef W32TASKBAR_H_INCLUDED
+#define W32TASKBAR_H_INCLUDED
+#define W32TASKBAR_H_VERSION "$Id: w32taskbar.h,v 1.3 2002/03/24 12:03:47 jongfoster Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/w32taskbar.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/w32taskbar.h,v $
  *
  * Purpose     :  Functions for creating, setting and destroying the
  *                workspace tray icon
  *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
  *
  *                Written by and Copyright (C) 1999 Adam Lock
  *                <locka@iol.ie>
  *
  * Revisions   :
  *    $Log: w32taskbar.h,v $
+ *    Revision 1.3  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.2  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:08  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -55,7 +65,7 @@ extern const char w32taskbar_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _W32TASKBAR_H */
+#endif /* ndef W32TASKBAR_H_INCLUDED */
 
 
 /*
diff --git a/win32.c b/win32.c
index 2252dc1..9db1ed1 100644 (file)
--- a/win32.c
+++ b/win32.c
@@ -1,12 +1,12 @@
-const char win32_rcs[] = "$Id: win32.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
+const char win32_rcs[] = "$Id: win32.c,v 1.8 2002/03/26 22:57:10 jongfoster Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/win32.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/win32.c,v $
  *
  * Purpose     :  Win32 User Interface initialization and message loop
  *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
  *
  *                Written by and Copyright (C) 1999 Adam Lock
  *                <locka@iol.ie>
@@ -31,6 +31,31 @@ const char win32_rcs[] = "$Id: win32.c,v 1.1 2001/05/13 21:57:07 administrator E
  *
  * Revisions   :
  *    $Log: win32.c,v $
+ *    Revision 1.8  2002/03/26 22:57:10  jongfoster
+ *    Web server name should begin www.
+ *
+ *    Revision 1.7  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.6  2002/03/16 21:53:28  jongfoster
+ *    VC++ Heap debug option
+ *
+ *    Revision 1.5  2002/03/04 23:47:30  jongfoster
+ *    - Rewritten, simpler command-line pre-parser
+ *    - not using raise(SIGINT) any more
+ *
+ *    Revision 1.4  2001/11/30 21:29:33  jongfoster
+ *    Fixing a warning
+ *
+ *    Revision 1.3  2001/11/16 00:46:31  jongfoster
+ *    Fixing compiler warnings
+ *
+ *    Revision 1.2  2001/07/29 19:32:00  jongfoster
+ *    Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:08  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -43,30 +68,39 @@ const char win32_rcs[] = "$Id: win32.c,v 1.1 2001/05/13 21:57:07 administrator E
 
 #include "project.h"
 #include "jcc.h"
+#include "miscutil.h"
 
 /* Uncomment this if you want to build Win32 as a console app */
 /* #define _WIN_CONSOLE */
 
+#ifndef STRICT
+#define STRICT
+#endif
 #include <windows.h>
 
 #include <stdarg.h>
 #include <process.h>
 
+#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
+/* Visual C++ Heap debugging */
+#include <crtdbg.h>
+#endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */
+
 #include "win32.h"
 
 const char win32_h_rcs[] = WIN32_H_VERSION;
 
 const char win32_blurb[] =
-"Internet Junkbuster Proxy(TM) Version " VERSION " for Windows is Copyright (C) 1997-8\n"
-"by Junkbusters Corp.  This is free software; it may be used and copied under\n"
-"the GNU General Public License: http://www.gnu.org/copyleft/gpl.html .\n"
+"Privoxy version " VERSION " for Windows\n"
+"Copyright (C) 2000-2002 by members of the Privoxy Team\n"
+"Copyright (C) 1997-8 by Junkbusters Corp.\n"
+"This is free software; it may be used and copied under the\n"
+"GNU General Public License: http://www.gnu.org/copyleft/gpl.html .\n"
 "This program comes with ABSOLUTELY NO WARRANTY OF ANY KIND.\n"
 "\n"
 "For information about how to to configure the proxy and your browser, see\n"
-"        " REDIRECT_URL "win\n"
-"\n"
-"The Internet Junkbuster Proxy(TM) is running and ready to serve!\n"
-"";
+"        " HOME_PAGE_URL "\n"
+"\n";
 
 #ifdef _WIN_CONSOLE
 
@@ -89,12 +123,12 @@ static void  __cdecl UserInterfaceThread(void *);
  * Description :  M$ Windows "main" routine:
  *                parse the `lpCmdLine' param into main's argc and argv variables,
  *                start the user interface thread (for the systray window), and
- *                call main (i.e. patch execution into normal IJB startup).
+ *                call main (i.e. patch execution into normal startup).
  *
  * Parameters  :
- *          1  :  hInstance = instance handle of this IJB execution
- *          2  :  hPrevInstance = instance handle of previous IJB execution
- *          3  :  lpCmdLine = command line string which started IJB
+ *          1  :  hInstance = instance handle of this execution
+ *          2  :  hPrevInstance = instance handle of previous execution
+ *          3  :  lpCmdLine = command line string which started us
  *          4  :  nCmdShow = window show value (MIN, MAX, NORMAL, etc...)
  *
  * Returns     :  `main' never returns, so WinMain will also never return.
@@ -102,56 +136,64 @@ static void  __cdecl UserInterfaceThread(void *);
  *********************************************************************/
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 {
-   int argc = 0;
    int i;
    int res;
-   char **argv = NULL;
-   char *pszArgs = NULL;
-   char *pszLastTok;
+   int argc = 1;
+   const char *argv[3];
    char szModule[MAX_PATH+1];
 #ifndef _WIN_CONSOLE
    HANDLE hInitCompleteEvent = NULL;
 #endif
 
-   /* Split command line into arguments */
-   pszArgs = (char *)malloc(strlen(lpCmdLine) + 1);
-   strcpy(pszArgs, lpCmdLine);
 
-   GetModuleFileName(hInstance, szModule, MAX_PATH);
+#if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
+#if 0
+   /* Visual C++ Heap debugging */
 
-   /* Count number of spaces */
-   argc = 1;
-   if (strlen(pszArgs) > 0)
-   {
-      pszLastTok = pszArgs;
-      do
-      {
-         argc++;
-         pszLastTok = strchr(pszLastTok+1, ' ');
-      } while (pszLastTok);
-   }
+   /* Get current flag*/
+   int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
 
-   /* Allocate array of strings */
-   argv = (char **)malloc(sizeof(char *) * argc);
+   /* Turn on leak-checking bit */
+   tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF;
 
-   /* step through command line replacing spaces with zeros, initialise array */
-   argv[0] = szModule;
-   i = 1;
-   pszLastTok = pszArgs;
-   do
+   /* Turn off CRT block checking bit */
+   tmpFlag &= ~(_CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF);
+
+   /* Set flag to the new value */
+   _CrtSetDbgFlag( tmpFlag );
+#endif
+#endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */
+
+   /*
+    * Cheat in parsing the command line.  We only ever have at most one
+    * paramater, which may optionally be specified inside double quotes.
+    */
+
+   if (lpCmdLine != NULL)
+   {
+      /* Make writable copy */
+      lpCmdLine = strdup(lpCmdLine);
+   }
+   if (lpCmdLine != NULL)
    {
-      argv[i] = pszLastTok;
-      pszLastTok = strchr(pszLastTok+1, ' ');
-      if (pszLastTok)
+      chomp(lpCmdLine);
+      i = strlen(lpCmdLine);
+      if ((i >= 2) && (lpCmdLine[0] == '\"') && (lpCmdLine[i - 1] == '\"'))
       {
-         while (*pszLastTok != '\0' && *pszLastTok == ' ')
-         {
-            *pszLastTok = '\0';
-            pszLastTok++;
-         }
+         lpCmdLine[i - 1] = '\0';
+         lpCmdLine++;
       }
-      i++;
-   } while (pszLastTok && *pszLastTok != '\0');
+      if (lpCmdLine[0] == '\0')
+      {
+         lpCmdLine = NULL;
+      }
+   }
+
+   GetModuleFileName(hInstance, szModule, MAX_PATH);
+   argv[0] = szModule;
+   argv[1] = lpCmdLine;
+   argv[2] = NULL;
+   argc = ((lpCmdLine != NULL) ? 2 : 1);
 
 #ifndef _WIN_CONSOLE
    /* Create a user-interface thread and wait for it to initialise */
@@ -164,15 +206,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
 #endif
 
 #ifdef __MINGW32__
-   res = _main( argc, argv );
+   res = real_main( argc, argv );
 #else
    res = main( argc, argv );
 #endif
 
-   /* Cleanup */
-   free(argv);
-   free(pszArgs);
-
    return res;
 
 }
@@ -206,7 +244,7 @@ void InitWin32(void)
    if (WSAStartup(wVersionRequested, &wsaData) != 0)
    {
 #ifndef _WIN_CONSOLE
-      MessageBox(NULL, "Cannot initialize WinSock library", "Internet JunkBuster Error", 
+      MessageBox(NULL, "Cannot initialize WinSock library", "Privoxy Error", 
          MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);  
 #endif
       exit(1);
@@ -230,7 +268,7 @@ void InitWin32(void)
  * Description :  User interface thread.  WinMain will wait for us to set
  *                the hInitCompleteEvent before patching over to `main'.
  *                This ensures the systray window is active before beginning
- *                IJB operations.
+ *                operations.
  *
  * Parameters  :
  *          1  :  pData = pointer to `hInitCompleteEvent'.
@@ -258,7 +296,7 @@ static void __cdecl UserInterfaceThread(void *pData)
    TermLogWindow();
 
    /* Time to die... */
-   raise(SIGINT);
+   exit(0);
 
 }
 
diff --git a/win32.h b/win32.h
index 3011f47..7c699dc 100644 (file)
--- a/win32.h
+++ b/win32.h
@@ -1,14 +1,14 @@
-#ifndef _WIN32_H
-#define _WIN32_H
-#define WIN32_H_VERSION "$Id: win32.h,v 1.1 2001/05/13 21:57:07 administrator Exp $"
+#ifndef WIN32_H_INCLUDED
+#define WIN32_H_INCLUDED
+#define WIN32_H_VERSION "$Id: win32.h,v 1.4 2002/03/24 12:03:47 jongfoster Exp $"
 /*********************************************************************
  *
- * File        :  $Source: /home/administrator/cvs/ijb/win32.h,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/win32.h,v $
  *
  * Purpose     :  Win32 User Interface initialization and message loop
  *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                IJBSWA team.  http://ijbswa.sourceforge.net
+ * Copyright   :  Written by and Copyright (C) 2001-2002 members of
+ *                the Privoxy team.  http://www.privoxy.org/
  *
  *                Written by and Copyright (C) 1999 Adam Lock
  *                <locka@iol.ie>
  *
  * Revisions   :
  *    $Log: win32.h,v $
+ *    Revision 1.4  2002/03/24 12:03:47  jongfoster
+ *    Name change
+ *
+ *    Revision 1.3  2001/07/30 22:08:36  jongfoster
+ *    Tidying up #defines:
+ *    - All feature #defines are now of the form FEATURE_xxx
+ *    - Permanently turned off WIN_GUI_EDIT
+ *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
+ *
+ *    Revision 1.2  2001/07/29 18:43:08  jongfoster
+ *    Changing #ifdef _FILENAME_H to FILENAME_H_INCLUDED, to conform to
+ *    ANSI C rules.
+ *
+ *    Revision 1.1.1.1  2001/05/15 13:59:08  oes
+ *    Initial import of version 2.9.3 source tree
+ *
  *
  *********************************************************************/
 \f
@@ -62,8 +78,8 @@ extern const char win32_h_rcs[];
 } /* extern "C" */
 #endif
 
-#endif /* ndef _WIN32_H */
-
+#endif /* ndef WIN32_H_INCLUDED */
+  
 /*
   Local Variables:
   tab-width: 3